← Public packages
@charlesmatte/granola
Search and read Granola meeting notes, summaries and transcripts from any agent; manage webhooks and legal holds safely.
src/mcp/call.ts
30 lines · 1.6 KB · TypeScriptimport { 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<string, unknown>; 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 ?? {}) }
}