modelcontextprotocol / modelcontextprotocol/typescript-sdk
McpServer re-registers capabilities after connect, blocking dynamic registration even when capabilities were supplied at construction
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 13.4k
- Forks
- 2.2k
- Avg merge
- 3d 15h
- Merged PRs (30d)
- 4
Description
Summary
When creating McpServer with ServerOptions.capabilities that include resources and tools, calling registerResource or registerTool after connect() fails with “Cannot register capabilities after connecting to transport”. The high-level server re-calls server.registerCapabilities(...) the first time handlers are installed, even post-connect.
Steps to Reproduce
- Create
McpServerwith capabilities:
const capabilities = {
resources: { subscribe: true, listChanged: true },
tools: { listChanged: true },
};
const server = new McpServer({ name: "demo", version: "1.0.0" }, { capabilities });
await server.connect(transport);- After connect, call
server.registerResource(...)(orserver.registerTool(...)) - Observe HTTP 500 with error “Cannot register capabilities after connecting to transport”
Expected Behavior
- If capabilities were provided at construction, registering resources/tools/prompts after connect should work. The server should not attempt to re-register capabilities post-connect.
Actual Behavior
- First registration after connect triggers handler initialization in
McpServer, which unconditionally callsserver.registerCapabilities(...). SinceServer.registerCapabilitiesforbids post-connect, it throws.
Notes
- Calls occur in
typescript-sdk/src/server/mcp.tswithin:setResourceRequestHandlers()→this.server.registerCapabilities({ resources: { listChanged: true } })setToolRequestHandlers()→this.server.registerCapabilities({ tools: { listChanged: true } })setPromptRequestHandlers()→this.server.registerCapabilities({ prompts: { listChanged: true } })
- Guard that throws is in
typescript-sdk/src/server/index.tsregisterCapabilities().
Proposed Fix
- Make
this.server.registerCapabilities(...)idempotent if capabilities are already registered.
Environment
- @modelcontextprotocol/sdk 1.17.3
- Transport: Streamable HTTP (client error surfaced as HTTP 500)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read the handler setup in typescript-sdk/src/server/mcp.ts, then trace the post-connect guard in typescript-sdk/src/server/index.ts through setResourceRequestHandlers(), setToolRequestHandlers(), and setPromptRequestHandlers(). Reproduce the construction, connect, and registration sequence from the issue; done means resources, tools, and prompts can be registered after connect when capabilities were supplied at construction, without the post-connect error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100