fix: pass req.body to StreamableHTTP transport on POST /mcp#1
Open
chipitaps wants to merge 1 commit into
Open
Conversation
express.json() consumes the request body before the MCP transport reads it,
causing remote MCP clients (Apify, ChatGPT, Cursor remote, etc.) to fail with
{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error: Invalid JSON"},"id":null}
The MCP SDK's StreamableHTTPServerTransport.handleRequest accepts a third
`parsedBody` argument exactly for this case. Passing req.body in restores
remote MCP compatibility without changing the existing express-json behaviour
that the rest of the routes rely on.
Verified locally: `curl -X POST localhost:3200/mcp -d '{...initialize...}'`
now returns the expected handshake response.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The HTTP transport for the MCP endpoint is unreachable from any external MCP client (Apify connectors, ChatGPT remote MCP, Cursor remote, etc.). Every JSON-RPC POST to
https://mcp.vin/mcpreturns:{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error: Invalid JSON"},"id":null}Reproducible with a plain curl:
Root cause
server.mjsmountsexpress.json()globally for parsing the REST API endpoints. By the time the request reaches theapp.post('/mcp', ...)handler,req.bodyis already populated but the underlying request stream has been consumed.The handler then calls:
The MCP SDK's
StreamableHTTPServerTransport.handleRequestfalls back to reading the raw request stream when noparsedBodyis supplied. The stream is empty, so the JSON parse fails and the transport emits a-32700error.Fix
Pass
req.bodyas the third argument tohandleRequest— exactly the path the SDK provides for this case (handleRequest(req, res, parsedBody?)). One-line change, no behaviour change for any other route.Verification
Running locally before the change:
After the change:
initializesucceeds and subsequenttools/list+tools/callwork end-to-end.Why this matters
The README and homepage advertise
https://mcp.vin/mcpas the remote HTTP endpoint for Claude Desktop / claude.ai / any MCP-compatible client. Right now the endpoint is unusable from anything other than the local stdio path — which means the hosted instance never gets used.