mmty commited on
Commit
a9aa3fa
·
verified ·
1 Parent(s): 3bfea7d

Update server.js

Browse files
Files changed (1) hide show
  1. server.js +33 -41
server.js CHANGED
@@ -6,30 +6,29 @@ const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch
6
  const app = express();
7
  const PORT = process.env.PORT || 7860;
8
 
9
- // --- 1. CRITICAL: TRUST PROXY ---
10
- // This ensures req.protocol and req.get('host') return the REAL public values
11
- // (https and your-space.hf.space) instead of http://localhost
12
- app.set('trust proxy', 1);
13
 
14
- // --- 2. MIDDLEWARE ---
15
  const corsOptions = {
16
  origin: '*',
17
  methods: ['GET', 'POST', 'OPTIONS'],
18
  allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],
19
  };
20
  app.use(cors(corsOptions));
21
- app.options(/.*/, cors(corsOptions)); // Fix for Express 5 crash
22
- app.use(express.json({ limit: '10mb' }));
23
 
24
- // Logging
25
  app.use((req, res, next) => {
26
- console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
 
27
  next();
28
  });
29
 
30
- // --- 3. SSE ENDPOINT ---
31
  app.get('/sse', (req, res) => {
32
- console.log("[SSE] New Connection");
33
 
34
  res.writeHead(200, {
35
  'Content-Type': 'text/event-stream',
@@ -39,21 +38,20 @@ app.get('/sse', (req, res) => {
39
  'Access-Control-Allow-Origin': '*'
40
  });
41
 
42
- // Construct the absolute URL.
43
- // With 'trust proxy', req.protocol should be 'https'
44
  const protocol = req.protocol === 'http' ? 'https' : req.protocol;
45
  const host = req.get('host');
46
  const messageEndpoint = `${protocol}://${host}/messages`;
47
 
48
- console.log(`[SSE] Sending Endpoint: ${messageEndpoint}`);
49
 
50
  // 1. Send Endpoint Event
51
  res.write(`event: endpoint\ndata: ${messageEndpoint}\n\n`);
52
 
53
- // 2. Send Padding (4KB) to flush buffers
54
  res.write(`: ${" ".repeat(4096)}\n\n`);
55
 
56
- // 3. Ping Loop
57
  const interval = setInterval(() => {
58
  res.write(`: ping\n\n`);
59
  }, 10000);
@@ -64,38 +62,31 @@ app.get('/sse', (req, res) => {
64
  });
65
  });
66
 
67
- // --- 4. MESSAGES ENDPOINT ---
68
  app.post('/messages', async (req, res) => {
69
  try {
70
  const body = req.body;
71
- const requestId = body.id; // Keep as-is (can be 0, string, or null)
72
 
73
  console.log(`[MESSAGES] Method: ${body.method} | ID: ${requestId}`);
74
 
75
  // A. Initialize
76
  if (body.method === 'initialize') {
77
- const response = {
 
78
  jsonrpc: "2.0",
79
  id: requestId,
80
  result: {
81
  protocolVersion: "2024-11-05",
82
- capabilities: {
83
- // Return empty objects for all capabilities to be safe
84
- tools: {},
85
- prompts: {},
86
- resources: {},
87
- logging: {}
88
- },
89
  serverInfo: { name: "github-mcp-hf", version: "1.0.0" }
90
  }
91
- };
92
- console.log("[MESSAGES] Sending Init Response");
93
- return res.json(response);
94
  }
95
 
96
  // B. List Tools
97
  if (body.method === 'tools/list') {
98
- console.log("[MESSAGES] Listing Tools");
99
  return res.json({
100
  jsonrpc: "2.0",
101
  id: requestId,
@@ -160,11 +151,9 @@ app.post('/messages', async (req, res) => {
160
  });
161
  }
162
  }
163
-
164
- // D. Notifications
165
  if (body.method === 'notifications/initialized') {
166
- console.log("[MESSAGES] Notification: initialized");
167
- return res.json({ result: true }); // Ack
168
  }
169
 
170
  res.status(404).json({ error: "Method not found" });
@@ -175,16 +164,19 @@ app.post('/messages', async (req, res) => {
175
  }
176
  });
177
 
178
- // --- 5. CATCH-ALL / HEALTH CHECK ---
 
179
  app.use((req, res) => {
180
- if (req.method === 'GET' || req.method === 'POST') {
181
- console.log(`[FALLBACK] Responding 200 OK to: ${req.path}`);
182
- return res.status(200).send("MCP Server Active");
183
- }
184
- res.status(404).send("Not Found");
 
 
185
  });
186
 
187
- // --- 6. STARTUP ---
188
  app.listen(PORT, '0.0.0.0', () => {
189
  console.log(`Server running on port ${PORT}`);
190
  });
 
6
  const app = express();
7
  const PORT = process.env.PORT || 7860;
8
 
9
+ // --- 1. CONFIGURATION ---
10
+ app.set('trust proxy', 1); // Required for Hugging Face Spaces
11
+ app.use(express.json({ limit: '10mb' }));
 
12
 
13
+ // --- 2. CORS (Strict & Global) ---
14
  const corsOptions = {
15
  origin: '*',
16
  methods: ['GET', 'POST', 'OPTIONS'],
17
  allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],
18
  };
19
  app.use(cors(corsOptions));
20
+ app.options(/.*/, cors(corsOptions)); // Handle Preflight for all routes
 
21
 
22
+ // --- 3. LOGGING ---
23
  app.use((req, res, next) => {
24
+ // Log request to debug timing
25
+ console.log(`[${new Date().toISOString()}] ${req.method} ${req.originalUrl}`);
26
  next();
27
  });
28
 
29
+ // --- 4. SSE ENDPOINT ---
30
  app.get('/sse', (req, res) => {
31
+ console.log("[SSE] Connection Initiated");
32
 
33
  res.writeHead(200, {
34
  'Content-Type': 'text/event-stream',
 
38
  'Access-Control-Allow-Origin': '*'
39
  });
40
 
41
+ // Calculate external endpoint
 
42
  const protocol = req.protocol === 'http' ? 'https' : req.protocol;
43
  const host = req.get('host');
44
  const messageEndpoint = `${protocol}://${host}/messages`;
45
 
46
+ console.log(`[SSE] Endpoint: ${messageEndpoint}`);
47
 
48
  // 1. Send Endpoint Event
49
  res.write(`event: endpoint\ndata: ${messageEndpoint}\n\n`);
50
 
51
+ // 2. Send Padding (Keep buffer flush)
52
  res.write(`: ${" ".repeat(4096)}\n\n`);
53
 
54
+ // 3. Keep-Alive Loop
55
  const interval = setInterval(() => {
56
  res.write(`: ping\n\n`);
57
  }, 10000);
 
62
  });
63
  });
64
 
65
+ // --- 5. MESSAGES ENDPOINT ---
66
  app.post('/messages', async (req, res) => {
67
  try {
68
  const body = req.body;
69
+ const requestId = body.id;
70
 
71
  console.log(`[MESSAGES] Method: ${body.method} | ID: ${requestId}`);
72
 
73
  // A. Initialize
74
  if (body.method === 'initialize') {
75
+ console.log("[MESSAGES] Sending Init Response");
76
+ return res.json({
77
  jsonrpc: "2.0",
78
  id: requestId,
79
  result: {
80
  protocolVersion: "2024-11-05",
81
+ capabilities: { tools: {}, prompts: {}, resources: {} },
 
 
 
 
 
 
82
  serverInfo: { name: "github-mcp-hf", version: "1.0.0" }
83
  }
84
+ });
 
 
85
  }
86
 
87
  // B. List Tools
88
  if (body.method === 'tools/list') {
89
+ console.log("[MESSAGES] Sending Tool List");
90
  return res.json({
91
  jsonrpc: "2.0",
92
  id: requestId,
 
151
  });
152
  }
153
  }
154
+
 
155
  if (body.method === 'notifications/initialized') {
156
+ return res.json({ result: true });
 
157
  }
158
 
159
  res.status(404).json({ error: "Method not found" });
 
164
  }
165
  });
166
 
167
+ // --- 6. JSON FALLBACK (The Fix) ---
168
+ // We handle ALL other requests by returning JSON, never Text/HTML.
169
  app.use((req, res) => {
170
+ console.log(`[FALLBACK] Handling ${req.method} ${req.path}`);
171
+ // Return valid JSON so ChatUI parsers don't crash
172
+ res.status(200).json({
173
+ status: "active",
174
+ message: "MCP Server Running",
175
+ path: req.path
176
+ });
177
  });
178
 
179
+ // --- 7. STARTUP ---
180
  app.listen(PORT, '0.0.0.0', () => {
181
  console.log(`Server running on port ${PORT}`);
182
  });