agentsclimarketplace

Stateless streamable http mcp

Skill kjuhwa/skills-hub/skills/architecture/stateless-streamable-http-mcp

Use StreamableHTTPServerTransport with sessionIdGenerator:undefined to serve MCP over HTTP without session affinity — multiple subprocess clients share one server, every request is independent.From its SKILL.md

Install
npx -y skills add kjuhwa/skills-hub --skill stateless-streamable-http-mcp

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

3.1 KB, 592 tokens by cl100k_base, as published. Nobody here has run it

Stateless Streamable-HTTP MCP

When to use

  • Building an MCP server meant to be consumed by MULTIPLE client subprocesses (Codex, Copilot, CLI).
  • Don't want the complexity of MCP's session-aware SSE transport.
  • Tools are stateless - any client can call any tool at any time.

How it works

  1. Instantiate the transport with sessionIdGenerator: undefined:
    new StreamableHTTPServerTransport({ sessionIdGenerator: undefined })
    
    This puts the transport in stateless mode - no session cookie, no server-side session registry, no sticky routing.
  2. Connect a single Server instance to the transport. All clients share it.
  3. Mount at a single path (/mcp). Route every method (POST, GET, DELETE) to transport.handleRequest(req, res) - the transport does the JSON-RPC dispatch internally.
  4. Each incoming request is fully processed before the socket closes; no long-polling session state.
  5. Clients use StreamableHTTPClientTransport(new URL(serverUrl)). In stateless mode, they don't persist a session ID between calls.

Example

import { createServer } from 'node:http';
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';

const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
const mcp = new Server({ name: 'pool', version: '1.0.0' }, { capabilities: { tools: {} } });
mcp.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: await collectTools() }));
mcp.setRequestHandler(CallToolRequestSchema, async (req) => runTool(req.params.name, req.params.arguments));
await mcp.connect(transport);

createServer(async (req, res) => {
  if (new URL(req.url!, 'http://127.0.0.1').pathname !== '/mcp') { res.writeHead(404).end(); return; }
  await transport.handleRequest(req, res);
}).listen(0, '127.0.0.1');

Gotchas

  • Resource subscriptions and server-initiated notifications DO require a session ID; stateless mode disables them.
  • Bind to loopback if you don't have auth - the HTTP layer doesn't check anything.
  • handleRequest expects a Node http.IncomingMessage/ServerResponse pair, not Fetch Request/Response - wrap if you're in a Fetch-native framework.
  • When tools are expensive, add your own rate limiting upstream - stateless means no built-in coalescing.
  • Random port (listen(0)) works nicely - read server.address() after listen to learn the port.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,764. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.