Skip to content
AI & Agents
Skill

/developing-genkit-tooling

Best practices for authoring Genkit tooling, including CLI commands and MCP server tools. Covers naming conventions, architectural patterns, and consistency guidelines.

BOOST
From plugin
genkit
6.5k2 skills
Install
$ npx -y skills add genkit-ai/genkit --skill developing-genkit-tooling --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/developing-genkit-tooling

Context preview

The summary Claude sees to decide when to auto-load this skill.

Best practices for authoring Genkit tooling, including CLI commands and MCP server tools. Covers naming conventions, architectural patterns, and consistency guidelines.

SKILL.md

developing-genkit-tooling.SKILL.md
name: developing-genkit-tooling
description: Best practices for authoring Genkit tooling, including CLI commands and MCP server tools. Covers naming conventions, architectural patterns, and consistency guidelines.

Developing Genkit Tooling

Naming Conventions

Consistency in naming helps users and agents navigate the tooling.

CLI Commands

Use **kebab-case** with colon separators for subcommands.

  • **Format**: `noun:verb` or `category:action`
  • **Examples**: `flow:run`, `eval:run`, `init`
  • **Arguments**: Use camelCase in code (`flowName`) but standard format in help text (`<flowName>`).

MCP Tools

Use **snake_case** for tool names to align with MCP standards.

  • **Format**: `verb_noun`
  • **Examples**: `list_flows`, `run_flow`, `list_genkit_docs`, `read_genkit_docs`

CLI Command Architecture

Commands are implemented in `cli/src/commands/` using `commander`.

Runtime Interaction

Most commands require interacting with the user's project runtime. Use the `runWithManager` utility to handle the lifecycle of the runtime process.

import { runWithManager } from '../utils/manager-utils';

// ... command definition ...
.action(async (arg, options) => {
  await runWithManager(await findProjectRoot(), async (manager) => {
    // Interact with manager here
    const result = await manager.runAction({ key: arg });
  });
});

Output Formatting

  • **Logging**: Use `logger` from `@genkit-ai/tools-common/utils`.
  • **Machine Readable**: Provide options for JSON output or file writing when the command produces data.
  • **Streaming**: If the operation supports streaming (like `flow:run`), provide a `--stream` flag and pipe output to stdout.

MCP Tool Architecture

MCP tools in `cli/src/mcp/` follow two distinct patterns: **Static** and **Runtime**.

Static Tools (e.g., Docs)

These tools do not require a running Genkit project context.

  • **Registration**: `defineDocsTool(server: McpServer)`
  • **Dependencies**: Only the `server` instance.
  • **Use Case**: Documentation, usage guides, global configuration.

Runtime Tools (e.g., Flows, Runtime Control)

These tools interact with a specific Genkit project's runtime.

  • **Registration**: `defineRuntimeTools(server: McpServer, options: McpToolOptions)`
  • **Dependencies**: Requires `options` containing `manager` (process manager) and `projectRoot`.
  • **Schema**: MUST use `getCommonSchema(options.explicitProjectRoot, ...)` to ensure the tool can accept a `projectRoot` argument when required (e.g., in multi-project environments).
// Runtime tool definition pattern
server.registerTool(
  'my_runtime_tool',
  {
    inputSchema: getCommonSchema(options.explicitProjectRoot, {
      myArg: z.string(),
    }),
  },
  async (opts) => {
    // Resolve project root before action
    const rootOrError = resolveProjectRoot(
      options.explicitProjectRoot,
      opts,
      options.projectRoot
    );
    if (typeof rootOrError !== 'string') return rootOrError;

    // access manager via options.manager
  }
);

Error Handling

MCP tools should generally catch errors and return them as content blocks with `isError: true` rather than throwing exceptions, which ensures the client receives a structured error response.

try {
  // operation
} catch (err) {
  const message = err instanceof Error ? err.message : String(err);
  return {
    isError: true,
    content: [{ type: 'text', text: `Error: ${message}` }],
  };
}
Read more
Ships withgenkit

Open-source framework for building agentic apps in JavaScript, Go, Dart, and Python, built and used in production by Google

Get the whole plugin
Stats
6,468
Stars
857
Forks
Active
Maintenance
TypeScript
Language
Apache-2.0
License
9h ago
Last commit
2y ago
Created
3h ago
Added

Repo: firebase/genkit

Other skills on genkit.