What this system is, and its 5 parts
Think of this as the agent that helps a developer rename a function across a 1,000-file codebase without losing their afternoon to it. Instead of one big agent reading every file (which fails because there's too much to remember), the work is split: one tiny helper finds the matching files with grep, another reads only those files, a third reviews the proposed changes from a fresh perspective so it doesn't just rubber-stamp its own work, and a human approves the final commit. The whole point is that productivity tasks are easier when you delegate to specialists rather than asking one agent to do everything alone.
Built-in Tool Suite
Read · Write · Edit · Bash · Grep · GlobThe six built-in tools cover almost every productivity task. Use Grep + Glob to locate before Read; use Edit (not Write) for in-place changes to existing files; reserve Bash for actual commands (compile, test, run). Never as a fallback for file I/O. The grep-then-read sequence is the single biggest token-efficiency lever.
ConfigurationTool whitelist per subagent: Reader=[Read,Grep,Glob]; Reviewer=[Read,Grep,Bash(test,lint)]; Doc-gen=[Read,Write,Glob]. Never grant 15 tools to one agent. Accuracy drops 8% per tool past 5.Concept: tool-calling →
Codebase Context Loader
imports · dependencies · architectureWalks the repo at session start: parses package.json / pyproject.toml, reads README.md + .claude/CLAUDE.md, builds a dependency graph (top 50 imports), surfaces the architecture-decisions doc. Loaded once into the lead agent's context so it doesn't re-discover on every turn.
ConfigurationRun on first invocation: project_type, key_dirs, top_imports[], architecture_summary. Persist as .claude/context-cache.json with hash-based invalidation. Refresh on package.json change.Concept: claude-md-hierarchy →
Code-Review Subagent
independent · fresh contextSpawned per change-set with [Read, Grep, Bash(test,lint)] only. No Edit, no Write. Fresh context, no inherited history from the writing agent. Reviews against .claude/rules/ and the codebase context. Returns { verdict, issues: [{ line, severity, message }], summary }. Independence is the architectural point. Same-session review just rubber-stamps.
Configurationsystem: 'You are a code reviewer. Read only. Check against .claude/rules/ and existing patterns.' tools: [Read, Grep, Bash(npm test, npm run lint)]. Receives diff + context summary; returns structured verdict.Concept: evaluation →
Doc-Generator Subagent
writes from code, not from specSpecialised subagent that reads source files and generates documentation that reflects what the code actually does, not what last quarter's spec said it would do. Writes JSDoc / docstrings inline (Edit), README sections (Write), or external API docs (Write to docs/). Tools scoped to read source + write docs only.
Configurationsystem: 'Generate docs from source. Use the code as ground truth.' tools: [Read, Write(docs/, *.md), Glob]. Run after code-review-subagent passes; auto-attached as part of the PR.Concept: subagents →
MCP Server Integrations
language servers · linters · formattersOptional but high-leverage in multi-language repos. Hook in pyright for Python type info, tsc --noEmit for TS, eslint/ruff for lint, prettier/black for formatting. Each MCP server adds language-specific context the agent can query without re-implementing it. Selected per file extension; not all loaded at once.
ConfigurationMCP registry per workspace: { '.ts': ['tsc', 'eslint'], '.py': ['pyright', 'ruff'], '.go': ['gopls'] }. Routed by file extension; agent calls mcp.lint(file) and gets structured diagnostics.Concept: mcp →The problem
- Find every reference to a function across a 1,000-file repo without reading every file.
- Review the agent's proposed changes with a fresh perspective so confirmation bias doesn't pass through.
- Generate up-to-date docs that reflect the actual code, not last quarter's spec.
- Monolithic single agent with 15 tools trying to do everything → routing accuracy drops 8% per tool past 5; the agent alternates between similar tools and misses obvious matches.
- Read every file first to 'understand the codebase' → context floods at file 80; the agent has lost track of the original task by file 200.
- Same session generates AND reviews the code → confirmation bias passes through; the reviewer agrees with the writer because it shares the writer's context.
- ✓ Grep / Glob locates matched files first; Read opens only those files
- ✓ Code review runs in an independent subagent with fresh context
- ✓ Tool count ≤ 5 per subagent; specialists distributed across reader / reviewer / docgen
- ✓ 4D Framework approval gate before any auto-merge or destructive action
- ✓ Bash structured-output flags (--format json, --porcelain) replace fragile regex parsing
One run, traced end to end
8 steps to production
Profile the codebase before any task
On first invocation, run a one-time codebase-context loader: language(s), framework, top entry points, dependency graph. Cache to .claude/context-cache.json. The lead agent loads this on every subsequent task instead of re-discovering. Saves ~4K tokens per turn.
Concept: claude-md-hierarchy →# scripts/profile_codebase.py
import json, subprocess
from pathlib import Path
from collections import Counter
def profile() -> dict:
profile = {"languages": [], "framework": None, "key_dirs": [], "top_imports": []}
if Path("package.json").exists():
pkg = json.loads(Path("package.json").read_text())
profile["languages"].append("typescript")
deps = list((pkg.get("dependencies") or {}).keys())
if "next" in deps: profile["framework"] = "next.js"
elif "react" in deps: profile["framework"] = "react"
if Path("pyproject.toml").exists():
profile["languages"].append("python")
# Top 50 imported modules across the repo
imports = Counter()
for ext, regex in [("ts", r"^import .* from ['\"]"), ("py", r"^(import|from) ")]:
for f in Path(".").rglob(f"*.{ext}"):
if "node_modules" in f.parts or ".venv" in f.parts:
continue
for line in f.read_text(errors="ignore").splitlines()[:50]:
if line.startswith(("import", "from")):
imports[line.split()[1].rstrip(',')] += 1
profile["top_imports"] = [m for m, _ in imports.most_common(50)]
profile["key_dirs"] = [
p.name for p in Path(".").iterdir()
if p.is_dir() and not p.name.startswith(".") and p.name not in ("node_modules", "dist")
]
Path(".claude/context-cache.json").write_text(json.dumps(profile, indent=2))
return profile
if __name__ == "__main__":
print(json.dumps(profile(), indent=2))Always Grep + Glob before Read
The single biggest exploration anti-pattern is Read on every file in a directory. Instead, Grep finds the symbol or pattern across the repo (returns matched files + line numbers); Glob narrows by path; only Read the files that matched. On a 1000-file repo searching for a function name, this is the difference between 1000 Reads and 12 Reads.
Concept: context-window →Distribute tools across 2-3 specialised subagents
One 15-tool agent routes worse than three 5-tool specialists. Define Reader (Grep + Glob + Read), Reviewer (Read + Grep + Bash test/lint), Doc-Generator (Read + Write + Glob). Each runs in its own context. The lead agent coordinates and merges results. Routing accuracy stays high because each specialist has a clear domain.
Concept: subagents →Spawn the reviewer in a SEPARATE session
If the reviewer shares context with the writer, it inherits the writer's assumptions and rubber-stamps. The fix is structural: the reviewer subagent runs with a fresh messages array, fresh system prompt, no inherited tool history. It sees only the diff + the project rules. The independence is the entire point. Confirmation bias is structural, not philosophical.
Concept: evaluation →Use a scratchpad file for cross-turn state
Long productivity tasks (rename across 50 files, refactor 3 services) span many turns. Don't try to keep all state in the message history. Write it to .claude/scratchpad.md. The lead agent reads it at the start of every turn, updates it after each subagent returns, and trims old entries. The scratchpad is the agent's working memory; the message history is the audit trail.
Concept: claude-md-hierarchy →Wire MCP servers per language extension
Multi-language repos benefit from language-specific MCP servers. pyright for Python types, tsc --noEmit for TS, eslint and prettier for JS, ruff for Python lint. Don't load all MCP servers at session start. Route by file extension when a tool needs them. Keeps context lean, reduces overhead.
Concept: mcp →Implement the 4D approval gate
Delegation (agent proposes), Description (clear output), Discernment (human reviews), Diligence (human approves). The 4D Framework. Code-changing actions are gated behind explicit human approval. The agent presents the diff + the reviewer's verdict + a one-paragraph summary; the human clicks approve or rejects. No auto-merge for productivity tasks; the gate exists because the cost of a bad merge is far higher than the friction of one click.
Concept: 4d-framework →Use Bash structured output, not regex
Tools that emit JSON (gh pr diff --json, git log --pretty=format:%H%x09%s, npm test --reporter json, eslint --format json) replace fragile prose-parsing. Even simple commands have structured-output flags (git status --porcelain, ls -la --time-style=long-iso). Always prefer them. Regex on free-form output is the reason most agent pipelines break in the third week of production.
Concept: tool-calling →9 decisions the exam turns into distractors
One monolithic 15-tool agent does everything in one session
Distribute work across 2-3 specialist subagents (reader → reviewer → applier); 4-5 tools each
Read every file to 'understand the codebase' before deciding
Grep + Glob first to locate matched files, then Read only those
Same session generates AND reviews the code
Spawn an independent reviewer subagent with fresh context, no inherited history
Auto-merge if reviewer subagent says 'approve'
4D Framework: Delegation → Description → Discernment → Diligence (human click)
Single agent has 15 tools (Read, Write, Edit, Bash, Grep, Glob, WebSearch, gh, npm, jest, eslint, prettier, git, jq, sed). Tool selection accuracy drops; the agent calls Bash(cat) when Read would do, alternates between similar tools, and occasionally hangs comparing options.
Distribute tools across 2-3 specialised subagents (Reader, Reviewer, Doc-gen). Each subagent has 4-5 tools maximum. Routing accuracy stays high because each specialist has a clear tool set and a clear job.
Agent generates a refactor diff, the reviewer subagent approves it, and the workflow auto-merges. A subtle regression ships to main. Rollback takes 40 min; the team's trust in the agent drops for the rest of the quarter.
4D Framework: Delegation (agent proposes) → Description (clear output) → Discernment (reviewer verdict) → Diligence (human clicks approve). The human gate is non-negotiable for code-changing actions.
Same Claude session writes the code AND reviews it. The reviewer agrees with the writer on every choice. Same context, same assumptions, same blind spots. Confirmation bias passes through; bugs reach production.
Spawn the reviewer as an independent subagent: fresh messages array, fresh system prompt, no inherited history. It sees only the diff + the project rules. Independence is structural, not philosophical.
Agent runs Read on every file in src/ to 'understand the codebase'. By file 80, context is full of irrelevant content; the agent has lost the original question. Returns generic recommendations instead of specific matches.
Grep + Glob first to locate; Read only matched files. The exploration sequence is non-negotiable: locate → narrow → read. On a 1000-file repo, this is the difference between 1000 Reads and 12.
Workflow parses git log --oneline output with regex to extract commit SHAs. A commit message containing parentheses or a colon breaks the regex; the workflow silently misses commits or attributes them to the wrong author.
Use structured output flags (git log --pretty=format:%H%x09%s, npm test --reporter json, eslint --format json, gh pr diff --json). Parse JSON or fixed-delimiter output. Regex over prose is the reason most agent pipelines break in the third week.
Cost & latency
Grep is one tool call (~200 tokens output, files-with-matches mode). Read on 10-15 files at ~2K tokens each = ~25K input + ~500 output. ~$0.005 typical. Avoiding read-everything saves orders of magnitude on big repos.
Reviewer reads the diff (~3K tokens) + affected files (~6K tokens) + .claude/rules (~500 tokens) + emits structured verdict (~1K). ~$0.012 at Sonnet 4.5 prices. Cheap insurance against a bad merge.
Doc-gen reads source (~4K) + writes JSDoc/docstring (~2K output) + writes README section if asked (~3K output). ~$0.024 typical. Worth running on every commit-back-to-main to keep docs current.
Profile + Grep + Read 12 files + propose diff + Review + Approve + Apply. Sums to ~$0.05 typical. The 4D gate adds zero token cost (human input); reviewer subagent is the dominant line item.
MCP context (language-server output, lint diagnostics) adds ~500-2K tokens per call. Routed per file extension so the cost only applies when language-specific context actually helps.
Check every gate before release
5 exam-pattern questions
Work through one question at a time, check the architecture, then move through the set.
A developer-productivity agent explores a 1,000-file codebase looking for references to a function. It uses Read on every file and runs out of context after 200 files. How should you fix this?
Frequently asked
Should I use Read or Grep to explore a large codebase?
Grep first, always. Grep finds the symbol or pattern across the whole repo in one tool call (returns matched files + line numbers). Then Read only the matched files. Read-everything-first is the single biggest token waste in productivity workflows. And it floods context, which makes the agent worse, not just slower.
Can an agent review code it just generated in the same session?
Not effectively. Same-session review inherits the writer's context, assumptions, and blind spots. The reviewer rubber-stamps because it shares the writer's mental model. Spawn an independent reviewer subagent with fresh context: it sees only the diff + the project rules, with no carry-over. Independence is structural, not philosophical.
How many tools should a developer-productivity agent have?
4-5 per subagent, distributed across 2-3 specialists. One 15-tool agent loses ~8% routing accuracy per tool past 5. By 15 tools, the agent is alternating between similar options and missing obvious matches. Three specialists with clear tool sets (Reader / Reviewer / Doc-gen) outperform one generalist on every dimension.
Do I need MCP servers for code-productivity workflows?
No, but they help in multi-language repos. Built-in tools (Read, Grep, Edit, Bash) cover most tasks. MCP servers add language-specific context: pyright for Python types, tsc --noEmit for TS, ruff for Python lint, eslint for JS. Route per file extension. Don't load all MCP servers at session start.
Should productivity agents auto-merge code?
No. The 4D Framework gate is non-negotiable for code-changing actions: Delegation → Description → Discernment → Diligence (human click). The cost of a bad merge is far higher than the friction of one click. If the team really wants automation, the right move is to auto-create the PR, run the reviewer subagent, and post the verdict. But the human still clicks merge.
How do you handle multi-language codebases?
Per-extension routing for both subagents and MCP servers. The Reader subagent uses Grep with --type ts or --type py to narrow searches by language. The Reviewer subagent loads pyright for .py files and tsc for .ts files. The Doc-Generator emits language-appropriate doc syntax (JSDoc for JS/TS, docstrings for Python). One agent topology, multiple language plug-ins.
How do I secure MCP servers against tool-arg injection and credential leakage?
Five-line MCP security checklist. (1) Secrets via ${ENV_VAR} expansion in .mcp.json, never inline. (2) Tool input schemas treat every parameter as untrusted (no eval, no string concatenation into shell or SQL inside the MCP server). (3) Allowlist binaries the MCP server can invoke; deny everything else. (4) Per-server transport: stdio for local, HTTPS-only for remote, never plain HTTP. (5) Audit-log every tool_use through the MCP server with the input + outcome + caller agent. Cross-link: P3.7 (agentic-tool-design) covers the 4-bucket structured-error contract MCP servers should emit; pair both pages when designing a new MCP server. Tagged related: mcp-security cluster.
