# mse — Agent (agent.md) authoring guide
An **agent.md** file is the durable system prompt for a Claude Code SubAgent
(built-in or custom). It is what gets fetched and pushed into the SubAgent's
context window every time the agent is invoked. Because that context window is
finite and shared with the runtime task payload (fetched Task IF, `Read`
results, `tool_result` bodies, MCP resource fetches, `PreOut` file contents),
**an oversized agent.md leaves no room to actually do the work**.
This guide states the canonical shape, size targets, and anti-patterns for
SubAgent prompts used from mse — the Operator wrapper agents, the mse-worker
family, and any custom SubAgent that participates in a Blueprint dispatch. It
follows the Claude Code SubAgent conventions; see the References section for
primary sources.
## Canonical shape (4 sections)
The Anthropic official examples (`code-reviewer`, `debugger`, `data-scientist`,
`db-reader`) all converge on the same 4-layer structure. Reproduce it:
1. **Role — 1 sentence.** What this agent is and what it excels at. No
preamble, no background, no history. If it takes more than one sentence, the
agent is doing too much and should be split.
2. **`When invoked:` — numbered workflow.** The exact steps this agent runs,
in order. Prefer 3–8 steps. Each step is imperative ("Read X", "Post to
/v1/…", "Return Y"). No decision trees, no exceptional paths described in
prose — put those into the step body as sub-bullets if truly needed.
3. **Tool guidance / key practices — checklist.** Which tools to reach for at
which step, plus non-obvious constraints (auth headers, ordering rules,
idempotency). Keep it to items that *change what the agent does*; do not
describe every tool from scratch (the tool schemas are already loaded).
4. **Output format — explicit.** What the caller expects back: the exact
`return` literal shape, the JSON schema, or the human-readable format. If
the caller parses the output, put a fenced example. If the agent hands off
to another SubAgent, state the handoff artifact path.
**Input is not a section.** The delegation prompt (Task message) carries the
input. Do not enumerate example inputs in the durable prompt — that content is
per-invocation and belongs in the caller's `Task` dispatch, not in agent.md.
## Size targets
There is **no official byte limit** in the Claude Code SubAgent docs, but
neighboring numbers make the working range obvious:
- Official example agents: **20–40 lines** each (measured across the 4
reference agents in `code.claude.com/docs/en/sub-agents §Example subagents`).
- `MEMORY.md` injection threshold: **first 200 lines or 25 KB, whichever is
first**; beyond that the runtime injects a curation instruction instead of
the content ([sub-agents §Enable persistent memory][mem]).
- Windows delegation hard cap: **8191 characters** in the delegation prompt
string; longer prompts fail to dispatch ([agent-sdk/subagents §Long prompt
failures on Windows][winlim]).
Target: **≤ 200 lines / ≤ 25 KB** for any agent.md. Treat 500+ lines / 50 KB+
as a defect — at that size the fetched system_prompt alone will consume a
significant fraction of a 200 K context window, leaving no headroom for the
task payload, and the SubAgent will fail with *Prompt is too long* the first
time it hits a real tool_result of any size.
These thresholds are observed by the `bp_doctor` MCP tool, which fetches a
Blueprint from `GET /v1/blueprints/:id/head`, measures every agent's
`profile.system_prompt` bytes/lines, and returns per-agent severity
(`OK` / `WARN` / `BLOCK`) plus an aggregate verdict. The default check is:
- **WARN** if `system_prompt` bytes ≥ 25 KB **or** lines ≥ 200.
- **BLOCK** if `system_prompt` bytes ≥ 50 KB **or** lines ≥ 500.
The verdict is a report label only — `bp_doctor` never prevents any
dispatch. **BLOCK is disabled by default**: modern Claude models (Opus-tier
and long-window Fable variants) tolerate large system prompts, so an
over-block-threshold agent falls back to WARN. Callers running against a
strict 200 K-window model can pass `disable_block=false` to opt into the
BLOCK band. Any of the four thresholds (`warn_bytes` / `warn_lines` /
`block_bytes` / `block_lines`) can also be overridden per call to fit the
model actually in play.
Agents whose backend does not carry an `agent.md` body (`RustFn` and other
spec-only agents where `profile` is `None`) are reported with size 0 and
severity `OK`.
## What to remove (anti-patterns)
Everything in this list is already available to the SubAgent from another
channel; re-stating it in agent.md is dead weight that costs tokens on every
invocation.
- **Content of `CLAUDE.md` / `~/.claude/CLAUDE.md` / project rules / managed
policy files.** The full memory hierarchy is auto-loaded into every SubAgent
except the built-in `Explore` / `Plan` ([sub-agents §What loads at
startup][load]). Re-quoting a rule your agent is expected to follow just
duplicates it.
- **Accident logs, retrospectives, "why this exists" narratives.** SubAgents
do not inherit the parent's conversation history or tool results ([agent-sdk
§What subagents inherit][inh]). A long historical explanation gives the
SubAgent no leverage it can use at runtime; it only bloats the fetch.
- **Full copies of upstream doc pages.** Link to `mse://guides/<slug>` or the
canonical URL and let the agent fetch on demand if truly needed.
- **Input examples / fixture blobs.** These belong in the delegation prompt
(Task message), which is per-invocation and correctly sized to the specific
work.
- **Exhaustive tool schemas.** Tool schemas are loaded automatically; the
agent only needs *which tool to reach for and why*, not the JSON Schema.
- **Persona / register decoration for agents that are pure workers.** Voice
and register belong to persona-facing agents; worker SubAgents that just
return structured output do not benefit from them.
## Fetch-vs-embed policy (mse SubAgent specifics)
When an mse SubAgent needs data at runtime, use the right channel for each
kind of payload:
| **System prompt (agent role definition)** | `fetch` (mse-worker `fetch` MCP tool) | Literal, hard guarantee. FilePath-only delivery fails on cwd drift / relative-path ambiguity ~ 100% of the time in some environments; embed as literal to eliminate that class. |
| **Lightweight context (FilePath, short config, env-derived values)** | Embed in system prompt OR pass via Task IF from MainAI | Small enough to co-locate; passing through Task IF keeps agent.md invocation-agnostic. |
| **PreOut (upstream phase artifacts, large fixtures)** | Pass the path in Task IF; SubAgent runs `Read` itself | Keeps agent.md size bounded and lets the SubAgent decide what to load. |
| **Anything else** | Assume it will fail. | These three channels cover the reliable delivery paths for mse SubAgents. |
The size discipline in the previous section exists to preserve headroom for
the "PreOut via `Read`" case: if agent.md consumes 77 K of the 200 K window
just for the system prompt, `Read` results have nowhere to go and the agent
crashes on the first non-trivial file.
## Quick self-check before you commit an agent.md
1. Is the file **≤ 200 lines / ≤ 25 KB**?
2. Does it have exactly the **4 canonical sections** (Role / When invoked /
Tool guidance / Output format)?
3. Does it **avoid re-stating** anything already in `CLAUDE.md`, user-global
rules, or tool schemas?
4. If the agent takes runtime input, does the prompt describe **the shape**
(not example values)?
5. Does it declare its **Output format** concretely enough that the caller
can parse or verify the return?
Five yeses → ship it. Any no → shrink and re-check.
## References
- [Create custom subagents — Claude Code Docs][sub-agents]
- [Subagents in the SDK — Claude Agent SDK Docs][sdk-subagents]
- [Effective context engineering for AI agents — Anthropic Engineering][context]
- [Writing effective tools for AI agents — Anthropic Engineering][tools]
[sub-agents]: https://code.claude.com/docs/en/sub-agents
[sdk-subagents]: https://code.claude.com/docs/en/agent-sdk/subagents
[mem]: https://code.claude.com/docs/en/sub-agents#enable-persistent-memory
[winlim]: https://code.claude.com/docs/en/agent-sdk/subagents
[load]: https://code.claude.com/docs/en/sub-agents
[inh]: https://code.claude.com/docs/en/agent-sdk/subagents
[context]: https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents
[tools]: https://www.anthropic.com/engineering/writing-tools-for-agents