MCP server at POST /mcp (official SDK, stateless Streamable HTTP) #11

Merged
kamilkrzywda merged 1 commits from feat/mcp-server into main 2026-09-24 20:39:45 +02:00
Owner

What

New POST /mcp — an in-process MCP (Model Context Protocol) server alongside the REST API and Scalar docs. Official @modelcontextprotocol/sdk 1.30.1, stateless Streamable HTTP transport (fresh McpServer + transport per request, no session store). Point any MCP client at http://bot.dev.kkhost.pl/mcp.

Tools (map 1:1 to MeshService methods — no new logic)

tool input maps to
mesh_status — status() → {connected, myNodeNum, host, port}
send_message {text, to?} resolveDest(to) + sendText — same semantics as POST /api/send (number | name | "!b"), errors surface with the REST messages
list_channels — channels()
list_nodes — nodes()
get_node {id} node(id) — tool error when missing/ambiguous
get_messages — messages() (newest first, last 100, tx delivery status)

All sends ride the pinned "test" channel index 3 (MESH_SEND_CHANNEL).

Details

  • /mcp excluded from the /api global prefix via setGlobalPrefix('api', { exclude: ['mcp'] })
  • SDK root entry is broken upstream (#2273 — dist/index.js missing from every published tarball) → imports use subpaths with .js extensions (server/mcp.js, server/streamableHttp.js, ...), noted in a code comment
  • Fake-bridge test helpers extracted to src/mesh/fake-bridge.ts for reuse (importing a .spec.ts would double-register its tests)

Verification

  • npm run build ✓
  • npm test — 30/30 passed (was 24, +6: tools/list with schemas, mesh_status shape, send_message broadcast+name-resolution, error messages, get_node resolve/missing, remaining read tools) via in-memory transport pair + SDK Client
  • lockfile verified in sync (npm ci --dry-run clean)
  • v0.6.0, CHANGELOG entry added
## What New `POST /mcp` — an in-process MCP (Model Context Protocol) server alongside the REST API and Scalar docs. Official `@modelcontextprotocol/sdk` 1.30.1, stateless Streamable HTTP transport (fresh McpServer + transport per request, no session store). Point any MCP client at `http://bot.dev.kkhost.pl/mcp`. ## Tools (map 1:1 to MeshService methods — no new logic) | tool | input | maps to | |---|---|---| | `mesh_status` | — | status() → {connected, myNodeNum, host, port} | | `send_message` | {text, to?} | resolveDest(to) + sendText — same semantics as POST /api/send (number \| name \| "!b"), errors surface with the REST messages | | `list_channels` | — | channels() | | `list_nodes` | — | nodes() | | `get_node` | {id} | node(id) — tool error when missing/ambiguous | | `get_messages` | — | messages() (newest first, last 100, tx delivery status) | All sends ride the pinned "test" channel index 3 (MESH_SEND_CHANNEL). ## Details - `/mcp` excluded from the /api global prefix via `setGlobalPrefix('api', { exclude: ['mcp'] })` - SDK root entry is broken upstream (#2273 — dist/index.js missing from every published tarball) → imports use subpaths with .js extensions (`server/mcp.js`, `server/streamableHttp.js`, ...), noted in a code comment - Fake-bridge test helpers extracted to src/mesh/fake-bridge.ts for reuse (importing a .spec.ts would double-register its tests) ## Verification - `npm run build` ✓ - `npm test` — 30/30 passed (was 24, +6: tools/list with schemas, mesh_status shape, send_message broadcast+name-resolution, error messages, get_node resolve/missing, remaining read tools) via in-memory transport pair + SDK Client - lockfile verified in sync (`npm ci --dry-run` clean) - v0.6.0, CHANGELOG entry added
kamilkrzywda added 1 commit 2026-09-24 20:38:44 +02:00
kamilkrzywda merged commit b31fb35464 into main 2026-09-24 20:39:45 +02:00
kamilkrzywda deleted branch feat/mcp-server 2026-09-24 20:39:45 +02:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OpenCode/MeshBot#11