{"version":3,"sources":["../src/mcp/types.ts","../src/mcp/tool-host.ts","../src/mcp/server.ts","../src/mcp/transports/in-process.ts","../src/mcp/transports/relay.ts"],"names":[],"mappings":"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","file":"mcp.cjs","sourcesContent":["/**\n * Minimal MCP (Model Context Protocol) types — covers the subset this\n * package implements: initialize, tools/list, tools/call, plus JSON-RPC.\n *\n * Aligned with the public MCP spec but trimmed to v0.1 needs. See\n * https://spec.modelcontextprotocol.io/ for the full surface.\n */\n\nexport type JsonValue =\n  | string\n  | number\n  | boolean\n  | null\n  | { [key: string]: JsonValue }\n  | JsonValue[];\n\nexport type JsonObject = { [key: string]: JsonValue };\n\nexport type JsonRpcId = string | number | null;\n\nexport type JsonRpcRequest = {\n  jsonrpc: \"2.0\";\n  id: JsonRpcId;\n  method: string;\n  params?: JsonObject;\n};\n\nexport type JsonRpcNotification = {\n  jsonrpc: \"2.0\";\n  method: string;\n  params?: JsonObject;\n};\n\nexport type JsonRpcSuccess = {\n  jsonrpc: \"2.0\";\n  id: JsonRpcId;\n  result: JsonValue;\n};\n\nexport type JsonRpcError = {\n  jsonrpc: \"2.0\";\n  id: JsonRpcId;\n  error: { code: number; message: string; data?: JsonValue };\n};\n\nexport type JsonRpcMessage = JsonRpcRequest | JsonRpcNotification | JsonRpcSuccess | JsonRpcError;\n\nexport const JSONRPC_PARSE_ERROR = -32700;\nexport const JSONRPC_INVALID_REQUEST = -32600;\nexport const JSONRPC_METHOD_NOT_FOUND = -32601;\nexport const JSONRPC_INVALID_PARAMS = -32602;\nexport const JSONRPC_INTERNAL_ERROR = -32603;\n\nexport type ServerCapabilities = {\n  tools?: { listChanged?: boolean };\n  resources?: { listChanged?: boolean; subscribe?: boolean };\n  prompts?: { listChanged?: boolean };\n  logging?: Record<string, never>;\n  experimental?: Record<string, JsonValue>;\n};\n\nexport type ServerInfo = {\n  name: string;\n  version: string;\n  title?: string;\n};\n\nexport type InitializeResult = {\n  protocolVersion: string;\n  capabilities: ServerCapabilities;\n  serverInfo: ServerInfo;\n  instructions?: string;\n};\n\nexport type ToolInputSchema = {\n  /** The JSON Schema dialect, when a server states it (e.g. draft-07). */\n  $schema?: string;\n  type: \"object\";\n  properties?: Record<string, JsonValue>;\n  required?: string[];\n  additionalProperties?: boolean;\n};\n\n/** Behaviour hints a client may use when presenting or gating a tool. */\nexport type ToolAnnotations = {\n  title?: string;\n  readOnlyHint?: boolean;\n  destructiveHint?: boolean;\n  idempotentHint?: boolean;\n  openWorldHint?: boolean;\n};\n\n/**\n * A tool as `tools/list` reports it. Every field is passed to the client\n * verbatim, so the optional ones below are the spec's, not extensions.\n */\nexport type ToolDefinition = {\n  name: string;\n  title?: string;\n  description?: string;\n  inputSchema: ToolInputSchema;\n  /** JSON Schema for `structuredContent`, when the tool returns it. */\n  outputSchema?: ToolInputSchema;\n  annotations?: ToolAnnotations;\n  /** 2025-11-25: whether the tool may run as a task. */\n  execution?: { taskSupport?: \"forbidden\" | \"optional\" | \"required\" };\n  _meta?: { [key: string]: JsonValue };\n};\n\nexport type ContentBlock =\n  | { type: \"text\"; text: string }\n  | { type: \"image\"; data: string; mimeType: string }\n  | { type: \"resource\"; resource: { uri: string; text?: string; mimeType?: string } };\n\nexport type CallToolResult = {\n  content: ContentBlock[];\n  isError?: boolean;\n  /** Structured tool output — non-spec but useful for typed bridges. */\n  structuredContent?: JsonValue;\n};\n\n/** Handler signature for a tool registered on the MicroMcpServer. */\nexport type ToolCallContext = { transport?: unknown };\nexport type ToolHandler = (args: JsonObject, context?: ToolCallContext) => Promise<CallToolResult> | CallToolResult;\n\n/**\n * Options for `ToolHost.registerTool`.\n *\n * Tool names are one namespace shared by every bridge and agent on a host, so a\n * name belongs to whoever registered it. A second registrant for a held name is\n * refused rather than silently replacing the first.\n */\nexport type RegisterToolOptions = {\n  /**\n   * Who is registering — a stable identity for the surface, e.g. the bridge id\n   * (`\"whiteboard\"`, `\"chart:revenue\"`). The SAME owner may register a name it\n   * already holds again; that replaces the tool, which is what a React remount\n   * needs. A different owner is refused. A registration without an owner is a\n   * registrant nobody can identify, so it never matches another one.\n   */\n  owner?: string;\n  /**\n   * Take the name over whoever holds it. The explicit opt-in for the one thing\n   * `registerTool` used to do implicitly; reach for it only when replacing\n   * another registrant's tool is the point.\n   */\n  replace?: boolean;\n};\n\n/** Internal record kept by the server. */\nexport type RegisteredTool = {\n  definition: ToolDefinition;\n  handler: ToolHandler;\n  /** The registrant that holds this name, when it identified itself. */\n  owner?: string;\n};\n\nexport const MCP_PROTOCOL_VERSION = \"2025-06-18\";\n","import type {\n  CallToolResult,\n  JsonObject,\n  RegisteredTool,\n  RegisterToolOptions,\n  ToolDefinition,\n  ToolHandler,\n} from \"./types\";\n\n/**\n * ToolHost — the minimal surface a bridge needs to register its tools.\n *\n * Bridges (whiteboard, flow, sheets, code, charts, screens, scene, form)\n * speak only through this interface. The MCP server implements it\n * alongside its transport / JSON-RPC duties, and the standalone\n * {@link ToolRegistry} implements it for in-process agents that don't\n * need any of MCP's wire framing.\n *\n * Net effect: every bridge works equally well behind an MCP server\n * (browser ↔ external agents over SSE) or behind a plain registry\n * (in-process agent calling `host.callTool(\"sheet_set_cell\", { … })`).\n */\nexport interface ToolHost {\n  /**\n   * Register a tool. Returns a disposer that unregisters it.\n   *\n   * Throws when the name is already held by a DIFFERENT registrant (see\n   * {@link RegisterToolOptions.owner}), unless `replace: true` is passed. The\n   * same owner registering again replaces its own tool.\n   */\n  registerTool(definition: ToolDefinition, handler: ToolHandler, options?: RegisterToolOptions): () => void;\n\n  /** Look up an already-registered tool's definition + handler, or null. */\n  getTool(name: string): RegisteredTool | null;\n\n  /** Snapshot of all currently-registered tool definitions. */\n  listTools(): ToolDefinition[];\n\n  /**\n   * Invoke a registered tool directly, bypassing any transport layer.\n   * Throws if no tool is registered under `name`.\n   *\n   * This is the single entry point in-process agents use to drive the\n   * surface — no JSON-RPC framing, no transport plumbing.\n   */\n  callTool(name: string, args?: JsonObject): Promise<CallToolResult>;\n}\n\n/**\n * Standalone in-memory ToolHost. Use this when no MCP server is needed —\n * e.g. an in-process agent that just wants to register the same bridges\n * and call them directly.\n *\n * Example:\n *\n *   const host = new ToolRegistry();\n *   registerSheetsBridge(host, { adapter });\n *   const result = await host.callTool(\"sheet_set_cell\", { address: \"B3\", value: 42 });\n *\n * Pair with a MicroMcpServer in the same app to expose the same tools\n * to remote agents over SSE while in-process agents still get\n * zero-overhead direct calls.\n */\nexport class ToolRegistry implements ToolHost {\n  protected readonly tools = new Map<string, RegisteredTool>();\n\n  /**\n   * Tools that existed and were withdrawn, kept so a call that races an unmount\n   * can say WHICH thing happened.\n   *\n   * The tool surface is dynamic by design — \"site tools always, page tools while\n   * mounted\" — so an agent deciding to call a tool while the human navigates\n   * away is normal traffic, not an edge case. Reporting that as `Unknown tool`\n   * is the least useful thing available: it reads as \"the agent is broken\" or\n   * \"you asked for something imaginary\", when the truth is \"that surface just\n   * closed\".\n   *\n   * Names only. Nothing about the handler is retained, so this cannot keep a\n   * disposed surface alive.\n   */\n  protected readonly withdrawn = new Set<string>();\n\n  registerTool(definition: ToolDefinition, handler: ToolHandler, options: RegisterToolOptions = {}): () => void {\n    const name = definition.name;\n    const { owner, replace = false } = options;\n    const held = this.tools.get(name);\n\n    // A name is one surface's. Replacing it silently left the first surface\n    // listed but unreachable — every call went to the second handler and\n    // nothing said so. Only the same identified owner may re-register (a\n    // remount); anyone else must ask for it with `replace: true`.\n    if (held && !replace && (owner === undefined || held.owner !== owner)) {\n      throw new Error(\n        `Tool \"${name}\" is already registered by ${describeOwner(held.owner)}; `\n          + `${describeOwner(owner)} cannot register it too. `\n          + `Two registrants for one name would leave the first one listed but unreachable. `\n          + `Give one of them a different tool name, dispose the first registration, `\n          + `or pass { replace: true } to take the name over deliberately.`,\n      );\n    }\n\n    const record: RegisteredTool = owner === undefined ? { definition, handler } : { definition, handler, owner };\n    this.tools.set(name, record);\n    // A remounted surface must stop apologising for a previous unmount.\n    this.withdrawn.delete(name);\n    this.onToolsChanged();\n    return () => {\n      // Only withdraw what THIS registration put there. A replaced registration's\n      // disposer often runs late (a remount's cleanup), and must not take its\n      // successor down with it.\n      if (this.tools.get(name) === record) {\n        this.tools.delete(name);\n        this.withdrawn.add(name);\n        this.onToolsChanged();\n      }\n    };\n  }\n\n  /** Why `name` is not callable, phrased for whoever has to act on it. */\n  protected missingToolMessage(name: string): string {\n    return this.withdrawn.has(name)\n      ? `Tool \"${name}\" was withdrawn: the surface it targets is no longer mounted. `\n        + `Call tools/list for the current surface — the site-wide tools remain available.`\n      : `Unknown tool: ${name}`;\n  }\n\n  getTool(name: string): RegisteredTool | null {\n    return this.tools.get(name) ?? null;\n  }\n\n  listTools(): ToolDefinition[] {\n    return Array.from(this.tools.values()).map((t) => t.definition);\n  }\n\n  async callTool(name: string, args: JsonObject = {}): Promise<CallToolResult> {\n    const tool = this.tools.get(name);\n    if (!tool) {\n      throw new Error(this.missingToolMessage(name));\n    }\n    return tool.handler(args);\n  }\n\n  /**\n   * Hook for subclasses (e.g. MicroMcpServer) to notify subscribers\n   * when the tool catalog changes. Default no-op.\n   */\n  protected onToolsChanged(): void {}\n}\n\nfunction describeOwner(owner: string | undefined): string {\n  return owner === undefined\n    ? \"an unnamed registrant (pass { owner } to registerTool to identify it)\"\n    : `\"${owner}\"`;\n}\n","import {\n  type CallToolResult,\n  type JsonObject,\n  type JsonRpcMessage,\n  type JsonRpcRequest,\n  type JsonRpcId,\n  type RegisteredTool,\n  type ServerCapabilities,\n  type ServerInfo,\n  type ToolDefinition,\n  type ToolHandler,\n  JSONRPC_INTERNAL_ERROR,\n  JSONRPC_INVALID_PARAMS,\n  JSONRPC_METHOD_NOT_FOUND,\n  MCP_PROTOCOL_VERSION,\n} from \"./types\";\nimport { ToolRegistry } from \"./tool-host\";\n\nexport type McpServerOptions = {\n  info: ServerInfo;\n  /** Defaults to { tools: { listChanged: true } } */\n  capabilities?: ServerCapabilities;\n  /** Free-text instructions surfaced to clients during initialize. */\n  instructions?: string;\n  /**\n   * The protocol revisions this server speaks, NEWEST FIRST.\n   *\n   * `initialize` echoes the client's requested revision when it is in this\n   * list, and answers the first entry otherwise — the spec's rule, which leaves\n   * the client to decide whether it can live with the answer.\n   *\n   * Defaults to `[MCP_PROTOCOL_VERSION]`: one revision, answered whatever the\n   * client asks, which is exactly what this server did before the option\n   * existed. Only list a revision the tools you register are correct under.\n   */\n  protocolVersions?: readonly string[];\n};\n\nexport type Transport = {\n  /** Called by the server when it has a message to deliver to the client. */\n  send: (message: JsonRpcMessage) => void;\n  /** Called by the server when it's torn down so the transport can clean up. */\n  close?: () => void;\n};\n\n/**\n * MicroMcpServer — protocol-level MCP server, transport-agnostic.\n *\n * Use it like:\n *\n *   const server = new MicroMcpServer({ info: { name: \"session\", version: \"0.1\" } });\n *   server.registerTool({ name: \"...\", inputSchema: { type: \"object\" } }, async (args) => ({...}));\n *   const transport = new InProcessTransport();\n *   server.attach(transport);\n *   transport.deliver({ ... }); // client → server frames\n *\n * The same server can serve multiple transports (e.g. an in-process agent\n * AND a relayed external client) by attaching each one.\n */\nexport class MicroMcpServer extends ToolRegistry {\n  private transports = new Set<Transport>();\n  /**\n   * Transports owed a `tools/list_changed` at the end of this tick. Empty when\n   * none is scheduled. See {@link scheduleListChangedNotification}.\n   */\n  private listChangedOwed = new Set<Transport>();\n\n  readonly info: ServerInfo;\n  readonly capabilities: ServerCapabilities;\n  readonly instructions?: string;\n  readonly protocolVersions: readonly string[];\n\n  constructor(options: McpServerOptions) {\n    super();\n    this.info = options.info;\n    this.capabilities = options.capabilities ?? { tools: { listChanged: true } };\n    this.instructions = options.instructions;\n    if (options.protocolVersions && options.protocolVersions.length === 0) {\n      // No answer exists for a client's initialize. Fail here, next to the\n      // mistake, rather than in a handshake nobody is watching.\n      throw new Error(\"MicroMcpServer: protocolVersions is empty — a server must speak at least one protocol revision.\");\n    }\n    this.protocolVersions = options.protocolVersions ? [...options.protocolVersions] : [MCP_PROTOCOL_VERSION];\n  }\n\n  attach(transport: Transport): () => void {\n    this.transports.add(transport);\n    return () => this.detach(transport);\n  }\n\n  detach(transport: Transport): void {\n    if (this.transports.delete(transport)) {\n      transport.close?.();\n    }\n  }\n\n  unregisterTool(name: string): void {\n    if (this.tools.delete(name)) {\n      this.scheduleListChangedNotification();\n    }\n  }\n\n  protected onToolsChanged(): void {\n    this.scheduleListChangedNotification();\n  }\n\n  /**\n   * Receive a JSON-RPC frame from a client (called by the transport).\n   * The transport is responsible for sending the response back.\n   */\n  async receive(transport: Transport, message: JsonRpcMessage): Promise<void> {\n    if (!(\"method\" in message)) return; // It's a response, not a request — ignore.\n\n    const isNotification = !(\"id\" in message);\n    if (isNotification) {\n      // Notifications are fire-and-forget. We ignore unknown methods.\n      return;\n    }\n\n    const request = message as JsonRpcRequest;\n    try {\n      const result = await this.handle(request, transport);\n      transport.send({ jsonrpc: \"2.0\", id: request.id, result });\n    } catch (err) {\n      transport.send({\n        jsonrpc: \"2.0\",\n        id: request.id,\n        error: this.toRpcError(err),\n      });\n    }\n  }\n\n  private async handle(request: JsonRpcRequest, transport: Transport): Promise<any> {\n    const { method, params } = request;\n    switch (method) {\n      case \"initialize\":\n        return {\n          protocolVersion: this.negotiate(params?.protocolVersion),\n          capabilities: this.capabilities,\n          serverInfo: this.info,\n          ...(this.instructions ? { instructions: this.instructions } : {}),\n        };\n\n      case \"tools/list\":\n        return { tools: this.listTools() };\n\n      case \"tools/call\": {\n        const name = params?.name;\n        const args = (params?.arguments ?? {}) as JsonObject;\n        if (typeof name !== \"string\") {\n          throw rpcError(JSONRPC_INVALID_PARAMS, \"tools/call requires `name`\");\n        }\n        const tool = this.tools.get(name);\n        if (!tool) {\n          throw rpcError(JSONRPC_METHOD_NOT_FOUND, this.missingToolMessage(name));\n        }\n        const result = await tool.handler(args, { transport });\n        return result satisfies CallToolResult;\n      }\n\n      case \"ping\":\n        return {};\n\n      default:\n        throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unsupported method: ${method}`);\n    }\n  }\n\n  /** The revision to answer `initialize` with: the one asked for if spoken, else the newest. */\n  private negotiate(requested: unknown): string {\n    return typeof requested === \"string\" && this.protocolVersions.includes(requested)\n      ? requested\n      : this.protocolVersions[0];\n  }\n\n  /**\n   * Tell the transports that SAW the old tool list that it changed.\n   *\n   * Changes in one tick coalesce into one notification. The recipients are the\n   * transports attached at the moment of a change, not at the moment the\n   * notification goes out: a transport attached afterwards never had the old\n   * list, so \"your list is stale\" is noise to it — and on stdio, where a host\n   * builds the server and attaches stdin/stdout in the same tick, it was the\n   * first frame a client received, before it had even sent `initialize`.\n   */\n  private scheduleListChangedNotification(): void {\n    if (this.transports.size === 0) return;\n    const scheduled = this.listChangedOwed.size > 0;\n    for (const t of this.transports) this.listChangedOwed.add(t);\n    if (scheduled) return;\n    queueMicrotask(() => {\n      const owed = this.listChangedOwed;\n      this.listChangedOwed = new Set();\n      for (const t of owed) {\n        // Detached since the change: it is not listening any more.\n        if (this.transports.has(t)) t.send({ jsonrpc: \"2.0\", method: \"notifications/tools/list_changed\" });\n      }\n    });\n  }\n\n  /** Send an application notification to every client, or one attached transport. */\n  notify(message: JsonRpcMessage, transport?: Transport): void {\n    if (transport) transport.send(message);\n    else this.broadcast(message);\n  }\n\n  private broadcast(message: JsonRpcMessage): void {\n    for (const t of this.transports) t.send(message);\n  }\n\n  private toRpcError(err: unknown): { code: number; message: string; data?: any } {\n    if (err && typeof err === \"object\" && \"code\" in err && \"message\" in err) {\n      return err as any;\n    }\n    return {\n      code: JSONRPC_INTERNAL_ERROR,\n      message: err instanceof Error ? err.message : String(err),\n    };\n  }\n}\n\nexport function rpcError(code: number, message: string, data?: any) {\n  return { code, message, ...(data !== undefined ? { data } : {}) };\n}\n\n/**\n * Helper to build a CallToolResult from a string or structured value.\n */\nexport function textResult(text: string, structured?: any): CallToolResult {\n  return {\n    content: [{ type: \"text\", text }],\n    ...(structured !== undefined ? { structuredContent: structured } : {}),\n  };\n}\n\nexport function errorResult(text: string): CallToolResult {\n  return { content: [{ type: \"text\", text }], isError: true };\n}\n\n// Internal helper so the JsonRpcId import isn't dropped by tsup\ntype _KeepIdImport = JsonRpcId;\n","import type { JsonRpcMessage } from \"../types\";\nimport type { MicroMcpServer, Transport } from \"../server\";\n\n/**\n * InProcessTransport — direct function-call wiring between an in-page MCP\n * client (e.g. an embedded chat agent) and a MicroMcpServer running in\n * the same JS context. No serialization, no network.\n *\n * Usage:\n *\n *   const t = new InProcessTransport();\n *   server.attach(t);\n *   t.onServerMessage((msg) => { ... });   // client subscribes\n *   t.send({ jsonrpc: \"2.0\", id: 1, method: \"tools/list\" }); // client → server\n */\nexport class InProcessTransport implements Transport {\n  private server?: MicroMcpServer;\n  private listeners = new Set<(msg: JsonRpcMessage) => void>();\n\n  /** Bind to a server. Called from the client's setup, not directly. */\n  bindServer(server: MicroMcpServer): void {\n    this.server = server;\n  }\n\n  /** Server → client (delivered to subscribed listeners). */\n  send(message: JsonRpcMessage): void {\n    for (const l of this.listeners) l(message);\n  }\n\n  /** Client → server. Awaitable so callers can flush. */\n  async deliver(message: JsonRpcMessage): Promise<void> {\n    if (!this.server) throw new Error(\"InProcessTransport has no bound server\");\n    await this.server.receive(this, message);\n  }\n\n  /** Subscribe to messages the server pushes to this client. */\n  onServerMessage(listener: (msg: JsonRpcMessage) => void): () => void {\n    this.listeners.add(listener);\n    return () => this.listeners.delete(listener);\n  }\n\n  close(): void {\n    this.listeners.clear();\n  }\n}\n\n/**\n * Convenience: create a server-attached in-process transport in one call.\n */\nexport function attachInProcess(server: MicroMcpServer): InProcessTransport {\n  const transport = new InProcessTransport();\n  transport.bindServer(server);\n  server.attach(transport);\n  return transport;\n}\n","import type { JsonRpcMessage } from \"../types\";\nimport type { MicroMcpServer, Transport } from \"../server\";\n\n/**\n * RelayTransport — wraps any duplex JSON-frame channel (e.g. a Reverb\n * websocket private channel, a WebRTC data channel) so external agents\n * can talk to a browser-side MicroMcpServer.\n *\n * The host app owns the actual channel. This class only handles framing\n * (JSON.stringify / JSON.parse) and the server contract.\n *\n * Channel contract:\n *   - host calls `transport.deliverFromRemote(payload)` with each frame\n *     it receives from the remote agent\n *   - host implements `sendToRemote(frame)` so the transport can deliver\n *     server → client frames outward\n *\n * See docs/relay-protocol.md for the wire format.\n */\nexport type RelayChannel = {\n  sendToRemote: (frame: JsonRpcMessage) => void;\n  /** Optional: notify the channel that the server is gone. */\n  onClose?: () => void;\n};\n\nexport class RelayTransport implements Transport {\n  private server?: MicroMcpServer;\n  constructor(private channel: RelayChannel) {}\n\n  bindServer(server: MicroMcpServer): void {\n    this.server = server;\n  }\n\n  send(message: JsonRpcMessage): void {\n    this.channel.sendToRemote(message);\n  }\n\n  /**\n   * Host calls this with each frame received from the remote agent. Accepts\n   * either a parsed object or a raw JSON string.\n   */\n  async deliverFromRemote(payload: JsonRpcMessage | string): Promise<void> {\n    if (!this.server) throw new Error(\"RelayTransport has no bound server\");\n    const message = typeof payload === \"string\"\n      ? (JSON.parse(payload) as JsonRpcMessage)\n      : payload;\n    await this.server.receive(this, message);\n  }\n\n  close(): void {\n    this.channel.onClose?.();\n  }\n}\n\n/**\n * Convenience wiring. Returns the bound transport.\n */\nexport function attachRelay(server: MicroMcpServer, channel: RelayChannel): RelayTransport {\n  const transport = new RelayTransport(channel);\n  transport.bindServer(server);\n  server.attach(transport);\n  return transport;\n}\n"]}