Skip to main content
Glama

Dynamic Excel MCP Server

by nam090320251
SSE-FIX.mdโ€ข4.19 kB
# SSE Endpoint Fix - Connection Hanging Issue ## ๐Ÿ› Problem The `/sse` endpoint was hanging and not establishing connections properly. Clients connecting to the SSE endpoint would hang indefinitely without receiving any data. ### Error Messages ``` Error [ERR_HTTP_HEADERS_SENT]: Cannot write headers after they are sent to the client ``` ## ๐Ÿ” Root Cause The issue had two main causes: 1. **Double Header Setting**: We were calling `res.writeHead()` manually before creating the SSE transport, but `SSEServerTransport` from the MCP SDK also sets headers when it starts. This caused the "ERR_HTTP_HEADERS_SENT" error. 2. **Incorrect Architecture**: We were passing a single MCP server instance to all connections. SSE transport requires each connection to have its own server instance. ## โœ… Solution ### 1. Factory Pattern for MCP Server Changed from passing a single server instance to using a factory function: ```typescript // โŒ Before: Single server instance const server = createMcpServer(); httpServer.setupMcpEndpoint(server); // โœ… After: Factory function httpServer.setupMcpEndpoint({ createServer: createMcpServer // Each connection gets new instance }); ``` ### 2. Let Transport Handle Headers Removed manual header setting and let SSEServerTransport handle it: ```typescript // โŒ Before: Manual header setting res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', }); const transport = new SSEServerTransport('/message', res); // โœ… After: Transport sets headers const transport = new SSEServerTransport('/message', res); // Headers are set internally by the transport ``` ### 3. Proper Connection Lifecycle Added: - Keep-alive pings every 30 seconds - Clean disconnect handling - Proper transport closure ```typescript // Keep connection alive const keepAlive = setInterval(() => { if (res.writableEnded) { clearInterval(keepAlive); return; } res.write(': keep-alive\n\n'); }, 30000); // Handle disconnect req.on('close', () => { clearInterval(keepAlive); transport.close(); }); ``` ## ๐Ÿงช Testing ### Quick Test ```bash # Start server TRANSPORT_MODE=http npm start # In another terminal curl http://localhost:3000/health curl http://localhost:3000/info curl -N http://localhost:3000/sse # Should connect without hanging ``` ### Test Script ```bash ./test-sse.sh ``` ### Expected Logs ``` [INFO] New SSE client connecting... [INFO] SSE connection established and MCP server connected [INFO] SSE client disconnected ``` ## ๐Ÿ“Š Results | Before | After | |--------|-------| | โŒ Connection hangs | โœ… Connects immediately | | โŒ ERR_HTTP_HEADERS_SENT | โœ… No errors | | โŒ Single server instance | โœ… Factory pattern | | โŒ Manual headers | โœ… Transport handles headers | ## ๐Ÿš€ Usage ### Local Testing ```bash # Create .env TRANSPORT_MODE=http HTTP_PORT=3000 STORAGE_TYPE=local # Start server npm start ``` ### With MCP Client ```typescript import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'; const transport = new SSEClientTransport( new URL('http://localhost:3000/sse') ); const client = new Client({ name: 'excel-client', version: '1.0.0', }, { capabilities: {} }); await client.connect(transport); // Now you can call tools! ``` ## ๐Ÿ“ Key Takeaways 1. **MCP SSE Pattern**: Each SSE connection needs its own MCP server instance 2. **Transport Control**: Let MCP transport classes handle their own headers/protocol 3. **Factory Pattern**: Use factory functions for per-connection instances 4. **Keep-Alive**: Send periodic pings to maintain SSE connections ## ๐Ÿ”— Related Files - `src/transports/http-server.ts` - HTTP/SSE transport implementation - `src/index.ts` - Server factory and initialization - `test-sse.sh` - Simple connectivity test - `examples/client-example.ts` - Full client example ## ๐Ÿ“š References - [MCP SDK Documentation](https://github.com/anthropics/mcp) - [SSE Specification](https://html.spec.whatwg.org/multipage/server-sent-events.html) - [Express.js SSE Guide](https://expressjs.com/)

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/nam090320251/dynamic-excel-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server