Claude Code Custom Agent Authoring: Build Reusable Subagents That Enforce Your Standards (2026)

A complete guide to authoring custom Claude Code subagents — frontmatter fields, system prompt design, tool allowlists, and two production-ready examples (migration reviewer, security gate) with the mistakes to avoid.

  • Claude Code
  • Agent SDK
  • CLI
  • Markdown
  • YAML
  • Proprietary
  • Updated 2026-05-29

Introduction #

In Claude Code Subagent Patterns we covered five workflows for spending your context window wisely — and the fifth, pipeline orchestration with custom agents, is the one teams ask about most. “Codify your review checklist as a subagent” sounds great until you open an empty .claude/agents/migration-reviewer.md and a blinking cursor.

This guide is the missing manual. We’ll walk through the anatomy of a custom agent definition, what each frontmatter field actually controls, how to write a system prompt that produces a structured report instead of a chatty ramble, why tool allowlists matter more than they look, and two complete, production-ready examples you can copy today. Then the mistakes — because the failure modes here are subtle and they cost you trust in the agent the first time it misses something obvious.

If you’ve never delegated to a subagent before, read the patterns piece first. If you have, and you’re ready to ship your own, this is the playbook.

Anatomy of a Custom Agent #

A custom agent is a single Markdown file with YAML frontmatter. It lives in one of two places:

  • .claude/agents/<name>.md — project-scoped, version-controlled, shared with your whole team
  • ~/.claude/agents/<name>.md — user-scoped, available across every project on your machine

The structure is dead simple:

---
name: migration-reviewer
description: Reviews database migrations for safety. Use when a PR touches db/migrate/, schema files, or any SQL DDL.
tools: Read, Grep, Glob
model: sonnet
---

You are a database migration reviewer. Your job is to catch unsafe
migrations before they reach production...

Everything above the closing --- is configuration. Everything below it is the system prompt — the persona and instruction set the subagent runs under. That’s the entire contract. No build step, no registration, no plugin manifest. Drop the file in, run /agents to confirm Claude Code picked it up, and it’s invokable.

The Frontmatter Fields #

Four fields do all the work. Three of them are optional, but the defaults are rarely what you want for a serious agent.

name (required) #

The agent’s identity — this is the string the parent passes as subagent_type. Keep it kebab-case and descriptive: security-auditor, not agent2. The filename is cosmetic; the name field is canonical.

description (required — and the one people underweight) #

This is the routing signal. When the parent agent is deciding whether to delegate, it reads descriptions, not system prompts. So a description must encode when to reach for this agent, with concrete triggers:

description: A code reviewer.description: Reviews code changes for correctness and security. Use proactively after writing a non-trivial diff, before committing, especially for auth, payments, or concurrency-sensitive code.

The word “proactively” is load-bearing — it nudges the parent to invoke without being explicitly asked. If your agent never seems to fire, the description is almost always why.

tools (optional — but declare it anyway) #

A comma-separated allowlist. Omit it and the agent inherits every tool the parent has. We’ll spend a whole section on why that’s usually wrong.

model (optional) #

Pin a tier: haiku for cheap mechanical passes, sonnet for balanced review work, opus for deep reasoning. A high-volume linter-style agent on haiku keeps costs sane; a security auditor where a miss is expensive earns opus.

Writing the System Prompt #

The body is where most agents are won or lost. Three rules produce reliable workers:

1. State the role and the boundary in the first sentence. “You are a migration reviewer. You do not write code or apply fixes — you report findings.” Telling the agent what not to do is as important as the job itself.

2. Specify the output contract. Vague prompts produce prose; you want structure. Spell it out:

Report your findings as a list. For each issue:
- SEVERITY: blocker | warning | nit
- LOCATION: file:line
- PROBLEM: one sentence
- FIX: the concrete change
End with a one-line VERDICT: SAFE TO MERGE or NEEDS CHANGES.

3. Give it a checklist, not a vibe. “Review for safety” is a wish. Enumerate exactly what to check — the agent will work through your list deterministically, which is the entire value of codifying it.

Tool Allowlists: Least Privilege for Agents #

Here’s the trap. Leave tools out, and your “reviewer” inherits Write, Edit, and Bash. The first time it finds an issue, it may “helpfully” fix it — mutating your working tree, running commands, and destroying the independence that made the review worth requesting.

The fix is least privilege. Match tools to the job:

Agent kindTools
Reviewer / auditorRead, Grep, Glob
Researcher / explorerRead, Grep, Glob, WebSearch, WebFetch
Test runnerRead, Grep, Glob, Bash
Fixer (rare, deliberate)Read, Edit, Bash

A read-only reviewer literally cannot go rogue. That predictability is what lets you trust its report without re-checking everything it touched. (If you later wire in external systems through MCP servers, the same discipline applies — only grant the MCP tools the agent genuinely needs.)

