Skip to content

Support remote/HTTP MCP servers in the integrations gateway (#229)#230

Merged
germanescobar merged 1 commit into
mainfrom
issue-229-remote-mcp
Jun 24, 2026
Merged

Support remote/HTTP MCP servers in the integrations gateway (#229)#230
germanescobar merged 1 commit into
mainfrom
issue-229-remote-mcp

Conversation

@germanescobar

Copy link
Copy Markdown
Owner

Summary

Extends server/lib/mcp-client.ts to support remote MCP servers over the Streamable HTTP transport, in addition to the existing stdio transport. A connection with a url in its transport config now POSTs JSON-RPC to that URL, accepting both application/json and text/event-stream (SSE) responses, and runs the same initializenotifications/initializedtools/list / tools/call flow as stdio.

Closes #229 (platform work). Registering Cloudflare (Code Mode) as the first consumer is a follow-up user action — see below.

Changes

  • Transport dispatch: withSession branches on config — urlwithHttpSession, commandwithStdioSession (existing logic, unchanged, just extracted), neither → a clear error.
  • Streamable HTTP: POSTs each JSON-RPC message with Accept: application/json, text/event-stream; parses both a single JSON body and SSE data: frames. Carries the optional Mcp-Session-Id handed back on initialize onto subsequent requests.
  • Auth injection at the HTTP boundary via resolveConnectionAuth — the same resolveAuth + getConnectionSecrets path the REST/OpenAPI executor uses — so a static Authorization: Bearer <token> attaches identically. A 401/403 surfaces a credentials error; other non-2xx surfaces status + body; a missing credential short-circuits before any network call.
  • No gateway plumbing changesintegration-gateway.ts already routes mcp mode through mcpListTools / mcpCallTool / mcpStatus, and the connection form already exposes the url field + Bearer preset.

Validation

  • New mcp-client.test.ts: 9 tests — JSON + SSE framing, auth header injection, status/tool-count, tools/call, 401, non-2xx, missing-credential short-circuit, no-command/no-url rejection.
  • Full server suite: 278/278 pass — no regression. Existing stdio path untouched.
  • tsc -p server/tsconfig.json --noEmit: clean.

Follow-up: Cloudflare (Code Mode)

The platform now supports it, but registration is a user action (the UI writes the Bearer API token to the encrypted secret store — not a repo artifact). After merge: add an MCP connection in Controller → Integrations with URL https://mcp.cloudflare.com/mcp + Bearer token, then verify with integrations tools / call / status.

🤖 Generated with Claude Code

Extend the MCP client to speak the Streamable HTTP transport in addition
to stdio. A connection with a `url` in its transport config now POSTs
JSON-RPC to that URL, accepting both `application/json` and
`text/event-stream` (SSE) responses and running the same
initialize -> notifications/initialized -> tools/list / tools/call flow.

Auth is injected at the HTTP boundary via resolveConnectionAuth (the same
resolveAuth + getConnectionSecrets path the REST/OpenAPI executor uses),
so a static Bearer token attaches exactly as it does for those transports.
The optional Mcp-Session-Id handed back on initialize is carried on
subsequent requests. The stdio path is unchanged (split into its own
helper). No gateway plumbing changes were needed.

Adds unit tests for the HTTP transport: JSON and SSE framing, auth header
injection, 401/non-2xx handling, missing-credential short-circuit, and
the no-command/no-url rejection.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

Support remote/HTTP MCP servers in the integrations gateway

1 participant