Skip to content

feat(mcp): support remote MCP servers over Streamable HTTP#198

Open
gtxy27 wants to merge 4 commits into
lessweb:mainfrom
gtxy27:feat/mcp-remote-transport
Open

feat(mcp): support remote MCP servers over Streamable HTTP#198
gtxy27 wants to merge 4 commits into
lessweb:mainfrom
gtxy27:feat/mcp-remote-transport

Conversation

@gtxy27

@gtxy27 gtxy27 commented Jun 25, 2026

Copy link
Copy Markdown

背景

目前 Deep Code 的 MCP 客户端只支持本地 stdio 服务器(command + args),无法连接走 HTTP 的远程 MCP 服务(如 GitHub 官方远程 server、各类 SaaS)。本 PR 增加对 Streamable HTTP(MCP 2025-03-26) 远程服务器的支持。

改动

  1. 抽出传输层抽象 McpTransportstart/send/close/isConnected/decorateError)。原有 stdio 逻辑搬进 StdioTransportMcpClient 只保留 JSON-RPC 协议层(请求/响应配对、握手、通知分发),通过注入的 transport 收发——stdio 行为不变。
  2. 新增 HttpTransport:实现 Streamable HTTP——每条 JSON-RPC 消息用一次 HTTP POST 发送,响应可为单个 JSON 或 SSE 流;自动记录并回传 Mcp-Session-Id;支持自定义请求头(如 Authorization)。
  3. 配置解析McpServerConfig 增加可选 type / url / headersmergeMcpServers 识别远程条目(有 urltype: "http"),项目级覆盖用户级、headers 跨层合并。
  4. 文档:中英文 MCP 文档、bundled skill 引用、README FAQ 均补充远程配置说明。

配置示例

{
  "mcpServers": {
    "local":  { "command": "npx", "args": ["-y", "..."] },
    "remote": { "type": "http", "url": "https://example.com/mcp", "headers": { "Authorization": "Bearer <token>" } }
  }
}

测试

  • 新增 HttpTransport 集成测试:本地起 node:http server,覆盖 JSON 与 SSE 两条响应路径 + session-id 回传。
  • 新增远程配置合并单测。
  • 既有 stdio 测试全部保持通过。
  • npm run check(typecheck + lint + format)通过;全量测试 0 失败。

实现说明

  • 不引入任何新依赖:使用 Node 22 内置的全局 fetch / ReadableStream / AbortController
  • 测试不依赖外网,本地 mock server 即可跑。

范围

仅实现 Streamable HTTP。旧版 HTTP+SSE 双端点传输(2024-11-05)、OAuth 授权流程、server 主动推送的独立 GET 流不在本 PR 范围内。

兼容性

无破坏性变更:现有 stdio 服务器配置与行为完全不变;新增字段均为可选。

gtxy27 added 4 commits June 25, 2026 21:09
Separate the JSON-RPC protocol layer from the byte transport so the
client can drive both local and remote MCP servers.

- Add McpTransport interface (start/send/close/isConnected/decorateError).
- Move the stdio subprocess + readline + stderr logic into StdioTransport.
- McpClient now owns only request/response correlation, the handshake
  and notification dispatch, delegating I/O to an injected transport.
- Add createMcpClient(name, config) factory that picks the transport
  from the server config.
- Add optional type/url/headers fields to McpServerConfig for an
  upcoming remote transport (no behavior change yet).

No behavior change for stdio servers; existing MCP tests pass unchanged.
Add HttpTransport implementing the MCP Streamable HTTP protocol
(spec 2025-03-26): each JSON-RPC message is sent with an HTTP POST and
the reply is read as either a single JSON object or an SSE stream. The
Mcp-Session-Id returned on initialize is echoed on later requests, and
custom headers (e.g. Authorization) are forwarded.

createMcpClient now selects HttpTransport when the server config has
`type: "http"` or a `url`, and the stdio transport otherwise.

Covered by an integration test that runs a local Streamable HTTP server
exercising both the JSON and SSE response paths plus session-id echoing.
Teach mergeMcpServers to recognize remote (Streamable HTTP) entries: a
server with a `url` (or `type: "http"`) resolves to a remote config with
project settings overriding user settings and headers merged across
layers. Stdio servers keep their existing command/args/env resolution.
Add a remote-server section and type/url/headers fields to the MCP
configuration guide (zh + en, docs and bundled skill references), and
note remote support in the README MCP FAQ.
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