How to apply least privilege to your agent's MCP tools: default-deny allowlists, narrow scopes, per-server credentials, approval for writes, and a runtime gate.
A JWT is a signed bundle of JSON claims. Here is how to read one, why decoding is not verifying, and how to check for the classic JWT security flaws.
9 min read
This checklist shows how to vet an MCP server before an agent touches it, from provenance and reading a published grade honestly to auth, version pinning and credential scope.
10 min read
A lot of MCP setups end up with the same shape: someone installs a server, the client lists every tool it exposes, and the agent can call all of them with whatever token was pasted into the config. The server did nothing wrong. The permissions were simply never designed.
This piece is about that design, after install. If you have not decided whether a server deserves to be connected at all, start with how to vet an MCP server and come back. Here the question is narrower: of the tools you have connected, what should each one be allowed to do, with which credentials, and who says yes before it acts?
An agent decides which tool to call from text it reads, and some of that text is untrusted. I covered how that goes wrong in MCP prompt injection and the lethal trifecta, so I will not repeat it here. The short version for this article: you cannot guarantee the model will never be steered, so you cap what a steered model can reach. Permissions set the blast radius.
OWASP names this risk directly. LLM06:2025 Excessive Agency traces damaging agent actions to three root causes: excessive functionality, excessive permissions and excessive autonomy. Each step below targets one of them.
There is no single permission switch. Access is decided in four places, and least privilege means tightening each one:
The MCP spec itself keeps the protocol neutral here. The authorization specification is optional, and it applies to HTTP transports; stdio servers are expected to take credentials from the environment instead. So for a lot of local setups, "permissions" means the token in an environment variable plus whatever the client lets the agent call.
Know the tool surface before you scope it. Look the server up in the MCP server directory, or run it through the Andrax MCP scanner, which grades against its own published rubric (mcpgrade-1.4.0, 39 checks). The grade tells you where the risk is: no auth, broad tools, shaky transport. It does not stop anything by itself. Hold that thought for Step 6.
Enable only the tools the task needs. If the agent triages issues, it needs read and comment tools, not delete-repository or change-settings. OWASP's first mitigation for excessive agency is exactly this: minimize the extensions an agent may call, and minimize what each one does.
Two habits make the allowlist hold up over time:
listChanged capability). Treat any tool that appears after an update as off until someone reviews it.write_report_file tool is easier to reason about than a general shell.A tool's real power is its credential. Scope that, not just the tool list.
*, all, full-access), bundling unrelated privileges up front, and treating the scopes claimed in a token as enough without server-side authorization logic.An allowed tool can still be called with bad arguments. Limit what it can reach:
The tools specification puts part of this on the server too: servers MUST validate all tool inputs, implement proper access controls and rate limit tool invocations.
Writes, deletes, payments, deploys and sending messages should wait for a person. This is not just my preference. The tools specification says there SHOULD always be a human in the loop with the ability to deny tool invocations, and that clients SHOULD prompt for confirmation on sensitive operations and show tool inputs to the user before calling the server. OWASP's excessive-agency guidance says the same thing: require user approval for high-impact actions.
Two details decide whether approval actually protects you:
send_email?" is not a decision. The recipient, subject and body are.Everything above is configuration, and configuration is a promise. A grade finds risk; a gate enforces policy. OWASP calls this complete mediation: authorization happens in a system outside the model, and every request through an extension is checked against policy rather than left to the LLM to decide.
In practice that means something sits on the call path, sees each tool call with its arguments, and allows, denies or holds it for approval. Whatever you use, log each decision: which tool, which arguments, which policy rule, who approved. OWASP lists logging, monitoring and rate limiting as the controls that limit damage when prevention misses, and the MCP best practices recommend logging scope elevation events with correlation IDs.
| Control | Where it lives | Example |
|---|---|---|
| Tool allowlist, default deny | Client config | Issue triage agent gets read and comment tools only |
| New tools off until reviewed | Client config | Tool list changes after an update; nothing new is enabled |
| One credential per server | Server credentials | Separate tokens for GitHub and the ticket tracker |
| Read-only and minimal scopes | Server credentials | Read-only database role; no wildcard OAuth scopes |
| Token audience checked | Remote server | Server rejects tokens not issued for it; no passthrough |
| Path and egress allowlists | Host | One project folder; outbound calls to listed hosts only |
| Sandboxed local servers | Host | Container with no access to the home directory |
| Approval for changes | Client or gateway | Full parameters shown before any send, delete or deploy |
| Runtime policy and logs | Policy layer | Every allow, deny and approval recorded |
If you would rather not build the policy layer yourself, that is the part SentinelAgent Guard does. It sits in front of your MCP server and runs 22 controls on every call. Those 22 controls are Guard's runtime rubric (mcpgrade-2.0.0); they are a different thing from the scanner's 39 checks, and the two numbers should never be compared as scores. The free tier runs all 22 controls on one server. See Guard's Free and Pro plans.
Rubric fence: Andrax scanner grades are mcpgrade-1.4.0 (39 checks). SentinelAgent Guard's runtime is mcpgrade-2.0.0 (22 controls). Never equate the two scores.
Does MCP have built-in permissions? Not as one feature. The protocol defines optional OAuth-based authorization for HTTP transports, including audience-bound tokens and scope challenges. Which tools an agent may call, and when a human must confirm, is left to the client and your own policy. The tools spec recommends a human in the loop but does not mandate a specific interaction model.
Is a scanner grade enough? No. A grade is a point-in-time view of risk. It does not restrict what the agent does at call time. Use it to decide what to scope, then enforce the scope.
Should I auto-approve read-only tools? Only for tools you have reviewed yourself, from servers you trust. Annotations from an untrusted server are not evidence, and even a genuine read can leak data if the agent can also send it somewhere.
Where should I start if I have a dozen servers connected? List every enabled tool, switch off what no task uses, then split shared tokens into per-server credentials. Those two changes cut the most blast radius for the least effort. For a quick reference afterwards, keep the MCP security cheat sheet open.
Share this article
Point-in-time MCP grades find risk; runtime firewalls enforce policy on tool calls. Andrax mcpgrade-1.4.0 vs Guard mcpgrade-2.0.0 — no score equating.
9 min read
Sign in to leave a comment.