Part 3 Chapter 8 Last verified 2026-04-17 Fresh

Extending agents

Commands, skills, hooks, MCP — the four axes by which an agent becomes more than the defaults it ships with. This is the most divergent surface in the category; get the mental model right and the command names become secondary.

Volatility: feature-surface
Tools compared: claude-codegemini-clicodex-cli
On this page
  1. Representation
  2. When to use which axis
  3. Why this chapter is volatile
  4. Operation
  5. Extension-surface comparison
  6. Commands and skills: the invoked layer
  7. Hooks: the always-fires layer
  8. MCP: the external-system layer
  9. Evolution
  10. Quick reference

Out of the box, every CLI-agent is just a general-purpose shell for a model. That’s where it stops being useful. The agent that ships with defaults is the agent that loses to the agent with your repo’s conventions wired in, your team’s verification gates running automatically, your private knowledge base reachable as a tool. This chapter is about the four axes on which agents become extended — and why extensibility is also the surface where tools diverge most sharply.

Representation

Extension is how a CLI-agent stops being a general-purpose coder and becomes your agent. Every tool this book covers supports extension, but they divide the work differently. The right mental model is not “which tool has the most features” — it’s “which extension axis does my need actually live on?”

When to use which axis

The decision tree is short:

Use a command / skill when a workflow is repeatable and the user should decide when to invoke it. Deploy checks, code review templates, chapter-porting workflows. Cost: minutes to write a markdown file. Guarantee: the agent runs the workflow when asked.

Use a hook when a standard is non-negotiable and the user should not have to remember it. Tests before commit, lint on write, secrets-scan on edit. Cost: a shell script and some config. Guarantee: fires on the matching event regardless of what the agent or user wants.

Use a permission / guardrail when a prohibition is load-bearing. The agent must never read .env; commits to main require approval; writes outside src/ are forbidden. Cost: one config entry. Guarantee: the agent cannot violate the rule without operator override.

Use an MCP server when an external system needs to become part of the agent’s working surface. Your company’s ticket tracker, internal knowledge base, custom deployment platform. Cost: stand up a server implementing the protocol. Guarantee: the external system’s tools appear alongside the built-in ones and are usable via the same prompt shape.

Why this chapter is volatile

The four-axis model is stable. The specific names, file formats, and configuration surfaces are not. Expect churn quarterly — this is feature-surface in a book otherwise dominated by architectural-pattern and stable-principle. Verify commands and file paths against current docs before relying on them.

Operation

Extension-surface comparison

The tri-tool map of what’s supported where:

AxisClaude CodeGemini CLICodex CLI
User commands.claude/skills/<name>/SKILL.md (or a single .md) → /name.gemini/commands/<name>.toml/nameslash commands via config / plugins
Reusable skillsmerged with commands — a skill-with-a-directory is the richer form of a commandvia extensionsvia MCP server + registered tools
Hooks9+ events: UserPromptSubmit, PreToolUse, PostToolUse, Notification, Stop, SubagentStop, PreCompact, SessionStart, SessionEndlighter; pre/post tool callbackscommand-approval config in ~/.codex/config.toml
Permissionssettings.json with allow-list / deny-rules; enforced by harnesstool-level allow-listsapproval modes (--suggest / -a on-request / --full-auto)
MCP supportfirst-class; shipped with Claude Code from earlyfirst-class (2025+); 200+ extension ecosystemfirst-class; codex mcp CLI + ~/.codex/config.toml
MCP transportsstdio + HTTP/SSEstdio + HTTPstdio + streamable HTTP

Two observations before the details:

  1. MCP is convergent. All three tools support the protocol with interoperable server implementations. An MCP server written for one client works for all three, modulo tiny transport-config differences. This is the single biggest extensibility story of 2025–2026.

  2. Everything non-MCP diverges. Skills, command authoring, hooks — each tool’s surface is incompatible with the others. Practices that lean on specific command-file formats or hook-event names do not port; practices that lean on “what the extension does” do.

Commands and skills: the invoked layer

A command is the simplest extension. You write a markdown file describing a workflow; the agent reads it when invoked. Claude Code recently merged its commands/ and skills/ directories — both now produce the same /slash-command interface. A “skill” is just the richer form: a directory with a SKILL.md entry point plus supporting reference files.

# Claude Code — simple command form
.claude/skills/review.md
  ---
  name: review
  description: Run the team's PR review checklist
  ---
  1. Run `git diff main...HEAD`
  2. For each changed file, check:
     - Does it match the precision-vocabulary in the briefing doc?
     - Are error paths handled explicitly?
     - ...

