Skip to content

fix(happy-cli): create fresh MCP server+transport per request for SDK >=1.26 compat#641

Closed
nikhilsitaram wants to merge 1 commit intoslopus:mainfrom
nikhilsitaram:fix/mcp-stateless-transport-reuse
Closed

fix(happy-cli): create fresh MCP server+transport per request for SDK >=1.26 compat#641
nikhilsitaram wants to merge 1 commit intoslopus:mainfrom
nikhilsitaram:fix/mcp-stateless-transport-reuse

Conversation

@nikhilsitaram
Copy link

Summary

  • Fixes MCP tool calls failing after the first invocation due to stateless transport reuse
  • Creates a fresh McpServer + StreamableHTTPServerTransport per HTTP request instead of sharing a single instance

Problem

MCP SDK v1.26.0 introduced a restriction that stateless transports (sessionIdGenerator: undefined) cannot be reused across requests. The previous code created one McpServer and one StreamableHTTPServerTransport at startup and reused them for all requests:

// Before: single shared transport
const transport = new StreamableHTTPServerTransport({
    sessionIdGenerator: undefined
});
await mcp.connect(transport);

const server = createServer(async (req, res) => {
    await transport.handleRequest(req, res);  // fails on 2nd call
});

The first tool call (e.g., mcp__happy__change_title) succeeds, but all subsequent calls fail with "Stateless transport cannot be reused".

Fix

Factory pattern — each request gets its own server+transport pair, cleaned up on connection close:

const server = createServer(async (req, res) => {
    const mcp = createMcpServer();  // fresh server with tools registered
    const transport = new StreamableHTTPServerTransport({
        sessionIdGenerator: undefined
    });
    await mcp.connect(transport);
    await transport.handleRequest(req, res);
    res.on('close', () => {
        transport.close();
        mcp.close();
    });
});

Test plan

  • Verify mcp__happy__change_title works on first call
  • Verify mcp__happy__change_title works on second and subsequent calls within the same session
  • Verify transport/server cleanup occurs after each request (no resource leaks)

🤖 Generated with Claude Code

… >=1.26 compat

MCP SDK v1.26.0 forbids reusing stateless transports (sessionIdGenerator:
undefined). The previous code created a single McpServer and transport at
startup, then reused the transport for every incoming HTTP request. The
first tool call succeeded, but subsequent calls failed with "Stateless
transport cannot be reused".

Changed to a factory pattern: each HTTP request creates its own McpServer
and StreamableHTTPServerTransport, connects them, handles the request,
then cleans up on connection close.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <[email protected]>
Co-Authored-By: Happy <[email protected]>
@nikhilsitaram nikhilsitaram closed this by deleting the head repository Feb 25, 2026
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