Skip to content

Make MCP endpoint Streamable HTTP compliant and fix Claude Desktop setup - #253

Merged
nwwatson merged 1 commit into
masterfrom
automated/mcp-claude-desktop-compat-ecf0b4
Sep 18, 2026
Merged

nwwatson merged 1 commit into
masterfrom
automated/mcp-claude-desktop-compat-ecf0b4

Conversation

@nwwatson

Copy link
Copy Markdown
Owner

Summary

The /mcp endpoint skipped the HTTP side of the MCP Streamable HTTP spec. The documented Claude Desktop config also couldn't work.

Endpoint

Mcp::SessionsController passed the raw body to MCP::Server#handle_json. It now routes GET/POST/DELETE /mcp through the gem's StreamableHTTPTransport, set up so nothing is kept between requests and responses are plain JSON.

Request Before After
notifications/initialized 200 with body "null" 202, empty body
GET /mcp (SSE probe) 404 HTML page 405
DELETE /mcp 404 HTML page 200
Malformed JSON 200 with an error 400 with error code -32700

The transport also checks Accept/Content-Type and the MCP-Protocol-Version header, and supports the 2026-07-28 protocol version. The body limit is raised from the transport's 4 MiB default to 16 MB, so base64 image uploads over about 3 MB keep working.

Docs

  • Claude Desktop: claude_desktop_config.json only runs stdio servers, so the documented url + headers entry was ignored. The docs now use the mcp-remote bridge (needs Node.js).
  • Claude Code: the command now uses --transport http (not streamable-http) with options before the server name, and the docs give the correct default scope (local).
  • CLAUDE.md describes the new controller setup.

Behavior change

Clients must send Content-Type: application/json and an Accept header that includes application/json. Claude Desktop (via mcp-remote), Claude Code and the official SDKs already do. The old standalone SSE transport (2024-11-05) is still not supported.

Testing

  • 8 new controller tests cover the table above, the protocol version header, and tool-name/schema rules.
  • The existing MCP tests now send the headers real clients send.
  • bin/rails test: 1556 runs, 0 failures. bin/rubocop and bin/brakeman are clean.
  • Not tested against a live Claude Desktop through mcp-remote.

🤖 Generated with Claude Code

…p setup

Route GET/POST/DELETE /mcp through the mcp gem's StreamableHTTPTransport
(stateless, JSON responses) instead of calling MCP::Server#handle_json
directly. Notifications now get 202, GET gets 405 instead of the HTML 404
page, malformed JSON gets a 400 parse error, and Accept/Content-Type and
MCP-Protocol-Version are validated. The request body cap is raised to 16 MB
so base64 image uploads keep working.

The documented Claude Desktop config (url + headers) is not supported by
claude_desktop_config.json, which only runs stdio servers; document the
mcp-remote bridge instead. Fix the Claude Code command (--transport http,
options before the name, local default scope).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@nwwatson
nwwatson merged commit c176ff7 into master Sep 18, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant