UNPKG

@fusedashlabs/ui9000-workspace

Version:

UI9000 workspace MCP. One tool, show_workspace, draws a chart from your table. Set TYPESAFE_API_KEY to let Jev choose the chart.

79 lines (78 loc) • 3.5 kB
/** * Thin MCP server. Registers exactly one tool: show_workspace. * * The handler is injected. This module does not import `handleShowWorkspace`, * `src/engine`, or the catalog — it only moves JSON-RPC frames between a * transport and the handler, so the tool contract can change without touching * the server. The registered name is `SHOW_WORKSPACE_NAME` from the tool * module so it cannot drift from the contract. * * In-process tests use this hand-rolled `handle()`. Live stdio * (`startWorkspaceServer`) uses `createSdkWorkspaceServer` (MCP SDK 1.30 + * ext-apps), the same wire Cursor issues `resources/read` against. */ import { SHOW_WORKSPACE_NAME } from '../tool/show-workspace.js'; import type { McpAppResource } from './mcp-app.js'; export { SHOW_WORKSPACE_NAME }; /** Injected implementation of show_workspace. Args arrive unparsed from the client. */ export type ShowWorkspaceHandler = (args: unknown) => unknown | Promise<unknown>; /** * Tool metadata. The real description and input schema live with the tool * contract (S3-09) and are passed in; a stub may pass 'stub' or nothing. */ export type ShowWorkspaceToolInfo = { description?: string; inputSchema?: Record<string, unknown>; /** When set, Cursor/Claude open `ui://` instead of the JSON data-link. */ appResource?: McpAppResource; }; export type ToolDescriptor = { name: string; description?: string; inputSchema: Record<string, unknown>; _meta?: Record<string, unknown>; }; export type JsonRpcId = string | number; export type JsonRpcResponse = { jsonrpc: '2.0'; id: JsonRpcId; result?: unknown; error?: { code: number; message: string; data?: unknown; }; }; export type McpServer = { /** Always length 1. Exposed so callers can assert the surface without a round trip. */ readonly tools: readonly ToolDescriptor[]; /** Handles one decoded JSON-RPC message. Returns null for notifications. */ handle(message: unknown): Promise<JsonRpcResponse | null>; }; export declare const PROTOCOL_VERSION = "2025-06-18"; /** Echo a supported client version. An absent or unknown one keeps the server default. */ export declare function negotiateProtocol(params: unknown): string; export declare const SERVER_INFO: { readonly name: "ui9000-core"; readonly version: "0.0.0"; }; /** * Returned on initialize. Hosts such as Claude put this in context before they * pick a tool. It does not remove the host's own chart tools. */ export declare const WORKSPACE_INSTRUCTIONS: string; declare const PARSE_ERROR = -32700; declare const INVALID_REQUEST = -32600; declare const METHOD_NOT_FOUND = -32601; declare const INVALID_PARAMS = -32602; declare const INTERNAL_ERROR = -32603; /** * Builds the server. One tool, one handler, no registry: a second registerTool * call is impossible by construction, so generate_* tools cannot appear. */ export declare function createServer(handler: ShowWorkspaceHandler, info?: ShowWorkspaceToolInfo): McpServer; /** Same CallToolResult envelope the stdio SDK path returns. */ export declare function workspaceToolResult(result: unknown, appResource: McpAppResource | undefined): Record<string, unknown>; export declare function okResponse(id: JsonRpcId, result: unknown): JsonRpcResponse; export declare function errorResponse(id: JsonRpcId, code: number, message: string): JsonRpcResponse; export { PARSE_ERROR, INVALID_REQUEST, METHOD_NOT_FOUND, INVALID_PARAMS, INTERNAL_ERROR };