File size: 2,327 Bytes
7e964be
 
 
 
 
 
 
 
 
 
2ac0ecc
7e964be
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323e16d
7e964be
 
 
 
 
 
 
 
323e16d
7e964be
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**
 * 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);
});