import { callMcpTool, DEFAULT_MCP_SERVER, GRANOLA_MCP_TOOLS, MCP_SERVER_PATTERN } from '../lib/mcp.ts' import { parseInput } from '../lib/validate.ts' /** * Call one tool on Granola's official MCP server through Kody (optional lane; connect it first * with ./mcp/connect). Only Granola's documented, read-only tools are allowed: * `query_granola_meetings` (ask a question across meetings — not in the REST API), `list_meetings`, * `get_meetings`, `list_meeting_folders` (paid), `get_meeting_transcript` (paid), `get_account_info`. * `args` is passed through unchanged; the tool schemas are defined by Granola (see ./mcp/tools and * Kody's `search({ entity: "mcp-server:granola" })`). Rate limit ≈100 requests/minute. * * @param input.tool - One of the documented tool names. Required. * @param input.args - Tool arguments object (default `{}`). * @param input.server - Kody MCP server name (default `granola`). * @returns `{ server, tool, result }` — the MCP tool result as returned by Kody. * * @example * import mcpCall from 'kody:@charlesmatte/granola/mcp/call' * * const who = await mcpCall({ tool: 'get_account_info' }) */ export default async function callGranolaMcp(input: unknown) { const p = parseInput<{ tool: string; args?: Record; server?: string }>( input, { tool: { type: 'enum', values: GRANOLA_MCP_TOOLS, required: true }, args: { type: 'object' }, server: { type: 'string', pattern: MCP_SERVER_PATTERN } }, 'mcp/call', ) const server = p.server ?? DEFAULT_MCP_SERVER return { server, tool: p.tool, result: await callMcpTool(server, p.tool, p.args ?? {}) } }