One-Line Summary: A publishable Claude Code plugin that turns Claude Code into a code-review swarm — three specialized sub-agents coordinated by hooks, augmented with a custom MCP tool server, slash commands, and a background audit worker.

Prerequisites: Familiarity with Claude Code, Node.js + TypeScript, basic understanding of the agent loop and tool calling. Course companion: Agent Harnesses & Orchestration (Modules 1–7).


The Goal

By the end of this blueprint, you will have a Claude Code plugin called harness-codereview that:

  • Spawns three sub-agents when triggered — a style reviewer, a correctness reviewer, and a security reviewer — each with its own scoped tool set and termination criteria.
  • Coordinates them via hooksPreToolUse blocks dangerous tools, PostToolUse summarizes findings, Stop aggregates the three reviews into a single report.
  • Exposes a custom MCP server that wraps eslint, ruff, and semgrep as standardized tools the sub-agents can call.
  • Adds slash commands (/review, /review-strict, /review-explain) so a developer can request a review on demand mid-conversation.
  • Runs a background audit worker that re-checks recent commits whenever Claude Code starts a session in the project, flagging regressions before the user even asks.
  • Is packaged as a plugin — a single directory you can drop into any repository's .claude/plugins/ or publish to a marketplace.

The finished plugin is the realization of every concept in Modules 1–7 of the course in one working artifact: harness primitives (Module 2), supervisor topology (Module 3), MCP integration (Module 2), permission scoping (Module 2), background workers (Module 7), prompt-injection defense (Module 6).

Why Build This as a Plugin (Not a Standalone Agent)?

A standalone agent that "does code review" is a script. A plugin is a harness extension — it inherits the harness's permission model, hook lifecycle, MCP plumbing, and user identity, and it works in any project the harness already knows about. That distinction is the point of the course: you are not building a new agent; you are extending an existing harness with new capabilities.

Concretely, packaging as a plugin means:

PropertyStandalone agentClaude Code plugin
Where does the agent loop live?You write itInherited from Claude Code
How are tools secured?You implement permissionsInherited (hooks + settings)
How does it install?git clone && npm install && configurecp -r plugin/ .claude/plugins/
How does the user invoke it?New CLI / new endpointSlash command in the existing Claude Code session
How does it compose with other extensions?It does notAll plugins coexist in the same session
Cross-machine portabilityDIYThe plugin directory is the portable unit

This is the architectural payoff of the harness model — and the reason ruflo, OpenHands, and the wider ecosystem have converged on plugin-shaped extensibility.

Architecture

┌──────────────────────────────────────────────────────────────────┐
│                       Claude Code (the harness)                    │
│                                                                    │
│   User types: /review                                              │
│         │                                                          │
│         ▼                                                          │
│   ┌──────────────┐    spawns    ┌──────────────────────────────┐  │
│   │ Orchestrator │ ───────────▶ │  Sub-agents (3, in parallel) │  │
│   │  (main loop) │              │                              │  │
│   └──────────────┘              │  • style-reviewer            │  │
│         ▲                       │  • correctness-reviewer      │  │
│         │ aggregated report     │  • security-reviewer         │  │
│         │                       └──────────────┬───────────────┘  │
│         │                                      │                  │
│         │                       Each calls    ▼                  │
│         │                       ┌──────────────────────────────┐  │
│         │                       │  Hooks: PreToolUse,          │  │
│         │                       │         PostToolUse, Stop    │  │
│         │                       └──────────────┬───────────────┘  │
│         │                                      ▼                  │
│         │                       ┌──────────────────────────────┐  │
│         │                       │  MCP Tool Server             │  │
│         │                       │  (eslint, ruff, semgrep)     │  │
│         │                       └──────────────────────────────┘  │
│                                                                    │
│   Background: ┌────────────────────────────────────────────────┐  │
│               │  audit-worker (runs on SessionStart hook)      │  │
│               │  → checks last 5 commits, posts findings       │  │
│               └────────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────────────────────┘

The orchestrator is the user's normal Claude Code session — there is no separate process. The sub-agents are Claude Code sub-agent definitions; hooks are JSON declarations; the MCP server is a Node process Claude Code spawns over stdio; the background worker is a SessionStart hook that runs an npx command.

Everything is owned by Claude Code. We just plug into the seams.

Project Structure

What the finished plugin directory looks like:

harness-codereview/
├── .claude-plugin/
│   └── plugin.json              # Plugin metadata (name, version, hooks, agents)
├── agents/
│   ├── style-reviewer.md        # Sub-agent definition + system prompt
│   ├── correctness-reviewer.md
│   └── security-reviewer.md
├── commands/
│   ├── review.md                # /review slash command definition
│   ├── review-strict.md
│   └── review-explain.md
├── hooks/
│   ├── pre-tool-use.sh          # Block dangerous tools, redact secrets
│   ├── post-tool-use.sh         # Append findings to shared scratchpad
│   ├── stop.sh                  # Aggregate three reviews → final report
│   └── session-start.sh         # Trigger background audit worker
├── mcp-server/
│   ├── package.json
│   ├── src/
│   │   └── index.ts             # MCP server exposing eslint/ruff/semgrep
│   └── tsconfig.json
├── workers/
│   └── audit-worker.ts          # Re-checks last 5 commits on session start
├── settings.example.json        # Reference settings the plugin expects
└── README.md

Nothing in this tree is exotic — every file is either Markdown (sub-agents, commands), JSON (settings, plugin manifest), shell (hooks), or TypeScript (MCP server, worker). The plugin is fundamentally a configuration directory with two small executables.

What You Will Have Learned

By the time you reach Step 9, you will have:

  1. Designed three specialized sub-agents with disjoint tool sets — exercising course concept sub-agents-as-primitives and role-based-orchestration.
  2. Wired four lifecycle hooks that turn them into a coordinated review pipeline — hooks-and-lifecycle-events and supervisor-pattern-deep-dive.
  3. Authored a custom MCP server that exposes static-analysis tools to any MCP-compatible harness — mcp-as-the-universal-tool-bus.
  4. Defined custom slash commands that surface the workflow as first-class UI — slash-commands.
  5. Implemented a background worker that runs without the user asking — background-worker-pattern.
  6. Locked down permissions and added injection defensepermission-and-tool-scoping-primitives and prompt-injection-defense-in-harnesses.
  7. Packaged everything as a redistributable pluginplugin-and-marketplace-systems and choosing-your-harness-stack.

That is a complete tour of the harness-extension surface in nine steps. Let's start.


Next: Step 2 - Set Up Claude Code and the Plugin Skeleton →