kunobi_call
Call a specific variant of a Kunobi tool by specifying variant, tool name, and arguments. Discover available tool schemas using kunobi://tools.
Instructions
Stable tool entrypoint for Kunobi operations. Call a variant tool via (variant, tool, arguments), e.g. variant="dev", tool="k8s". Use kunobi://tools to discover full downstream tool schemas and metadata.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| variant | Yes | Kunobi variant name, e.g. "dev", "stable", "local". | |
| tool | Yes | Remote tool name without variant prefix, e.g. "k8s". | |
| arguments | No | Arguments object passed to the target variant tool. Match the selected tool inputSchema from kunobi://tools. |
Implementation Reference
- src/tools/call.ts:34-69 (handler)The main handler function for the 'kunobi_call' tool. Validates that the variant exists via manager.getStates(), then calls manager.callVariantTool(variant, tool, args) and returns the result. This is the core execution logic triggered when the tool is invoked.
async ({ variant, tool, arguments: args }) => { const states = manager.getStates(); if (!states.has(variant)) { return { content: [ { type: 'text' as const, text: `Unknown variant "${variant}". Available variants: ${[...states.keys()].join(', ')}`, }, ], isError: true, }; } const result = await manager.callVariantTool( variant, tool, (args ?? {}) as Record<string, unknown>, ); if (!result) { return { content: [ { type: 'text' as const, text: `Variant "${variant}" is no longer available. Use kunobi_status/kunobi_refresh first.`, }, ], isError: true, }; } return result; }, ); - src/tools/call.ts:10-33 (schema)Input schema and registration for 'kunobi_call' using server.registerTool. Defines three input parameters: variant (string), tool (string), and arguments (optional record). Also specifies annotations like readOnlyHint, destructiveHint, and openWorldHint.
'kunobi_call', { description: 'Stable tool entrypoint for Kunobi operations. Call a variant tool via (variant, tool, arguments), e.g. variant="dev", tool="k8s". Use kunobi://tools to discover full downstream tool schemas and metadata.', inputSchema: { variant: z .string() .describe('Kunobi variant name, e.g. "dev", "stable", "local".'), tool: z .string() .describe('Remote tool name without variant prefix, e.g. "k8s".'), arguments: z .record(z.string(), z.unknown()) .optional() .describe( 'Arguments object passed to the target variant tool. Match the selected tool inputSchema from kunobi://tools.', ), }, annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: true, }, }, - src/server.ts:156-156 (registration)Registration call: registerCallTool(server, manager) is invoked in the main server setup to register the 'kunobi_call' tool with the MCP server.
registerCallTool(server, manager); - src/manager.ts:185-200 (helper)The VariantManager.callVariantTool method that the handler delegates to. Looks up the tracked variant by name, lazily connects if needed via addVariant, then calls tracked.bundler.callTool(tool, args) to actually execute the remote tool call.
async callVariantTool( variant: string, tool: string, args: Record<string, unknown> = {}, ): Promise<CallToolResult | null> { let tracked = this.tracked.get(variant); if (!tracked) { const port = this.ports[variant]; if (port === undefined) return null; await this.addVariant(variant, port); tracked = this.tracked.get(variant); } if (!tracked) return null; return tracked.bundler.callTool(tool, args); } - src/catalog.ts:1-39 (registration)The buildDiscoveryCatalog function references 'kunobi_call' as the callTool identifier in the discovery catalog returned by the kunobi://tools resource, informing clients which tool to use for stable downstream calls.
import type { VariantManager } from './manager.js'; export function buildDiscoveryCatalog(manager: VariantManager): { callTool: 'kunobi_call'; callShape: { variant: string; tool: string; arguments: Record<string, unknown>; }; variants: Record<string, unknown>; } { const variants: Record<string, unknown> = {}; for (const [variant, entry] of manager.getCatalog()) { variants[variant] = { port: entry.port, status: entry.status, tools: entry.tools.map((tool) => ({ ...tool, dynamicToolName: `${variant}__${tool.name}`, })), resources: entry.resources, prompts: entry.prompts.map((prompt) => ({ ...prompt, dynamicPromptName: `${variant}__${prompt.name}`, })), }; } return { callTool: 'kunobi_call', callShape: { variant: 'dev', tool: 'k8s', arguments: { action: 'list', variant: 'events' }, }, variants, }; }