Python 88.3%
TypeScript 7.6%
Shell 4.1%
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