You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
McpServer re-registers capabilities after connect, blocking dynamic registration even when capabilities were supplied at construction #893
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.
After connect, call server.registerResource(...) (or server.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 calls server.registerCapabilities(...). Since Server.registerCapabilities forbids post-connect, it throws.
Notes
Calls occur in typescript-sdk/src/server/mcp.ts within:
@inverted-capital I faced the same issue when working on a project that needed to create tools/resources/prompts at runtime.
The workaround I used was to register dummies (1 of each type of tool/resource/prompt) before a transport is established. This seemed to enable the capability for each type in the SDK permitting later things to be registered even after connection. NOTE: They can even be removed after connection and things still work - though since they are disabled, it is fine to keep them around until other tools/resources/prompts are registered.
Hey! I ran into a similar pattern in our bug knowledge base and thought this might help.
What's happening: McpServer lazily calls server.registerCapabilities() on first setRequestHandler() call for each type (tools/resources/prompts). If connect() already happened, registerCapabilities() throws. Even if capabilities were declared in constructor, the internal Server only receives them when a handler is first installed — which may be post-connect.
What worked for us:
In McpServer.connect(), before calling this._server.connect(transport), eagerly install the request handlers (and thus trigger registerCapabilities) for any capability types declared in constructor options. Alternatively, patch Server.registerCapabilities() to no-op for capabilities already registered pre-connect. Workaround: register one dummy tool/resource/prompt before connect() to force early capability registration, then remove them post-connect.
// Workaround — register dummies before connect to force capability registrationconstserver=newMcpServer({name: "demo",version: "1.0.0"},{ capabilities });// Force early capability registrationserver.tool("__init","dummy",async()=>({content: []}));server.resource("__init","dummy://init",async()=>({contents: []}));server.prompt("__init","dummy",async()=>({messages: []}));awaitserver.connect(transport);// Safe to remove dummies after connectserver.removeTool("__init");server.removeResource("__init");server.removePrompt("__init");// Now dynamic registration worksserver.tool("real-tool","desc",async()=>({content: [{type: "text",text: "ok"}]}));
Hope this helps! Let me know if it doesn't match your case — happy to dig deeper. 🦞
Disclosure: This analysis is from Confucius Debug, an AI-powered community KB for agent bugs. Please verify before applying.
🦞 Confucius Debug — community knowledge base for AI agent bugs. Free to search via MCP.
Activity
Steve-Mcl commentedon Sep 7, 2025
@inverted-capital I faced the same issue when working on a project that needed to create tools/resources/prompts at runtime.
The workaround I used was to register dummies (1 of each type of tool/resource/prompt) before a transport is established. This seemed to enable the capability for each type in the SDK permitting later things to be registered even after connection. NOTE: They can even be removed after connection and things still work - though since they are disabled, it is fine to keep them around until other tools/resources/prompts are registered.
It is not ideal but its working well for me.
sstklen commentedon Feb 24, 2026
Hey! I ran into a similar pattern in our bug knowledge base and thought this might help.
What's happening: McpServer lazily calls server.registerCapabilities() on first setRequestHandler() call for each type (tools/resources/prompts). If connect() already happened, registerCapabilities() throws. Even if capabilities were declared in constructor, the internal Server only receives them when a handler is first installed — which may be post-connect.
What worked for us:
In McpServer.connect(), before calling this._server.connect(transport), eagerly install the request handlers (and thus trigger registerCapabilities) for any capability types declared in constructor options. Alternatively, patch Server.registerCapabilities() to no-op for capabilities already registered pre-connect. Workaround: register one dummy tool/resource/prompt before connect() to force early capability registration, then remove them post-connect.
Hope this helps! Let me know if it doesn't match your case — happy to dig deeper. 🦞
🦞 Confucius Debug — community knowledge base for AI agent bugs. Free to search via MCP.
fix: allow registering tools/resources/prompts after connect when cap…
fix: correct spread order in withDefaultListChangedCapabilities (mode…
felixweinberger commentedon Oct 5, 2026
Fixed in v2 since 2.0.0 (#2269). On v1 it's in the next patch release (#2958). Closing.