{"version":3,"file":"mcp.mjs","names":[],"sources":["../../src/feature/mcp.ts"],"sourcesContent":["import { buildInputSchema, collectEndpoints, serializeArgsToFlags } from '../core/commands.ts';\nimport { generateHelp } from '../output/help.ts';\nimport type { AnyPadroneCommand, AnyPadroneProgram } from '../types/index.ts';\nimport { readStreamAsText } from '../util/stream.ts';\n\nexport type PadroneMcpPreferences = {\n  /** Server name. Defaults to the program name. */\n  name?: string;\n  /** Server version. Defaults to the program version. */\n  version?: string;\n  /**\n   * Transport mode.\n   * - `'http'` — Start a Streamable HTTP server (default). Responds with `application/json` or `text/event-stream` based on the client's `Accept` header. Use `port` and `host` to configure.\n   * - `'stdio'` — Communicate over stdin/stdout with newline-delimited JSON.\n   */\n  transport?: 'http' | 'stdio';\n  /** HTTP port. Defaults to `3000`. Only used with `transport: 'http'`. */\n  port?: number;\n  /** HTTP host. Defaults to `'127.0.0.1'`. Only used with `transport: 'http'`. */\n  host?: string;\n  /** Base path for the MCP endpoint. Defaults to `'/mcp'`. Only used with `transport: 'http'`. */\n  basePath?: string;\n  /** CORS allowed origin. Defaults to `'*'`. Set to a specific origin or `false` to disable CORS headers. Only used with HTTP transports. */\n  cors?: string | false;\n};\n\nconst PROTOCOL_VERSION = '2025-11-25';\n\ntype JsonRpcRequest = {\n  jsonrpc: '2.0';\n  id?: string | number;\n  method: string;\n  params?: Record<string, unknown>;\n};\n\ntype JsonRpcResponse = {\n  jsonrpc: '2.0';\n  id: string | number | null;\n  result?: unknown;\n  error?: { code: number; message: string; data?: unknown };\n};\n\n/** Convert an endpoint dot-path to a valid MCP tool name. Spec allows: [A-Za-z0-9_\\-\\.] */\nfunction toToolName(path: string): string {\n  return path.replace(/\\s+/g, '.');\n}\n\n/** Convert a tool name back to a command path (dot → space). */\nfunction toCommandPath(toolName: string): string {\n  return toolName.replace(/\\./g, ' ');\n}\n\n/** Build MCP tool annotations from a command's metadata. */\nfunction buildAnnotations(cmd: AnyPadroneCommand) {\n  if (cmd.mutation == null) return undefined;\n  return {\n    destructiveHint: cmd.mutation || undefined,\n    readOnlyHint: cmd.mutation === false || undefined,\n  };\n}\n\n/** Build an MCP tool definition from a command. */\nfunction buildToolDefinition(name: string, cmd: AnyPadroneCommand) {\n  return {\n    name: toToolName(name),\n    title: cmd.title ?? undefined,\n    description: cmd.description || cmd.title || `Run the \"${name}\" command`,\n    inputSchema: buildInputSchema(cmd),\n    annotations: buildAnnotations(cmd),\n  };\n}\n\n/** Create the MCP request handler. Returns an async function that processes a JSON-RPC request and returns a response (or undefined for notifications). */\nexport function createMcpHandler(\n  existingCommand: AnyPadroneCommand,\n  evalCommand: AnyPadroneProgram['eval'],\n  prefs?: PadroneMcpPreferences,\n) {\n  const serverName = prefs?.name ?? existingCommand.name;\n  const serverVersion = prefs?.version ?? existingCommand.version ?? '0.0.0';\n\n  const rootTools = collectEndpoints(existingCommand.commands, '');\n  if (existingCommand.action || existingCommand.argsSchema) {\n    rootTools.unshift({ name: '', command: existingCommand });\n  }\n\n  const toolMap = new Map(rootTools.map((t) => [toToolName(t.name), t]));\n\n  const helpToolName = 'help';\n  const helpToolDef = {\n    name: helpToolName,\n    title: 'Help',\n    description: `Show help for the \"${serverName}\" program or a specific command`,\n    inputSchema: {\n      type: 'object' as const,\n      properties: { command: { type: 'string', description: 'Command name to get help for (omit for program help)' } },\n      additionalProperties: false,\n    },\n  };\n\n  return async function handleRequest(req: JsonRpcRequest): Promise<JsonRpcResponse | undefined> {\n    const { id, method, params } = req;\n\n    switch (method) {\n      case 'initialize':\n        return {\n          jsonrpc: '2.0',\n          id: id ?? null,\n          result: {\n            protocolVersion: PROTOCOL_VERSION,\n            capabilities: { tools: {} },\n            serverInfo: { name: serverName, version: serverVersion },\n          },\n        };\n\n      case 'notifications/initialized':\n      case 'notifications/cancelled':\n        return undefined;\n\n      case 'ping':\n        return { jsonrpc: '2.0', id: id ?? null, result: {} };\n\n      case 'tools/list': {\n        const tools = [...rootTools.map((t) => buildToolDefinition(t.name, t.command)), helpToolDef];\n        return { jsonrpc: '2.0', id: id ?? null, result: { tools } };\n      }\n\n      case 'tools/call': {\n        const toolName = params?.name as string;\n        const args = (params?.arguments ?? {}) as Record<string, unknown>;\n\n        // Built-in help tool\n        if (toolName === helpToolName) {\n          const cmdName = args.command as string | undefined;\n          const targetCmd = cmdName ? rootTools.find((t) => t.name === cmdName || toToolName(t.name) === cmdName)?.command : undefined;\n          const helpText = generateHelp(existingCommand, targetCmd ?? existingCommand, { format: 'text', detail: 'full' });\n          return {\n            jsonrpc: '2.0',\n            id: id ?? null,\n            result: { content: [{ type: 'text', text: helpText }], isError: false },\n          };\n        }\n\n        const tool = toolMap.get(toolName);\n        if (!tool) {\n          return {\n            jsonrpc: '2.0',\n            id: id ?? null,\n            error: { code: -32602, message: `Unknown tool: ${toolName}` },\n          };\n        }\n\n        // Build command string: convert tool name back to command path + serialize args as flags\n        const commandPath = toCommandPath(tool.name);\n        const argParts = serializeArgsToFlags(args);\n        const input = [commandPath, ...argParts].filter(Boolean).join(' ') || undefined;\n\n        try {\n          const output: string[] = [];\n          const errors: string[] = [];\n          const result = await evalCommand(input as any, {\n            caller: 'mcp',\n            runtime: {\n              output: (...outArgs: unknown[]) => output.push(outArgs.map(String).join(' ')),\n              error: (text: string) => errors.push(text),\n              interactive: 'unsupported',\n              format: 'text',\n            },\n          });\n\n          const content: { type: string; text: string }[] = [];\n\n          if (result.error) {\n            const errorMsg = result.error instanceof Error ? result.error.message : String(result.error);\n            if (errors.length) content.push({ type: 'text', text: errors.join('\\n') });\n            content.push({ type: 'text', text: errorMsg });\n            return { jsonrpc: '2.0', id: id ?? null, result: { content, isError: true } };\n          }\n\n          if (result.argsResult?.issues) {\n            const issueMessages = result.argsResult.issues.map((i: any) => `${i.path?.join('.') || 'root'}: ${i.message}`).join('\\n');\n            content.push({ type: 'text', text: `Validation error:\\n${issueMessages}` });\n            return { jsonrpc: '2.0', id: id ?? null, result: { content, isError: true } };\n          }\n\n          if (output.length) content.push({ type: 'text', text: output.join('\\n') });\n          if (result.result !== undefined && result.result !== null) {\n            const resultText = typeof result.result === 'string' ? result.result : JSON.stringify(result.result, null, 2);\n            content.push({ type: 'text', text: resultText });\n          }\n          if (content.length === 0) content.push({ type: 'text', text: 'Done.' });\n          return { jsonrpc: '2.0', id: id ?? null, result: { content, isError: false } };\n        } catch (err) {\n          const errorMsg = err instanceof Error ? err.message : String(err);\n          return {\n            jsonrpc: '2.0',\n            id: id ?? null,\n            result: { content: [{ type: 'text', text: errorMsg }], isError: true },\n          };\n        }\n      }\n\n      default: {\n        if (id !== undefined) {\n          return { jsonrpc: '2.0', id, error: { code: -32601, message: `Method not found: ${method}` } };\n        }\n        return undefined;\n      }\n    }\n  };\n}\n\n/** stdio transport: newline-delimited JSON per 2025-11-25 spec. */\nasync function startStdioTransport(handleRequest: (req: JsonRpcRequest) => Promise<JsonRpcResponse | undefined>): Promise<void> {\n  const { stdin, stdout } = await import('node:process');\n  const { createInterface } = await import('node:readline');\n\n  function send(msg: JsonRpcResponse) {\n    stdout.write(`${JSON.stringify(msg)}\\n`);\n  }\n\n  const rl = createInterface({ input: stdin, crlfDelay: Infinity });\n\n  for await (const line of rl) {\n    if (!line.trim()) continue;\n    try {\n      const req = JSON.parse(line) as JsonRpcRequest;\n      const res = await handleRequest(req);\n      if (res) send(res);\n    } catch {\n      // Ignore malformed JSON\n    }\n  }\n}\n\n/** Streamable HTTP transport per 2025-11-25 spec. Responds with JSON or SSE based on client's Accept header. */\nasync function startHttpTransport(\n  handleRequest: (req: JsonRpcRequest) => Promise<JsonRpcResponse | undefined>,\n  prefs: PadroneMcpPreferences,\n  log: (msg: string) => void,\n  onSignal?: (callback: () => void) => () => void,\n): Promise<void> {\n  const http = await import('node:http');\n  const crypto = await import('node:crypto');\n\n  const port = prefs.port ?? 3000;\n  const host = prefs.host ?? '127.0.0.1';\n  const endpoint = prefs.basePath ?? '/mcp';\n\n  // Session management\n  let sessionId: string | undefined;\n  let negotiatedVersion: string | undefined;\n\n  const corsOrigin = prefs.cors !== false ? (prefs.cors ?? '*') : undefined;\n\n  const server = http.createServer(async (req, res) => {\n    // CORS headers\n    if (corsOrigin) {\n      res.setHeader('Access-Control-Allow-Origin', corsOrigin);\n      res.setHeader('Access-Control-Allow-Methods', 'POST, GET, DELETE, OPTIONS');\n      res.setHeader('Access-Control-Allow-Headers', 'Content-Type, MCP-Session-Id, MCP-Protocol-Version');\n      res.setHeader('Access-Control-Expose-Headers', 'MCP-Session-Id');\n    }\n\n    if (req.method === 'OPTIONS') {\n      res.writeHead(corsOrigin ? 204 : 405);\n      res.end();\n      return;\n    }\n\n    if (req.url !== endpoint) {\n      res.writeHead(404, { 'Content-Type': 'application/json' });\n      res.end(JSON.stringify({ error: 'Not found' }));\n      return;\n    }\n\n    // DELETE: terminate session\n    if (req.method === 'DELETE') {\n      const reqSessionId = req.headers['mcp-session-id'] as string | undefined;\n      if (sessionId && reqSessionId === sessionId) {\n        sessionId = undefined;\n        negotiatedVersion = undefined;\n        res.writeHead(200);\n        res.end();\n      } else {\n        res.writeHead(404);\n        res.end();\n      }\n      return;\n    }\n\n    // GET: SSE stream (not implemented — return 405)\n    if (req.method === 'GET') {\n      res.writeHead(405, { 'Content-Type': 'application/json' });\n      res.end(JSON.stringify({ jsonrpc: '2.0', id: null, error: { code: -32601, message: 'SSE stream not supported' } }));\n      return;\n    }\n\n    if (req.method !== 'POST') {\n      res.writeHead(405);\n      res.end();\n      return;\n    }\n\n    // Validate session ID on non-initialize requests\n    const reqSessionId = req.headers['mcp-session-id'] as string | undefined;\n    if (sessionId && reqSessionId && reqSessionId !== sessionId) {\n      res.writeHead(404, { 'Content-Type': 'application/json' });\n      res.end(JSON.stringify({ jsonrpc: '2.0', id: null, error: { code: -32600, message: 'Invalid session' } }));\n      return;\n    }\n\n    // Validate MCP-Protocol-Version header on post-init requests\n    const reqProtocolVersion = req.headers['mcp-protocol-version'] as string | undefined;\n    if (negotiatedVersion && reqProtocolVersion && reqProtocolVersion !== negotiatedVersion) {\n      res.writeHead(400, { 'Content-Type': 'application/json' });\n      res.end(JSON.stringify({ jsonrpc: '2.0', id: null, error: { code: -32600, message: 'Protocol version mismatch' } }));\n      return;\n    }\n\n    // Read request body\n    const body = await readStreamAsText(req as AsyncIterable<Uint8Array>);\n\n    let rpcRequest: JsonRpcRequest;\n    try {\n      rpcRequest = JSON.parse(body);\n    } catch {\n      res.writeHead(400, { 'Content-Type': 'application/json' });\n      res.end(JSON.stringify({ jsonrpc: '2.0', id: null, error: { code: -32700, message: 'Parse error' } }));\n      return;\n    }\n\n    const response = await handleRequest(rpcRequest);\n\n    // On initialize response: create session and set header\n    if (rpcRequest.method === 'initialize' && response?.result) {\n      sessionId = crypto.randomUUID();\n      negotiatedVersion = PROTOCOL_VERSION;\n      res.setHeader('MCP-Session-Id', sessionId);\n    }\n\n    if (response) {\n      const accept = req.headers.accept ?? '';\n      if (accept.includes('text/event-stream')) {\n        res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', Connection: 'keep-alive' });\n        res.write(`event: message\\ndata: ${JSON.stringify(response)}\\n\\n`);\n        res.end();\n      } else {\n        res.writeHead(200, { 'Content-Type': 'application/json' });\n        res.end(JSON.stringify(response));\n      }\n    } else {\n      // Notification or response from client — no body\n      res.writeHead(202);\n      res.end();\n    }\n  });\n\n  return new Promise<void>((resolve, reject) => {\n    server.listen(port, host, () => {\n      log(`MCP server listening on http://${host}:${port}${endpoint}`);\n    });\n    server.on('error', reject);\n    const unsubscribe = onSignal?.(() => {\n      server.close(() => resolve());\n    });\n    server.on('close', () => unsubscribe?.());\n  });\n}\n\nexport async function startMcpServer(\n  _program: AnyPadroneProgram,\n  existingCommand: AnyPadroneCommand,\n  evalCommand: AnyPadroneProgram['eval'],\n  prefs?: PadroneMcpPreferences,\n): Promise<void> {\n  const handleRequest = createMcpHandler(existingCommand, evalCommand, prefs);\n  const transport = prefs?.transport ?? 'http';\n\n  if (transport === 'stdio') {\n    return startStdioTransport(handleRequest);\n  }\n\n  const { getCommandRuntime } = await import('../core/commands.ts');\n  const runtime = getCommandRuntime(existingCommand);\n  return startHttpTransport(handleRequest, prefs ?? {}, (msg) => runtime.error(msg), runtime.onSignal);\n}\n"],"mappings":"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"}