/** * mcp/server/stdio-server.ts * * A minimal, dependency-free Model Context Protocol server that speaks JSON-RPC * 2.0 over a newline-delimited stream (stdio is the local-first default). It * exposes the GoodVibes operator surface as MCP tools (tool-definitions.ts) and * dispatches every tools/call through an injected invoker, so the transport that * reaches the daemon is the consumer's choice, the operator client, an * in-process handler, anything, and this module stays pure protocol plumbing. * * Implemented against the protocol directly rather than pulling in an MCP SDK * dependency: the surface is small (initialize / tools/list / tools/call / * ping), and keeping it in-tree preserves the repo's dependency and audit * discipline. */ import type { OperatorMcpToolSet } from './tool-definitions.js'; /** The default MCP protocol version this server advertises when the client sends none. */ export declare const DEFAULT_MCP_PROTOCOL_VERSION = "2025-06-18"; /** Invokes an operator method by id with a params object, returning its result. */ export type OperatorMcpInvoker = (methodId: string, input: Record) => unknown | Promise; export interface OperatorMcpServerInfo { readonly name: string; readonly version: string; } export interface OperatorMcpServerOptions { readonly toolSet: OperatorMcpToolSet; readonly invoke: OperatorMcpInvoker; readonly serverInfo?: OperatorMcpServerInfo | undefined; readonly instructions?: string | undefined; } interface JsonRpcRequest { readonly jsonrpc: '2.0'; readonly id?: string | number | null | undefined; readonly method: string; readonly params?: Record | undefined; } interface JsonRpcResponse { readonly jsonrpc: '2.0'; readonly id: string | number | null; readonly result?: unknown; readonly error?: { readonly code: number; readonly message: string; readonly data?: unknown; }; } /** * The protocol core: turns a decoded JSON-RPC message into a response (or null * for a notification, which gets none). Transport-agnostic, call it from a * stdio loop, a socket, or a test. */ export declare class OperatorMcpServer { private readonly toolSet; private readonly invoke; private readonly serverInfo; private readonly instructions; constructor(options: OperatorMcpServerOptions); /** The MCP tools this server advertises (wire shape). */ listTools(): Record[]; /** Dispatch a tools/call: resolve the tool to its operator method and invoke it. */ callTool(name: unknown, args: unknown): Promise>; private toolError; private initializeResult; /** Handle a decoded JSON-RPC request. Returns null for a notification (no id). */ handleRequest(request: JsonRpcRequest): Promise; /** * Decode one line of newline-delimited JSON-RPC, dispatch it, and return the * response line to write (or null for a notification / blank line). A parse * failure returns a JSON-RPC parse-error response with a null id. */ handleLine(line: string): Promise; } /** A newline-delimited line transport: a source of inbound lines and a sink for outbound ones. */ export interface McpLineTransport { readonly lines: AsyncIterable; write(line: string): void | Promise; } /** * Run the server over a line transport until the inbound stream ends. Each * inbound line is dispatched; a non-null response line is written back. */ export declare function serveOperatorMcp(server: OperatorMcpServer, transport: McpLineTransport): Promise; /** A Node-style readable stream that yields string or byte chunks. */ export interface ChunkSource { [Symbol.asyncIterator](): AsyncIterator; } /** A Node-style writable stream. */ export interface ChunkSink { write(chunk: string): unknown; } /** Turn a byte/string chunk stream into an async iterable of newline-delimited lines. */ export declare function readLines(source: ChunkSource): AsyncIterable; /** Build a line transport from a Node-style readable/writable pair (e.g. process.stdin/stdout). */ export declare function createStreamTransport(input: ChunkSource, output: ChunkSink): McpLineTransport; export {}; //# sourceMappingURL=stdio-server.d.ts.map