piyushgithub15

Streamable MCP Server

Community piyushgithub15
Updated

Streamable MCP Server

A Model Context Protocol server written in TypeScript, exposed over the Streamable HTTP transport (the modern replacement for the older HTTP+SSE transport).

Features

  • Streamable HTTP transport at POST/GET/DELETE /mcp, with per-session state (via the mcp-session-id header)
  • Example tools: echo, add, get-time
  • Example resource: info://server
  • GET /healthz for container/orchestrator health checks
  • Multi-stage, non-root Dockerfile

Project layout

src/
  server.ts   # McpServer factory: tools & resources are registered here
  index.ts    # Express app wiring the Streamable HTTP transport + session management

Local development

npm install
npm run dev      # tsx watch, restarts on change

Or build and run compiled JS:

npm run build
npm start

The server listens on http://localhost:3000/mcp by default (override with PORT).

Trying it with curl

Initialize a session (note the mcp-session-id response header, needed for follow-up requests):

curl -i -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl-test","version":"1.0"}}}'

Then, using the returned session id:

SESSION=<mcp-session-id from above>

curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "mcp-session-id: $SESSION" \
  -d '{"jsonrpc":"2.0","method":"notifications/initialized"}'

curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "mcp-session-id: $SESSION" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"add","arguments":{"a":21,"b":21}}}'

Docker

Build the image:

docker build -t streamable-mcp-server .

Run it:

docker run -d -p 3000:3000 --name mcp-server streamable-mcp-server

Check health:

curl http://localhost:3000/healthz

Adding your own tools

Add new server.registerTool(...) calls in src/server.ts. Each new session gets a freshly created McpServer, so any per-session state should live inside the factory function's closure or be looked up externally (e.g. a database) rather than stored in module-level globals.

MCP Server ยท Populars

MCP Server ยท New