/** * In-process MCP server for rSpace. * * Exposes rSpace module data as MCP tools via Streamable HTTP at /api/mcp. * Stateless mode: fresh McpServer + transport per request. * Direct Automerge syncServer access for reads (no HTTP round-trip). * * 101 tools across 35 groups: * spaces (2), rcal (4), rnotes (5), rtasks (5), rwallet (4), * rsocials (4), rnetwork (3), rinbox (4), rtime (4), rfiles (3), rschedule (4), * rvote (3), rchoices (3), rtrips (4), rcart (4), rexchange (4), rbnb (4), * rvnb (3), crowdsurf (2), rbooks (2), rpubs (2), rmeets (2), rtube (2), * rswag (2), rdesign (2), rsplat (2), rphotos (2), rflows (2), rdocs (1), * rdata (1), rforum (2), rchats (3), rmaps (3), rsheets (2), rgov (2) * 1 resource: rspace://spaces/{slug} */ import { Hono } from "hono"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js"; import type { SyncServer } from "./local-first/sync-server"; import { registerSpacesTools } from "./mcp-tools/spaces"; import { registerCalTools } from "./mcp-tools/rcal"; import { registerNotesTools } from "./mcp-tools/rnotes"; import { registerTasksTools } from "./mcp-tools/rtasks"; import { registerWalletTools } from "./mcp-tools/rwallet"; import { registerSocialsTools } from "./mcp-tools/rsocials"; import { registerNetworkTools } from "./mcp-tools/rnetwork"; import { registerInboxTools } from "./mcp-tools/rinbox"; import { registerTimeTools } from "./mcp-tools/rtime"; import { registerFilesTools } from "./mcp-tools/rfiles"; import { registerScheduleTools } from "./mcp-tools/rschedule"; import { registerVoteTools } from "./mcp-tools/rvote"; import { registerChoicesTools } from "./mcp-tools/rchoices"; import { registerTripsTools } from "./mcp-tools/rtrips"; import { registerCartTools } from "./mcp-tools/rcart"; import { registerExchangeTools } from "./mcp-tools/rexchange"; import { registerBnbTools } from "./mcp-tools/rbnb"; import { registerVnbTools } from "./mcp-tools/rvnb"; import { registerCrowdSurfTools } from "./mcp-tools/crowdsurf"; import { registerBooksTools } from "./mcp-tools/rbooks"; import { registerPubsTools } from "./mcp-tools/rpubs"; import { registerMeetsTools } from "./mcp-tools/rmeets"; import { registerTubeTools } from "./mcp-tools/rtube"; import { registerSwagTools } from "./mcp-tools/rswag"; import { registerDesignTools } from "./mcp-tools/rdesign"; import { registerSplatTools } from "./mcp-tools/rsplat"; import { registerPhotosTools } from "./mcp-tools/rphotos"; import { registerFlowsTools } from "./mcp-tools/rflows"; import { registerDocsTools } from "./mcp-tools/rdocs"; import { registerDataTools } from "./mcp-tools/rdata"; import { registerForumTools } from "./mcp-tools/rforum"; import { registerChatsTools } from "./mcp-tools/rchats"; import { registerMapsTools } from "./mcp-tools/rmaps"; import { registerSheetsTools } from "./mcp-tools/rsheets"; import { registerGovTools } from "./mcp-tools/rgov"; function createMcpServerInstance(syncServer: SyncServer): McpServer { const server = new McpServer({ name: "rspace", version: "1.0.0", }); registerSpacesTools(server); registerCalTools(server, syncServer); registerNotesTools(server, syncServer); registerTasksTools(server, syncServer); registerWalletTools(server); registerSocialsTools(server, syncServer); registerNetworkTools(server, syncServer); registerInboxTools(server, syncServer); registerTimeTools(server, syncServer); registerFilesTools(server, syncServer); registerScheduleTools(server, syncServer); registerVoteTools(server, syncServer); registerChoicesTools(server, syncServer); registerTripsTools(server, syncServer); registerCartTools(server, syncServer); registerExchangeTools(server, syncServer); registerBnbTools(server, syncServer); registerVnbTools(server, syncServer); registerCrowdSurfTools(server, syncServer); registerBooksTools(server, syncServer); registerPubsTools(server, syncServer); registerMeetsTools(server, syncServer); registerTubeTools(server, syncServer); registerSwagTools(server, syncServer); registerDesignTools(server, syncServer); registerSplatTools(server, syncServer); registerPhotosTools(server, syncServer); registerFlowsTools(server, syncServer); registerDocsTools(server, syncServer); registerDataTools(server, syncServer); registerForumTools(server, syncServer); registerChatsTools(server, syncServer); registerMapsTools(server, syncServer); registerSheetsTools(server, syncServer); registerGovTools(server); return server; } export function createMcpRouter(syncServer: SyncServer): Hono { const router = new Hono(); router.all("/*", async (c) => { const server = createMcpServerInstance(syncServer); const transport = new WebStandardStreamableHTTPServerTransport({ enableJsonResponse: true, }); await server.connect(transport); const response = await transport.handleRequest(c.req.raw); return response; }); return router; }