What MCP changes: tools any agent can call
The Model Context Protocol (MCP) is an open protocol for connecting AI applications to tools and data. An MCP server describes a set of tools, each with a name, a description and an input schema; an MCP client inside an AI application lists those tools and lets the model call them. The specification is public and versioned, and both servers and clients are now common across developer tools, office suites and business software.
The benefit is reuse: one server can serve many agents. The risk follows from the same fact. A tool that posts an invoice, issues a refund or changes a record is now callable by any agent that connects to the server, with whatever credential the server holds, on the strength of whatever the model decided. MCP standardises how tools are called. It does not decide which calls should be allowed. That decision is yours.
Where the server runs matters too. A local server started on a laptop over standard input and output runs with that user's permissions and whatever tokens sit in its configuration file. A remote server reached over HTTP runs with its operator's credentials and, under the specification's authorisation model, should validate tokens issued to it rather than accept any token it is handed. Inventory both kinds: local servers are the ones most often missed, because they never pass through a procurement process.
The main threats to MCP servers with write tools
Most MCP risks are familiar security problems in a new shape. The ones that matter most for write tools are these.
| Threat | What happens | Main control |
|---|---|---|
| Prompt injection through tool output | Text returned by one tool, such as an email or web page, carries instructions the model follows when calling another tool. | Policy on the write itself; never trust the model's plan for consequential changes |
| Tool poisoning | A tool's description or schema contains hidden instructions, or changes after you approved the server. | Pin and review tool definitions; alert on changes |
| Excessive agency | Tools offer more functionality, permissions or autonomy than the task needs (OWASP LLM06). | Least privilege; separate read, stage and act tools |
| Credential sprawl | Long-lived tokens for business systems sit in server configurations and agent environments. | Short-lived, scoped credentials held outside the agent |
| Confused deputy | The server uses its own broad credential to act for a user who should not have that access. | Act with the caller's authority; check it per call |
The OWASP Top 10 for LLM Applications 2025 ranks prompt injection first, and OWASP's agentic AI threats and mitigations guidance covers tool misuse and privilege compromise. The common thread is that you cannot fully prevent a model from being misled, so the protection has to sit at the point where a tool changes something.
Classify tools: read, stage, act
Sort every tool on a server into one of three classes, by what it can change, not by what its name suggests.
- Read toolsReturn data. No change to any system. Scope them to what the user may see.
- Stage toolsPrepare a change (a draft, a diff, a quote) without committing it.
- Act toolsSubmit a write intent. A policy check runs, an approver is asked above the threshold, and a separate writer that holds the credential commits it.The agent never holds the write credential.
- Record every act callCaller, arguments, policy decision, approver and outcome, linked so later edits are detectable.
Read tools return data and change nothing. They still need access control, because they can leak what the user should not see. Stage tools prepare a change without committing it: a draft invoice, a proposed journal, a quote. They let the agent do useful work while leaving the decision for later. Act tools commit a change to a system of record. Keep act tools few and narrow: “post this staged journal” is safer than “run any accounting operation”.
| Tool | Class | Why |
|---|---|---|
| get_trial_balance | Read | Returns figures; changes nothing |
| search_suppliers | Read | Returns records the user may see |
| draft_journal_entry | Stage | Creates a draft that is not posted |
| draft_payment_batch | Stage | Prepares payments without releasing them |
| post_journal_entry | Act | Posts a staged draft to the ledger |
| release_payment_batch | Act | Sends money; hard to reverse |
| update_supplier_bank_details | Act | Changes where future payments go; always held |
The stage class is the one most servers lack, and it is the one that makes approval practical. An approver can review a staged change as a diff; an approver asked about a free-form instruction cannot.
Tool annotations are hints, not controls
MCP lets a server annotate each tool with hints: readOnlyHint (the tool does not modify its environment), destructiveHint (a modifying tool may make destructive rather than additive changes), idempotentHint and openWorldHint. They help a client decide when to ask the user for confirmation.
They are, however, claims made by the server about itself. The specification states that clients must treat annotations as untrusted unless they come from a trusted server, and the protocol's own blog post on tool annotations explains why: a server can declare a tool read-only and still delete data. Use annotations to improve the user experience. Do not use them as the reason a write was allowed.
The same applies to tool descriptions in general. A description is text the model reads, which makes it an input an attacker can shape. Review descriptions as you would review code, and treat a change to one as a change that needs approval.
Keep the credential away from the agent
The strongest single control for MCP write tools is architectural: the agent, and the MCP server it talks to, never hold a standing credential that can write to the system of record. Instead, an act tool submits a write intent. A separate component checks it against rules, obtains an approval where needed, and only then uses a short-lived, single-use credential, scoped to that one change, to commit it. This is the single writer pattern.
With a single writer, a compromised or misled agent can propose a bad change but cannot make one outside the rules. Without it, every control is only as strong as the agent's willingness to follow it. For HTTP-based servers, follow the specification's authorisation model and its security best practices, which warn against passing a client's token straight through to downstream services.
Approvals for act tools above a threshold
The MCP specification expects hosts to keep a person able to deny tool calls. For write tools, make that concrete: set a threshold per act tool, by amount, by record type, by counterparty or by reversibility, and hold calls above it for a named approver who is not the requester. Below the threshold, act calls proceed within limits and are recorded.
Two details matter. The approver should see the staged change as a diff, not the model's reasoning. And the approval should bind to that exact change: if the agent alters the arguments after approval, the approval should no longer apply. Our guide to human-in-the-loop for AI agents covers thresholds and approval fatigue.
Record each act call with its policy decision
A transport log of JSON-RPC messages is useful for debugging but weak as evidence. For each act call, record the calling agent and the user or process it acted for, the tool and its arguments, the rules evaluated and their results, the approver if any, the outcome, and a link to the previous record so later edits are detectable. Record refused calls too.
Pin the tool definitions you approved, with a digest of each description and schema, and record which definition was in force for each call. If a server changes a tool's description after review, you will see it, and so will your auditor. The AI agent audit trail guide lists the fields in detail.
Give every act call a correlation identifier that travels from the agent's session through the MCP server to the record and, where the downstream system allows, into the change itself, such as a reference on the journal entry. Then a reviewer can trace a ledger line back to the agent, the rules and the approver in one step, and trace a refused call to the conversation that produced it.
Governing an MCP server you did not build
Many MCP servers come from vendors. You cannot change their code, but you can put a governing layer in front of them: a proxy or gateway that lists the server's tools, classifies them, applies your rules to each call, holds act calls above the threshold and records every decision.
Be honest about what this gives you. If the vendor's server holds its own credential to the downstream system, your gateway can evaluate and record every call that passes through it, but it cannot stop a call made by another route. That is an advisory arrangement, useful and auditable, but not enforcement. Enforcement needs the credential to sit with the component that makes the decision.
A checklist for MCP write tools
- Every tool on every connected server is classified as read, stage or act, and the list is reviewed when a server updates.
- Act tools are few and narrow, and each has a written threshold for approval.
- No agent or MCP server holds a standing credential that can write to a system of record.
- Credentials for act calls are short-lived, single-use and scoped to the change.
- Approvals bind to the exact staged change and are given by a named person who is not the requester.
- Tool descriptions and schemas are pinned by digest; changes raise an alert.
- Every act call, allowed or refused, leaves a linked record with its policy decision.
- Annotations are used for user experience only, never as the basis for allowing a write.
How elan1 handles this
The elan1 MCP server exposes its tools in exactly these three classes. Read tools return data, stage tools prepare a change without committing it, and every act tool submits a write intent that climbs the Right Path in elan1 Govern: identity, pre-gates, versioned rules, a guardrail, an autonomy check and a named approver where your rules ask. The MCP server reference: read, stage and act tools lists each tool and the typed refusals it can return.
Where elan1 holds the write credential (Mode A), the kernel is the single writer and commits with a short-lived, single-use credential, so the rules are enforced. Where you connect over MCP or HTTP and keep the credential, elan1 works in Mode B (Attested advisory): every intent is evaluated and recorded, and enforcement stays with your system. See MCP governance for the integration options, and safe AI agent write access to production for the developer view.