This commit is contained in:
Bastian Wagner
2026-06-17 14:36:34 +02:00
parent 81b5f1dde9
commit 486c8fff2e

View File

@@ -22,15 +22,8 @@ export class McpServerService {
}
async startHttp(port = 3001): Promise<void> {
const mcpServer = this.createServer();
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined,
});
await mcpServer.connect(transport);
const httpServer = createServer((request, response) => {
void this.handleHttpRequest(request, response, transport);
void this.handleHttpRequest(request, response);
});
await new Promise<void>((resolve) => {
@@ -55,7 +48,6 @@ export class McpServerService {
private async handleHttpRequest(
request: IncomingMessage,
response: ServerResponse,
transport: StreamableHTTPServerTransport,
): Promise<void> {
this.setCorsHeaders(response);
@@ -80,20 +72,72 @@ export class McpServerService {
return;
}
if (this.isBrowserHealthRequest(request)) {
response.writeHead(200, { 'content-type': 'application/json' });
response.end(
JSON.stringify({
name: 'strava-mcp',
status: 'ok',
transport: 'streamable-http',
endpoint: '/mcp',
note: 'Use an MCP client or POST a JSON-RPC initialize request with Accept: application/json, text/event-stream.',
}),
);
return;
}
const mcpServer = this.createServer();
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined,
});
try {
await mcpServer.connect(transport);
await transport.handleRequest(request, response);
} catch (error) {
process.stderr.write(
`MCP HTTP request failed: ${
error instanceof Error ? (error.stack ?? error.message) : String(error)
}\n`,
);
if (!response.headersSent) {
response.writeHead(500, { 'content-type': 'application/json' });
response.writeHead(this.errorStatus(error), {
'content-type': 'application/json',
});
}
response.end(
JSON.stringify({
error: error instanceof Error ? error.message : 'MCP request failed',
}),
);
} finally {
await mcpServer.close().catch(() => undefined);
}
}
private isBrowserHealthRequest(request: IncomingMessage): boolean {
if (request.method !== 'GET') {
return false;
}
const accept = request.headers.accept ?? '';
return !accept.includes('text/event-stream');
}
private errorStatus(error: unknown): number {
const message = error instanceof Error ? error.message : '';
if (message.includes('Not Acceptable')) {
return 406;
}
if (message.includes('Method not allowed')) {
return 405;
}
if (message.includes('Bad Request')) {
return 400;
}
return 500;
}
private isAuthorized(request: IncomingMessage): boolean {
const token = process.env.MCP_AUTH_TOKEN;
if (!token) {