Think of a vault with several layers of security. What can the agent can do
is determined by the tools you list in the field tools
— not by the prompt text. The prompt says "what to do"; the tools say "with what".
Mixing the two is the most common mistake when creating subagents.
Detailed content
🎯 Give it only what it needs
The principle of least privilege is simple: an agent that doesn't need to write shouldn't have permission to write. It seems obvious, but it’s violated all the time. The cost of being too generous with tools doesn’t show up the first time you use them—it shows up when the agent makes an unexpected decision in production.
Least privilege principle applied to subagents
Each tool you add to the field tools
expands the agent's scope of action. Expand only when the agent needs the tool to achieve
the specific objective. When in doubt, start without it — you can add it later; undoing damage in
production is much more expensive.
Draft — unrestricted
You include everything: Read, Write, Bash, WebSearch. The agent works, but isn't auditable.
Refinement — only what you use
You observe which tools the agent actually called. Remove the rest.
Production — minimum validated
Only the necessary tools. Behavior is predictable and risk is contained.
📖 Read-only agents: Read, Grep, Glob
Most analysis, review, and research agents you don't need to write anything.
The trio Read, Grep
e Glob covers practically every file-reading use case —
inspecting files, searching patterns, listing structure. With just these three, you can create an agent
that can learn everything about the repository without changing a byte.
✓ What the trio covers
- ✓Read — read any project file, including configs and secrets (be careful when reporting)
- ✓Grep — search for patterns in text, ideal for finding functions, TODOs, and imports
- ✓Glob — list files by default, map folder structure
- ✓Combined: complete mapping + semantic search + context reading
✗ What they don’t do
- ✗Create or modify files (Write)
- ✗Run system commands (Bash)
- ✗Make HTTP requests (WebFetch, WebSearch)
- ✗Interact with external MCP servers
Tip: Glob + Read in sequence
A very useful pattern: use Glob to find out which files exist, then Read to read only the relevant ones. This is much more efficient than asking the agent to "read everything" — it will prioritize based on the pattern you defined in the Glob.
⚖️ Allowed x disallowed — the concrete list
The file .md of a subagent has a field
tools that receives a list. Everything on the list
is allowed — everything outside it is automatically blocked, with no additional configuration.
There is no "explicitly deny": you includes what it can, the rest doesn’t exist for the agent.
| Tool | Category | Risk if included unnecessarily | Include when... |
|---|---|---|---|
| Read | Reading | Low (can read secrets) | Needs to inspect file contents |
| Grep | Search | Low | Needs to search for patterns in the codebase |
| Glob | Listing | Low | Needs to map the file structure |
| Write | Writing | Medium (modifies files) | Agent needs to generate or edit artifacts |
| Edit | Writing | Medium (patches files) | Agent needs to make precise edits |
| Bash | Execution | High (runs any command) | Agent needs to run scripts/tests |
| WebFetch | Network | High (external access) | Agent needs to fetch external data |
🔌 Allowed MCPs — access to the outside world
MCP tools (Model Context Protocol) give the agent access to external systems: databases, APIs, browsers, services. They are more powerful — and riskier — than native tools. The decision to include an MCP in a subagent should be intentional and specific: does the agent need this MCP server to complete its function?
How MCP servers are inherited
By default, subagents inherit the MCP servers from the parent context. This means that if you have
a database server configured globally, the child agent can also access it
— unless you explicitly restrict it with mcpServers: []
(empty list = no MCPs) or list only the allowed ones.
- →Default inheritance: all MCPs from the parent context are available
- →Total restriction:
mcpServers: []— with no access to any MCP - →The list specifies: only the listed servers are available
✓ MCPs are generally safe for subagents
- ✓Database read MCP (SELECT only)
- ✓Search MCP (Brave, tavily) with a rate limit
- ✓MCP for accessing internal documentation (read-only)
- ✓GitHub MCP for reading PRs and issues
✗ MCPs that need careful review
- ✗MCP that can send emails or messages
- ✗MCP with database write access
- ✗MCP for running deploys or infrastructure
- ✗Payments or billing MCP
🛡️ Real permissions beat the prompt "don't do it"
One of the most common pitfalls: putting instructions in the prompt like “never delete files”
or “don’t run system commands” while the field tools
still includes Bash.
The prompt provides guidance; the tools field is law.
Natural-language instructions can be misinterpreted, ignored under pressure, or bypassed—the tool list can’t.
Don't rely on the prompt alone for security
The agent receives the prompt as high-level context, but the LLM is a probabilistic system. Under high pressure, with ambiguous instructions or long chains, it may:
- —Reasoning that "the exception applies to this specific case"
- —Interpret a vague instruction unexpectedly
- —Be manipulated by prompt injection in the content it processes
Remove the tool. Don’t instruct the agent not to use it.
Practical rule: tools as contract, prompt as style
Use the field tools to define what the agent can do (immutable contract). Use the prompt / description to define how it should do (tone, format, criteria). Mixing the two—using the prompt to prohibit what the tools allow—is false security.
👁️ "If it can read it, assume it will"
When you include Read in the tools field,
the agent can read any file accessible in the project — including .env,
SSH keys, tokens in configs. This is expected and useful, but requires you to know what the agent
can do and that the reports it generates don’t leak sensitive data.
✗ Bad: agent read and reproduced the values in the report
Instruct the agent not to reproduce sensitive data
For agents with Read access in real projects, include this in the prompt: "Never reproduce environment variable values, keys, tokens, or passwords in reports. Only mention that they exist and whether they are configured correctly." Here, the prompt is YES and this is the right place — you are not prohibiting a tool; you are guiding behavior within what is allowed.
🔬 Granularity — Bash and the special case
Bash and the most powerful tool, and the one
that requires the most care. With Bash, the agent can run any system command — install packages,
delete files, make requests with curl, start processes. When Bash is necessary,
the granularity comes from precise description in the prompt about which commands are expected, combined with allowedTools in settings.json
from the project to restrict which binaries can be called.
---
name: code-reviewer
description: |
Revisor de codigo que analisa qualidade, padroes e problemas potenciais.
Leia arquivos .ts, .js e .py no caminho indicado. Reporte: (1) problemas
criticos, (2) sugestoes de melhoria, (3) pontos positivos. Nao altere
nenhum arquivo. Nao execute comandos. Entregue um relatorio estruturado.
tools:
- Read
- Grep
- Glob
# Sem Write, sem Edit, sem Bash, sem WebFetch
# Nenhum MCP server necessario para este agente
---
Ready-made prompts
"Create a subagent named doc-auditor that is completely read-only. It should read Markdown files in the /docs directory, check whether each one has frontmatter with 'title', 'date', and 'author', and generate a compliance report. List the required tools and explain why it doesn't need Write or Bash."
"Read the .claude/agents/meu-agente.md file and assess whether all the tools listed in tools are necessary for the task described in description. For each tool, say: necessary, unnecessary, or it depends. Suggest a streamlined version of the tools list."
"I want an agent that checks whether the package.json file has dependency X. Explain how to do this with only Read (without Bash) and when it would be necessary to add Bash. What is the risk of each approach?"
Exercise
Create the file .claude/agents/log-analyzer.md
for an agent that analyzes log files (.log, .txt) for critical errors
and generates a report with: the number of errors by level (ERROR, WARN, FATAL), the 5 most frequent errors,
and one recommendation. The agent cannot modify any files.
Steps
- 1Define the field
tools— list ONLY the tools needed to read and search text files. - 2Write the field
descriptionwith clear instructions on how to report the results (without reproducing full log lines). - 3Check: Does the agent need Bash? Does it need Write? If not, remove them.
- 4Testing invocation: “use the log-analyzer agent to inspect the files in /tmp/logs”
Verification criteria — how to know you got it right
The agent is correct if it meets all the criteria below:
- ✓Minimum required: tools contain only Read, Grep, and Glob — no Write, Edit, Bash, or network tools.
- ✓Precise description: the description field specifies the report's three items (count, top 5, recommendation).
- ✓Without false security: there’s no instruction in the prompt prohibiting Write — Write simply isn’t in tools.
- ✓Sensitive data: description instructs it not to reproduce full stack trace lines containing user data.
- ✓Testable: when you invoke the agent, it completes the task without requesting extra permissions and without trying to edit files.
Next module:
2.5 — Project x Global. When to put the agent in .claude/agents/ from the project versus the user's global folder.