feat: add Streamable HTTP transport support#326
Conversation
Add --transport http option to start in Streamable HTTP mode (default remains stdio). Uses SDK built-in StreamableHTTPServerTransport + node:http with no new runtime dependencies. - Stateless mode (each request creates an independent session) - Origin header validation, Content-Type check, 1MB body limit - Default 127.0.0.1 bind, --port and --hostname options - Graceful shutdown with SIGTERM/SIGINT handling - Tests added (14 for HTTP server, 9 for config parsing)
|
@keykbd |
| // eslint-disable-next-line @typescript-eslint/no-empty-function | ||
| const noop = () => {}; | ||
|
|
||
| const LOOPBACK_HOSTS = new Set(["127.0.0.1", "localhost", "::1", "[::1]"]); |
There was a problem hiding this comment.
Please remove localhost from the set. Unlike the IP literals 127.0.0.1 and ::1, it is a DNS-resolvable hostname and may raise security concerns.
| const cleanup = () => { | ||
| transport?.close().catch(noop); | ||
| server?.close().catch(noop); | ||
| }; |
There was a problem hiding this comment.
Since both res.on("close", cleanup) and the explicit cleanup() call in the catch block may invoke transport.close() / server.close() twice on error, please make cleanup idempotent.
| const cleanup = () => { | |
| transport?.close().catch(noop); | |
| server?.close().catch(noop); | |
| }; | |
| let cleaned = false; | |
| const cleanup = () => { | |
| if (cleaned) return; | |
| cleaned = true; | |
| transport?.close().catch(noop); | |
| server?.close().catch(noop); | |
| }; |
|
|
||
| kintoneの公式ローカルMCPサーバーです。 | ||
|
|
||
| <!-- NOTE: TOCはpnpm doc:update-tocで自動生成されます。 --> |
There was a problem hiding this comment.
A new section has been added, so please run pnpm doc:update-toc.
| if (!connectionReset) { | ||
| // If we got a response, it must have been 413 | ||
| expect(true).toBe(true); | ||
| } |
There was a problem hiding this comment.
This assertion can be safely removed.
| expect(mockHandleRequest).not.toHaveBeenCalled(); | ||
| }); | ||
|
|
||
| it("should return 500 and cleanup when connect throws", async () => { |
There was a problem hiding this comment.
Please also add a test case verifying that cleanup is called in the normal (non-error) flow.
Why
Addresses the HTTP transport portion of #304.
Currently the server only supports stdio transport, which requires a 1:1 process
per client. Adding Streamable HTTP transport enables deployment on remote
environments such as AWS AgentCore, or running as a shared MCP server for a team.
What
--transport httpto start in Streamable HTTP mode (default remains stdio)StreamableHTTPServerTransport+node:http)Out of scope (planned for a follow-up PR):
How to test
To manually verify HTTP mode:
KINTONE_BASE_URL=https://example.cybozu.com \ KINTONE_USERNAME=user KINTONE_PASSWORD=pass \ node dist/index.js --transport http # -> HTTP server listening on http://127.0.0.1:3000/mcpChecklist
pnpm lintandpnpm teston the root directory.cc @nameless-mc @shabaraba @neos-nozaki