# Claude Code — richer skill form
.claude/skills/deploy/
  SKILL.md             # required entry point, frontmatter + instructions
  checklist.md         # supporting reference
  examples/            # sample outputs

Gemini CLI uses TOML-based custom commands in .gemini/commands/; Codex CLI ships a built-in slash-command set and leans on MCP servers to add custom verbs. The mental model is the same everywhere: a named, invocable workflow.

Hooks: the always-fires layer

A hook is a script that runs automatically at a specific lifecycle point, regardless of what the user or agent is doing. Hooks are how you make a standard non-negotiable: “always run tests before commit” is an advisory line in the briefing doc that the agent may forget in a long session; as a PreToolUse hook matching Bash commands that contain git commit, it fires every time.

Claude Code has the richest hook surface — nine lifecycle events covering prompt submission, tool invocation (before/after), compaction, session start/end, sub-agent lifecycle, and generic notifications. Each hook can match specific tool names or patterns and run arbitrary shell commands. Gemini CLI has a lighter set focused on pre/post tool invocation. Codex CLI’s model is command-approval configuration — the agent’s operations are gated by approval policy rather than by event hooks.

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": ".claude/hooks/pre-commit-gate.sh",
        "description": "Block git commit if tests fail"
      }]
    }]
  }
}

MCP: the external-system layer

Model Context Protocol is the shared wire format for agent ↔ external-system communication. An MCP server exposes tools (functions the agent can call), resources (read-only content the agent can retrieve), and prompts (pre-structured templates the agent can invoke). Once connected, the server’s capabilities appear in the agent’s surface alongside the built-ins — a Jira MCP server adds create_ticket and search_tickets tools; a Postgres MCP server adds query and describe_schema; a company-knowledge MCP server adds search_docs.

All three CLIs now support MCP as first-class. Configuration mechanisms differ:

  • Claude Code: .claude/settings.json or global config, with stdio + HTTP/SSE transport.
  • Gemini CLI: mcpServers entry in Gemini config; 200+-extension ecosystem at geminicli.com/extensions; includes official remote MCP servers for Google Workspace, Google Cloud services, etc.
  • Codex CLI: ~/.codex/config.toml + the codex mcp CLI for add/list/remove operations; supports stdio and streamable HTTP transports.
# ~/.codex/config.toml — adding an MCP server
[mcp_servers.jira]
command = "jira-mcp-server"
args = ["--workspace", "acme"]
env = { JIRA_API_KEY = "..." }

Evolution

Extension is simultaneously the most convergent part of the category (on MCP as protocol) and the most divergent (on everything else). Both stories are still in motion.

Convergence: slash commands as the invocation surface. All three tools converged on /command-name as the user-invocable extension syntax. The file format for defining a command differs (Claude’s skill-merged markdown, Gemini’s TOML, Codex’s plugin system), but the user experience — type a slash, pick from autocomplete, invoke — is identical across tools.

Convergence: custom commands merging with richer skills/extensions. Claude Code’s 2026 merge of .claude/commands/ into .claude/skills/ formalized a pattern that was already implicit: a “command” is just the simple form of a “reusable skill with optional supporting files.” Gemini’s extensions and Codex’s MCP-as-command-source follow the same logic at different layers of abstraction.

Emerging: cross-tool skill registries. A few community projects in 2026 are experimenting with CLI-agnostic skill formats that translate into each tool’s native format on install. None are mature; all face the fundamental divergence of hook/permission semantics that no translation layer can paper over. The write-once-everywhere story will arrive for commands (already close) before hooks (genuinely hard).

Quick reference

  • Four extension axes: commands/skills (invoked), hooks (always-fires), permissions (guardrails), MCP (external systems). Match the axis to the guarantee you need.
  • Commands/skills are cheap and on-demand; hooks are medium-cost and always-fire; permissions are harness-enforced; MCP is the gateway to external systems.
  • MCP is the one cross-tool extension axis: write the server once, use it from any compliant CLI. Commands and hooks do not port.
  • Claude Code merged commands + skills into one system; a command is just the simple form of a skill.
  • Claude Code has the richest hook surface (nine events); Gemini has lighter hooks; Codex uses command-approval as its enforcement paradigm.
  • Quarterly extension audit: delete what hasn’t been invoked in a month. Hooks especially — they fail silently.
  • Before writing a tool-specific extension, ask: could this be an MCP server instead? If the answer is yes and it would ever be shared, write the MCP server.
  • This is the most volatile chapter in the book. Verify command names, file formats, and event lists against current docs before relying on them for anything load-bearing.