/** * Streamable-HTTP entrypoint for the demo server — the face deployed as a public * Hugging Face Docker Space. * * The same `createServer()` factory used over stdio (server.ts) is served over * Streamable HTTP at `/mcp` so any MCP client can run * `initialize -> tools/list -> tools/call` against the live endpoint. Nothing * about the tools or their 2020-12 validation changes; this only swaps the * transport (stdio -> Streamable HTTP). * * Built on the 2.0 HTTP surface: `createMcpHandler(factory)` (root export) * produces a web-standard fetch handler, adapted to Node's `(req, res)` with * `toNodeHandler` from @modelcontextprotocol/node, and mounted on a plain * node:http server bound to 0.0.0.0:$PORT (binding localhost is the #1 HF * "builds but won't connect" cause). * * Run locally: npm run start:http # serves http://127.0.0.1:7860/mcp * Env: PORT (listen port, default 7860; on HF Spaces this must equal the * README's app_port), SCHEMAS_PATH (see demo-tools.ts). */ import { createServer as createHttpServer } from "node:http"; import { createMcpHandler } from "@modelcontextprotocol/server"; import { toNodeHandler } from "@modelcontextprotocol/node"; import { createServer } from "./server.js"; const MCP_PATH = "/mcp"; const PORT = Number(process.env.PORT ?? "7860"); // A fresh McpServer per request (the modern stateless posture); every instance // registers the same six tools from the shared schemas.json. const handler = createMcpHandler(() => createServer()); const node = toNodeHandler(handler); const httpServer = createHttpServer((req, res) => { const url = new URL(req.url ?? "/", "http://localhost"); if (url.pathname === MCP_PATH) { void node(req, res); return; } if (url.pathname === "/" || url.pathname === "/health") { res.writeHead(200, { "content-type": "text/plain" }); res.end(`json-schema-2020-12-ts — MCP Streamable HTTP at ${MCP_PATH}\n`); return; } res.writeHead(404, { "content-type": "text/plain" }); res.end("Not found\n"); }); httpServer.listen(PORT, "0.0.0.0", () => { console.error( `json-schema-2020-12-ts running on Streamable HTTP at http://0.0.0.0:${PORT}${MCP_PATH}` ); }); process.on("SIGINT", () => { httpServer.close(); void handler.close?.(); process.exit(0); });