Worked Example: A Migration Reviewer #

---
name: migration-reviewer
description: Reviews database migrations for production safety. Use proactively when a change touches db/migrate/, schema.rb, or any SQL DDL file.
tools: Read, Grep, Glob
model: sonnet
---

You are a database migration reviewer. You do NOT edit files or run
migrations — you read the proposed migration and report risks.

Check every migration against this list:
1. Adding a column with a NOT NULL constraint and no default on a large table (locks).
2. Adding an index without CONCURRENTLY (blocks writes).
3. Renaming or dropping a column still referenced by application code.
4. A data backfill running inside the same transaction as the schema change.
5. Missing a corresponding rollback / down path.

Report findings as:
- SEVERITY: blocker | warning | nit
- LOCATION: file:line
- PROBLEM / FIX
End with VERDICT: SAFE TO MERGE or NEEDS CHANGES.

Invoke it from the parent with a natural request — “review the migration on this branch” — and because the description names db/migrate/, the parent routes there on its own.

Worked Example: A Security Gate #

---
name: security-gate
description: Threat-models diffs that touch authentication, authorization, secrets, or user input. Use proactively before merging any auth or payments change.
tools: Read, Grep, Glob
model: opus
---

You are a security reviewer with a threat-modeling mindset. Assume the
input is hostile. You report only — you never modify code.

For the diff, check:
- Authn/authz: can this path be reached without the expected check?
- Injection: is user input concatenated into SQL, shell, or HTML?
- Secrets: any key, token, or password added to code or logs?
- IDOR: are object references scoped to the authenticated user?

For each finding give an EXPLOIT SKETCH (how an attacker triggers it),
then the FIX. Default to flagging when uncertain — false positives are
cheap, a missed auth hole is not.

Note the opus model and the “default to flagging when uncertain” instruction — for a security gate you tune toward paranoia.

Testing and Iterating on Agents #

Don’t ship an agent you haven’t tried to fool. Spin up a git worktree or a throwaway branch with a planted problem — a migration missing CONCURRENTLY, an endpoint missing an ownership check — and invoke the agent.

You’re testing two independent things:

  • Did it get triggered by a natural request? If not, fix the description.
  • Did it catch the planted bug? If not, fix the system prompt’s checklist.

These fail for different reasons, so iterate on them separately. A common surprise: the agent works perfectly when you name it explicitly but never fires on its own — that’s always a description problem, never a body problem.

Common Authoring Mistakes #

  • Vague description. The agent does great work nobody ever triggers. Add concrete file paths and the word “proactively.”
  • No tool allowlist. Your reviewer edits the code it was supposed to review. Declare Read, Grep, Glob.
  • Prose output, no contract. You get three paragraphs of opinion instead of a triaged list. Specify the exact report format.
  • One mega-agent. A single “do-everything” agent is just the parent with extra steps. Split by concern — that’s the specialist delegation pattern working for you.
  • Set-and-forget. Agents are code. An unmaintained checklist rots as your stack changes. Review them quarterly.

The Principle #

A custom agent is executable institutional knowledge. The review standard that used to live in a wiki page nobody opened, or in the head of the one senior engineer who always caught the bug — you encode it once, version-control it, and every teammate plus every CI run gets the identical, tireless reviewer. The agent doesn’t get rushed before a deadline and skip steps 3, 5, and 7. That consistency, not raw intelligence, is the win.

Setting Up Production-Ready Claude Code #

To run custom-agent pipelines at scale you want stable infrastructure:

  1. A reliable host for long-running and CI sessions. Custom agents shine in CI, where they gate every PR. You need a box that won’t drop the job. HTStack — Hong Kong VPS with low-latency access from mainland China and stable BGP routing. It’s the same IDC that hosts dibi8.com, so we run our own agent pipelines on it. Value tier runs $5-12/month.

  2. Cloud headroom for parallel gates. When an orchestrator fans out to migration-reviewer + security-gate + perf-checker at once, you want spare CPU. DigitalOcean — $200 free credit for 60 days across 14+ regions, great for hosting CI runners next to your app.

  3. A skills bundle. The steepest part of the curve is writing agent definitions that don’t fall over. We packaged five battle-tested skills as a $19 bundle on Gumroad — see the floating CTA in the corner — including the orchestrator prompts and three more ready-to-ship agent definitions.

Verdict #

Custom agents turn your team’s best practices from documentation nobody reads into checks that run on every change. The recipe: a sharp description so it triggers, a least-privilege tool allowlist so it stays in its lane, and a system prompt with an explicit checklist and output contract so it produces a report you can act on.

Start with one — the migration reviewer above is the highest-leverage first agent for most teams. Plant a bug, confirm it catches it, then commit the file. From that moment, every teammate has a reviewer that never gets tired and never skips a step.

📦 Featured in collections

💬 Discussion