SPB Git forge

spb/doc-api

Public
2commits 1branches 0releases
15.7 MBsize
maindefault branch
14 days agolast push
Python 88.3% TypeScript 7.6% Shell 4.1%
3.8 KB · 62 lines typescript
Raw Blame History
1// Minimal remote MCP server (Streamable HTTP, JSON-RPC 2.0) exposing ONE tool, `echo`, written with Node built-ins only2// (no @modelcontextprotocol/sdk dependency so it runs with `node --experimental-strip-types`).3//4// STATUS: LIVE_VERIFIED locally 2026-09-18 (initialize / tools/list / tools/call over HTTP on 127.0.0.1) — NOT yet connected through the5// Anthropic MCP connector, which only reaches PUBLIC https URLs. To let Claude use it:6//   1. node --experimental-strip-types examples/anthropic/mcp/mini-mcp-server.ts            (listens on :8788, path /mcp)7//   2. expose it publicly with a tunnel, e.g. `cloudflared tunnel --url http://localhost:8788` (or ngrok, or on this cluster:8//      `mlt add mcp-demo.<your-domain> <node>:8788` on the MacLustr Tunnel gateway) -> https://<public-host>/mcp9//   3. call the Messages API with header anthropic-beta: mcp-client-2025-11-20 and10//      mcp_servers: [{type:"url", url:"https://<public-host>/mcp", name:"mini"}], tools: [{type:"mcp_toolset", mcp_server_name:"mini"}]11//      (see mcp_connector.sh / .py / .ts — swap the DeepWiki URL for yours). Anthropic then performs initialize + tools/list + tools/call.12// Optional bearer auth: set MCP_TOKEN=… and pass authorization_token in the server definition.13import { createServer } from "node:http";1415const PORT = Number(process.env.PORT ?? 8788);16const TOKEN = process.env.MCP_TOKEN; // optional shared secret17const TOOLS = [{18  name: "echo",19  description: "Echoes back the provided text. Use it when the user asks you to echo or repeat something through the MCP server.",20  inputSchema: { type: "object", properties: { text: { type: "string", description: "Text to echo" } }, required: ["text"] },21}];2223function rpcResult(id: unknown, result: unknown) { return { jsonrpc: "2.0", id, result }; }24function rpcError(id: unknown, code: number, message: string) { return { jsonrpc: "2.0", id, error: { code, message } }; }2526function handle(msg: any): unknown {27  switch (msg.method) {28    case "initialize":29      return rpcResult(msg.id, { protocolVersion: msg.params?.protocolVersion ?? "2025-06-18", capabilities: { tools: {} }, serverInfo: { name: "mini-mcp", version: "0.1.0" } });30    case "notifications/initialized":31    case "ping":32      return msg.id === undefined ? undefined : rpcResult(msg.id, {});33    case "tools/list":34      return rpcResult(msg.id, { tools: TOOLS });35    case "tools/call": {36      const { name, arguments: args } = msg.params ?? {};37      if (name !== "echo") return rpcResult(msg.id, { content: [{ type: "text", text: `Unknown tool ${name}` }], isError: true });38      return rpcResult(msg.id, { content: [{ type: "text", text: `echo: ${args?.text ?? ""}` }], isError: false });39    }40    default:41      return msg.id === undefined ? undefined : rpcError(msg.id, -32601, `Method not found: ${msg.method}`);42  }43}4445createServer((req, res) => {46  if (req.url !== "/mcp") { res.writeHead(404).end(); return; }47  if (TOKEN && req.headers.authorization !== `Bearer ${TOKEN}`) { res.writeHead(401).end(); return; }48  if (req.method === "GET") { res.writeHead(405).end(); return; } // no server->client SSE stream in this mini server49  let body = "";50  req.on("data", (c) => (body += c));51  req.on("end", () => {52    try {53      const parsed = JSON.parse(body);54      const out = Array.isArray(parsed) ? parsed.map(handle).filter(Boolean) : handle(parsed);55      if (out === undefined || (Array.isArray(out) && out.length === 0)) { res.writeHead(202).end(); return; }56      res.writeHead(200, { "content-type": "application/json" }).end(JSON.stringify(out));57    } catch {58      res.writeHead(400, { "content-type": "application/json" }).end(JSON.stringify(rpcError(null, -32700, "Parse error")));59    }60  });61}).listen(PORT, () => console.log(`mini MCP server on http://127.0.0.1:${PORT}/mcp (tools: echo)`));62