Most organisations govern Model Context Protocol servers the way they govern browser extensions: someone installs one, nobody records it, and the review — if there is one — asks whether the publisher looks reputable. The comparison that fits is not the extension. It is the service account with API keys that your integration team would have spent a fortnight approving three years ago.
The sentence that decides how you read the rest. The specification says of a server’s own descriptions of its tools: “For trust & safety and security, clients MUST consider tool annotations to be untrusted unless they come from trusted servers.” A read-only marker is a claim made by the thing you are deciding whether to trust.
Plain-English explainer · MCP revisions and vendor terms change — verify current documentation · Last reviewed August 2026
Installing an MCP server grants three things at once, and organisations usually review only the first. It exposes data to a model, it hands the model a set of callable tools, and it lets those tools take real actions in organisational systems under a credential somebody already holds. The Model Context Protocol is an open protocol for connecting AI clients to external systems: a client — Claude Desktop and Claude Code, Cursor, VS Code with GitHub Copilot, ChatGPT connectors, Microsoft Copilot Studio, among others — connects to a server that advertises tools, and the model chooses which to call. Which client is in play changes what you can enforce, so the client belongs in the policy alongside the server. The protocol is well specified and the engineering is sound. The governance failure is not technical. It is that the install looks like adding an extension and behaves like provisioning an integration with standing access, and the approval most estates apply is sized for the first of those. What follows is what the grant consists of, why authentication is not approval, the review a material server deserves, a tier model that keeps low-risk use frictionless, the two artefacts that make any of it evidenceable, and what an assessor asks for when the register is finally tested. Where the question is really whether formal governance applies at all, start with when a tool becomes an AI agent.
Key Takeaways
- An MCP server is a capability surface, not a piece of software: what matters is the set of tools it exposes, the credential those tools spend, and the fact that the set can change after you approved it.
- OAuth establishes that a principal consented and binds a token to an audience. It says nothing about whether the scopes are minimal, whether the tools match their descriptions, whether the server resists manipulation through content it reads, or whether this use case should exist.
- Enforce read-only at the credential — a token or role that physically cannot write — because that is the one place in the chain where the server has no vote.
- The approval you granted describes the tool set on the day you granted it. A server can add tools later, so the durable control is a recorded baseline manifest with a hash, a pinned version where one exists, and a scheduled diff that alerts a named owner.
- Individual per-service OAuth makes least privilege, attribution, revocation and inventory structurally hard. Enterprise-brokered authorisation with purpose-created identities makes all four ordinary.
Four grants, one click
Separating the grants is the first useful move, because each is owned by a different person and each fails differently. The fourth applies only to local servers, and it is the one security teams miss because it does not look like installing software — it looks like editing a configuration file.
| Grant | What it actually confers | The question it forces | Anchors |
|---|---|---|---|
| Context exposure | Whatever the server returns enters the model context alongside your prompt, your open files and the output of every other connected server. A tool result is not passive data — it is text the model will read and may act on. | What can reach this server, and what does it return into a context window that also holds privileged material? | CC6.7 · A.7 |
| Tool access | A named set of callable functions with typed inputs, discovered at runtime through tools/list. The set can be empty, can change over time, and may vary with the authorisation the caller presents. | Which tools exist today, which of them write, and what happens the day the list is longer than it was at approval? | CC6.3 · CC8.1 · A.9.4 |
| Action in your systems | Every call runs under a credential someone already holds — an OAuth token for a remote server, or an environment variable for a local one. The system being acted on sees that principal, not the model. | Whose authority is being spent, what is the blast radius of the widest scope granted, and who is accountable in the downstream audit log? | CC6.1 · CC6.2 · A.10.2 |
| Code execution on the endpoint | A local server is a process launched on the user machine by a command in a configuration file, running with the user’s privileges. The specification treats this as a distinct risk and requires clients offering one-click configuration to show the exact command before executing it. | Is this server local or remote, what command starts it, where did the package come from, and is it sandboxed? | CC6.8 · CC7.1 |
Two protocol details make the grant larger than it first appears. The tool list is discovered at runtime rather than declared in advance, so what a server can do is a property of the server at the moment you ask, not of anything you installed. And servers can drive interaction back through the client — asking the user for input mid-call, for instance — so the connection is bidirectional in a way an outbound API call is not. Neither is a flaw. Both mean “a library we added” is the wrong mental model, and “a party we granted standing access to” is the right one.
Authentication is not approval
The most common reason an MCP server enters an estate unreviewed is that it presented a familiar consent screen and the person clicking it treated the screen as the control. The protocol’s authorisation model is genuinely careful: a protected server acts as an OAuth 2.1 resource server, servers must publish protected resource metadata under RFC 9728 so clients can discover the authorisation server, clients must send the resource indicator defined in RFC 8707 so a token is bound to the server it is meant for, and the specification forbids the passthrough anti-pattern outright — an MCP server must not accept tokens that were not issued for it, and must not forward them onward.
All of that is worth having, and none of it is an approval. The consent screen tells you a named person authorised a named client to hold a token with certain scopes — and nothing about scope minimality, tool behaviour, resistance to hostile content, or whether the organisation wants this capability at all.
Authentication answers who is connecting. Authorisation answers what the token may reach. Approval answers whether this should exist in our estate, at this reach, for this purpose, until when. Only the third is a governance decision, and it is the one nobody is asked to make.
There is a further gap that surprises people, and it turns on which transport is in play. Two are relevant. stdio is how a local server runs: the client launches a process on the endpoint and speaks to it over standard input and output. Streamable HTTP is how a remote server runs, having superseded the earlier HTTP+SSE transport. Authorisation is optional in the protocol and it is scoped to the HTTP transport: the specification states that implementations using stdio should not follow the authorisation specification and should instead retrieve credentials from the environment. So for a locally run server — which is how a great many developer servers run — there is no consent screen, no scope set and no authorisation server. There is an environment variable containing an API key. Any control model that assumes an OAuth flow sits between a person and a system will simply not see that class of server, and the gateway, broker and egress-proxy advice on this page applies to the HTTP transport only. It has no purchase on a process talking over a pipe.
One caveat on all of the protocol detail here: this page was reviewed against the MCP specification revision current in August 2026. Revisions change transports, deprecate others and tighten requirements. Confirm the revision in force for your clients and servers before relying on any clause quoted here.
Scope quality is the second gap, and the specification’s own security guidance is blunt about it. Its scope-minimisation section names the common mistakes directly: publishing every possible scope in the supported list, using wildcard or omnibus scopes, and bundling unrelated privileges to pre-empt future prompts. Each of those is invisible on a consent screen that renders a scope name rather than its consequences. Read the scopes against the tools you actually approved — and if the vendor ships one indivisible scope set covering both reading and writing, that is a finding, not a formality.
The threats that are specific to this
The protocol’s own security guidance names its attack classes and states the mitigations, which is more than most integration patterns offer, and public-sector guidance has followed — the United States National Security Agency’s Artificial Intelligence Security Center published a cybersecurity information sheet on MCP security design considerations for AI-driven automation in 2026. Read the third column first: most of these are obligations on the client vendor or the server publisher rather than on you, which turns them from work into questions — asked during client selection, and asked of a publisher during review. The fourth column is what lands on your side.
| Named risk | How it works | Whose obligation | What lands on you |
|---|---|---|---|
| Confused deputy | A server proxying a third-party API holds one static client identifier for it. Combine that with dynamic client registration and a consent cookie already set in the browser, and an attacker can obtain an authorisation code without the user genuinely consenting a second time. | Server publisher | A diligence question when you consume a proxy server, an obligation if you publish one: per-client consent stored server-side, redirect URIs validated by exact string match rather than pattern, and single-use state values set only after consent is approved. |
| Token passthrough | A server accepts a token that was issued for a different audience and forwards it unmodified to a downstream API. Rate limits, request validation and audit trails that key on audience are all bypassed, and the downstream log shows the wrong identity. | Server publisher | Ask whether the server validates the audience of every token it accepts and whether it obtains a new, correctly scoped token for downstream calls. The specification forbids passthrough outright, which makes this a conformance question rather than a preference. |
| SSRF through discovery | Applies to the Streamable HTTP transport, not to stdio. During authorisation discovery the client fetches URLs the server supplies. A hostile server can point those at internal addresses, at a cloud instance metadata endpoint, or at a service listening on localhost — and the response or the error message leaks back. | Client vendor | A client-selection criterion: does it require HTTPS and block private, loopback and link-local ranges, and does it validate redirect targets rather than following them. Where a client runs server-side, route its HTTP-transport discovery through an egress proxy that blocks internal destinations. |
| Malicious authorisation URL | A hostile server returns an authorisation URL using a scheme the client passes straight to the operating system or a shell — script execution in the client, or command injection on the host. | Client vendor | Another client-selection criterion. Clients are required to accept only http and https schemes and to avoid shell execution when opening URLs. It is also a plain reason not to point a managed corporate client at an unreviewed remote server. |
| Local server compromise | A configuration entry launches a process on the endpoint with the user’s privileges. The payload can sit in the package, in the start command itself, or arrive with the next unpinned fetch of the latest version. | Shared | Allowlist local servers, ban start commands that resolve the latest published version at launch, prefer stdio over a locally bound HTTP port, sandbox where the client supports it, and keep secrets in a manager rather than in the configuration file. |
| Tool shadowing | Tool names are unique only within a server. A client aggregating several servers can hold two tools with the same name, and a server connected later can shadow a name the user believes belongs to something else. | Client vendor | Prefer clients that qualify tool names with a server identifier, and make the set of servers connected in one session the unit of review — because the collision is a property of the combination, not of either server alone. |
| State handle hijacking | A server that carries state across calls returns a handle — a cart, a workflow, a session — and accepts it back as an ordinary argument. If the server does not check that the handle belongs to the caller, anyone holding it can act on someone else’s state. | Server publisher | Ask stateful servers how handles are bound to the authenticated principal and how long they live. The rule is that possession of a handle must never be treated as authentication. |
Read down the third column and a conclusion falls out that most enterprise MCP policies miss: the client is part of the control surface. Four of the mitigations above live entirely in the client — URL scheme validation, private-range blocking during discovery, tool-name disambiguation, and the dialog that shows the exact command a local server will run before executing it. A policy naming which servers may be connected but not which clients may connect them has governed half the problem. Name the approved clients, and treat a change of client as a change of control environment.
One more risk sits outside the protocol and above it. When a model reads content it did not generate — a ticket body, an inbound message, a page — and a tool is available that can act, instructions embedded in that content can influence which tool gets called. This is not an MCP defect. It is what happens when a probabilistic caller is given real capability, and it is why Prompt Injection sits at LLM01 in the 2026 edition of the OWASP Top 10 for LLM Applications. The controls that reduce blast radius are set out in prompt injection once tools are connected.
What a material server deserves
This is the checklist for anything above the self-service line, deliberately short enough to complete in under an hour for a well-documented server — a review that takes a week will be routed around. The fourth column is what should stop an approval rather than merely be noted.
| Review area | What to establish | A good answer | What should stop it |
|---|---|---|---|
| Publisher and provenance | Who publishes the server, whether the namespace is verified, whether the publisher is an organisation you already have a contract with, and whether the code is inspectable. | A verified namespace tied to a domain or organisation you recognise, a maintained repository with a release history, and an existing supplier relationship or a signed agreement. | An anonymous publisher, a package first published weeks ago, a name that closely resembles a well-known server, or a repository with no issue history and one contributor. |
| Distribution and pinning | How the server reaches the machine or network — npm, PyPI, a container image, a hosted URL — and whether the version in use is pinned or floating. | A pinned version or an image digest, resolved from a registry your organisation already proxies and scans, with a documented upgrade path. | A start command that fetches the latest published version at every launch, so the code executing today is not the code that was reviewed. |
| Tools exposed | The full tool list as it stands at review: names, descriptions, input schemas, and which of them mutate state. Capture it, do not summarise it. | An exported tool manifest attached to the approval record, with each tool classified read or write by what it does rather than by what it is called. | A tool whose description does not match its schema, a generic escape hatch such as an arbitrary query or shell tool, or a list nobody can produce on request. |
| Scopes and credential | Which OAuth scopes the server requests, or which environment variables and API keys a local server reads, and what those permissions allow beyond the stated use case. | A narrow scope set matched to the tools actually approved, held by a purpose-created identity rather than a person’s standing access. | Wildcard or omnibus scopes, admin-tier tokens requested for a read use case, or a personal access token pasted into a config file on a laptop. |
| Data flow and residency | Where the server runs, what leaves your boundary to reach it, what it retains, what it logs, and which sub-processors sit behind it. | A remote server under a contract with stated retention and sub-processors, or a local server with no outbound egress beyond the system it integrates. | A hosted server with no agreement, no stated retention, and confidential material in scope — a vendor relationship created by an install rather than by a contract. |
| Write capability | Whether the server can only read, or can also create, modify, delete, send, spend or grant — and whether any write is irreversible. | Read and write capabilities held as separate approvals, on separate credentials, with irreversible actions gated by explicit confirmation. | A single approval covering both, which silently takes the tier of the most destructive tool in the list. |
| Injection posture | Whether the server returns content that an untrusted party can influence — ticket bodies, inbound email, web pages, repository issues, customer records. | A documented understanding that returned content is data, confirmation required before consequential calls, and no path from one server’s output to another server’s write tool without a human. | A server that reads attacker-influenced content in the same session as a tool that can move money, change access or send mail externally. |
| Update and change control | How the tool set can change after approval, whether the client is notified, and who watches. A list-changed notification is a protocol event, not a governance one. | A pinned version, a recorded baseline manifest, an automated diff against that baseline, and a named owner who receives the alert. | A hosted server that can add tools server-side with no version to pin and no notification anyone reads. |
| Logging and deprovisioning | What record exists of each tool call, whether it identifies the human on whose behalf it ran, how long it is retained, and how the server is removed. | Tool-call logs retained beyond your assessment period, attributable to a person, plus a documented revocation path that ends the credential and not merely the client entry. | Deleting the config file and calling it removal. The token, the service identity and the downstream grant all outlive the entry. |
The row people skip is the tool manifest, and it is the one that pays for the whole exercise. Exporting the tool list at approval costs a minute and converts every later question — did this change, when, who approved the addition — from an argument into a diff. The exact fields to export are set out further down, because “record the manifest” is not an instruction anyone can follow.
A tier model that survives contact
Tiering is what stops the review process collapsing under its own weight. Four dimensions decide a tier because four dimensions decide consequence: whether the server writes, whose credential it spends, whether its effects are reversible and internal, and how much human oversight sits in the path. The tier belongs to the deployment, not the software — the same server is Tier 1 on a read-scoped token and Tier 3 on an administrative one.
| Tier | Definition | Typical examples | Approval route |
|---|---|---|---|
| Tier 0 | Read-only, local scope, no organisational credential. Reads public data or files already on the machine and returns them to the model. | A documentation fetcher, a local filesystem reader scoped to a project directory, a public reference lookup. | Self-service from an allowlist. Recorded, not reviewed. |
| Tier 1 | Read-only against an internal system, using an organisational credential with read scopes. No mutation of any kind. | Search over an internal wiki, read-only ticket lookup, read-only observability queries, a code-search server over private repositories. | System owner approves. Security notified. Register entry required. |
| Tier 2 | Write-capable within a bounded system whose actions are reversible and internal, with no third-party or customer-visible effect. | Creating and updating internal tickets, writing to a scratch database, opening a pull request that still requires a human approver. | Security review against the checklist. Named owner. Separate credential. |
| Tier 3 | Write-capable in a system of record, or capable of externally visible or hard-to-reverse action — customer data, identity, money, communications. | CRM record mutation, sending mail on a user’s behalf, changing group membership, payment or refund tools, production deployment. | Full review plus explicit business sign-off. Confirmation required per consequential call. Enhanced logging. |
| Tier 4 | Cross-system reach combined with delegated authority and low human oversight — several servers in one session, at least one of them Tier 3, running unattended or on a schedule. | An agent that reads inbound mail, queries the CRM and issues credits without a human in the path. | Treated as an AI agent deployment, not as an integration. Impact assessment, oversight design and a stop mechanism before go-live. |
Two rules make the model hold. A deployment takes the tier of its most consequential tool, not the average. And a combination of servers in one session can exceed the tier of any server in it — the tool-name collision above is exactly that, a defect of a pair that no review of either member surfaces. So record the set of servers connected together, not only the individual approvals: the session is the unit of assessment, and it is what produces Tier 4. Excessive Agency — tools beyond the task, permissions beyond the tools, autonomy beyond the risk — is LLM03 in the 2026 edition of the OWASP Top 10 for LLM Applications, published on 4 August 2026, up from LLM06 in the 2025 edition and the largest upward move in that list. The tier boundaries above are drawn along exactly those three seams.
Registries, allowlists and self-service
An approved registry is the control that scales, because it moves the decision from the moment of installation to a moment you chose. In practice it means one curated internal list of servers, each with a tier, an owner, a pinned version and a note of which credential it may use, published somewhere engineers actually look, with additions handled in days rather than weeks.
It is important to be precise about what a public registry does and does not give you. The official MCP Registry — in preview at the time of writing — verifies namespace ownership through GitHub, DNS or HTTP challenges, so a name in the com.example/server form genuinely belongs to the party that controls that domain. Its own documentation is candid that it delegates security scanning to the underlying package registries and to downstream aggregators, and that it focuses on namespace authentication and metadata hosting. That is a sound division of labour, and it means the same thing OAuth means: verified provenance tells you who published this, not whether it is safe, well-scoped, or right for you. Marketplace listing is not certification either — curation quality varies, and the publisher is the one making the claims.
Self-service is defensible, and pretending otherwise is how you end up with a register that describes a fictional estate. The honest boundary has four conditions, and all four have to hold together: the server is on the curated allowlist, it holds no organisational credential beyond read access to information the requester could already reach, it makes no externally visible change, and the client it runs in is a managed one signed in under your tenant. Inside that boundary, record the install and move on. Outside it, the review applies.
What makes this work is the enumeration underneath it, and that is the part most estates have not built. Configuration lives client-side, in files on endpoints, so the population of servers in use is not something a central console knows unless you collect it — a point developed in building an AI system and agent inventory. An allowlist with no discovery behind it is a policy document. An allowlist with endpoint collection and a broker in front of remote servers is a control.
Two approvals, and a moving target
A server that can read and write should be two approvals, not one. The reason is arithmetic rather than principle: a blanket approval takes the tier of the most destructive tool in the set, so bundling a search tool with a delete tool prices the search at the delete’s risk and buys you nothing. Split them, and the read deployment runs at Tier 1 for everyone while the write deployment carries the review, the confirmation prompts and the narrower population of users who need it.
Splitting is only real if it is enforced where the server has no vote. Three places work, in descending order of strength. First, separate credentials, so the read deployment holds a token or role that physically cannot write. Second, separate server instances or configurations, where the product supports exposing a subset of tools. Third, client-side tool allowlisting, which is useful but weakest, because it depends on the client being configured correctly on every endpoint. What does not work is relying on the read-only annotation, for the reason set out at the top of this page.
Then there is the change problem, which is the part that breaks approvals quietly. The tool set is discovered at runtime. The specification is explicit that it may change over time, and provides a notification for servers that declare the capability. A hosted server can therefore add a tool — or change what an existing tool name does — with no version bump on your side and no file on any endpoint changing. Every approval carries an unstated assumption that the capability you assessed is the capability in production, and this is the mechanism that quietly falsifies it.
The four controls, in order of cost: pin versions and digests, record the manifest, diff it on a schedule with the alert routed to the named owner rather than a shared mailbox, and write the re-approval trigger to fire on capability change rather than on configuration change, because those are different events and only one of them is visible on your endpoints. The full treatment, including how to write the trigger, is in approving MCP tools and handling capability change.
The two artefacts everything else rests on
Everything above reduces to two files per server. A register entry, which is the decision, and a baseline manifest, which is the capability the decision was made about. Neither needs a tool to produce, and both are worthless if the fields are improvised per server — the whole value is that a later comparison is mechanical.
Register entry
One row per deployment, not per server. The same software approved twice on two credentials is two entries.
server_name · namespace | The reverse-DNS name where one exists, so two servers called “search” are distinguishable in the register itself. |
publisher · relationship | Who publishes it, and whether a contract already exists with them or the install created the relationship. |
source · version_or_digest | Registry, image or URL, plus the pinned version or digest. A blank here means the reviewed code is not the running code. |
transport | stdio or Streamable HTTP. It decides whether the authorisation specification applies at all. |
tier | 0 to 4, assigned to the deployment rather than the software. |
requesting_team · target_system · system_owner | The three names that make ownership survive a reorganisation. |
credential_identity · granted_scopes | The purpose-created identity and the exact scope set, not the vendor’s documented default. |
tool_count_at_baseline · manifest_hash | The two values the scheduled diff compares. Everything else in the entry is context. These are the control. |
approver · approval_date · review_date | Approver must not be the requester. The review date is what turns the register into a recurring control. |
revocation_route | Where the credential is killed — the authorisation server or the target system — written down before it is needed. |
Baseline manifest
The saved response to the protocol’s tools/list call, plus its resource and prompt equivalents, captured at approval.
tools[].name | Unique only within a server, so store it qualified by the server identifier to make collisions visible. |
tools[].description | The text the model reads when choosing. A description that drifts from the schema is a finding, not a typo. |
tools[].inputSchema | The actual argument surface. A tool that gains a free-text query or path parameter has widened without changing its name. |
tools[].annotations | Captured as a claim, never as a control — including any read-only hint. |
resources[] · prompts[] | Server-controlled text and templates that also enter the context window. Omitting them understates the surface. |
response_hash | A hash over the normalised whole. This is what makes the scheduled check a string comparison rather than a reading exercise. |
Two notes on capture. Normalise before hashing — sort the tool array by name and strip anything that varies between calls — or the diff fires every night on nothing and stops being read within a fortnight. And capture the manifest through the credential the deployment will use, not through an administrator’s session, because a server may advertise a different tool set to a different authorisation. A baseline taken as an admin is a baseline for a deployment that does not exist.
Enterprise authorisation versus per-user OAuth
The default pattern — each employee connecting each server to their own account, one consent screen at a time — is the easiest to start and the hardest to govern. Every row below is a property that individual OAuth makes structurally difficult and brokered authorisation makes ordinary.
| Property | Individual per-service OAuth | Enterprise-brokered | Why it matters |
|---|---|---|---|
| Whose credential is spent | The employee’s own access, granted through a consent screen they clicked. | A purpose-created identity for the integration, provisioned by a system owner. | Determines whether least privilege is even possible, and who the downstream log implicates. |
| Least privilege | Bounded by what that person can already reach, which is usually far wider than the use case. | Scoped to the approved tool set, and reducible without taking anything from the human. | CC6.3 asks that access be granted with least privilege and segregation of duties in view. |
| Offboarding | The integration breaks — or worse, keeps working on a token that outlives the account. | Ownership transfers. Nothing silently keeps running under a departed employee. | Orphaned integrations are among the most common findings in an access review. |
| Attribution | Downstream logs show the person, with no signal that an agent acted rather than a human. | The service identity is distinguishable, and the human on whose behalf it ran is carried in the record. | Without it, incident reconstruction cannot separate what a person did from what a model did. |
| Revocation | Requires finding every user who connected the server, on every machine. | One grant to withdraw, one identity to disable, one list of who was affected. | A kill mechanism you cannot execute in minutes is not a kill mechanism. |
| Visibility | None by default. The install is a line in a config file on an endpoint nobody enumerates. | A brokered connection is a chokepoint you can inventory, rate-limit, log and inspect. | The inventory obligation is unmeetable if discovery depends on asking people. |
The pattern that delivers those properties is a broker or gateway in front of remote servers on the HTTP transport: one place where connections are authorised, scoped, rate-limited and logged, holding purpose-created identities rather than employee tokens. It is not free — a component to run and a single point of failure to design around — so the honest sequencing is to broker Tier 2 and above first and leave Tier 0 and Tier 1 direct. One detail is worth insisting on regardless: downstream systems should be able to tell an agent call from a human one, which means the service identity must be distinguishable and the human on whose behalf it ran must be carried in the record. Delegation design is developed in AI agent identity and delegated authority.
The responsibility split, in one table
Most MCP governance fails at ownership rather than design. Two rows get dropped in practice — the credential and the deprovisioning — because everyone assumes the system owner did the first and that deleting a config entry accomplished the second. Read the last column with the same eye: an advisor prepares and coordinates, and does not test its own work.
| Lifecycle step | Requesting team | Target system owner | Security | TCSA (advisory) |
|---|---|---|---|---|
| Raise the request | Owns. States the use case, the systems involved and what the assistant is meant to do that it cannot do today. | — | — | Supplies the request template so the tier can be assigned without a second conversation. |
| Assign the tier | Proposes. | Confirms what the target system would actually expose. | Owns the decision. The tier drives everything downstream. | Designs the tier boundaries and calibrates them against the estate. |
| Establish publisher and provenance | Supplies the source, the package and the version. | — | Owns. Verifies namespace, distribution and pinning. | Runs the checklist and drafts the record. |
| Mint the credential and set scopes | — | Owns. Creates the purpose-built identity and grants the minimum scopes. | Reviews the scope set against the approved tool list. | Specifies the scope set and argues down anything wider than the use case. |
| Capture the baseline manifest | Exports the tool list from the connected client. | — | Stores it with the approval record. | Sets the format so a later diff is mechanical rather than interpretive. |
| Record in the register and connect | Connects. | Named as the accountable owner of the target system. | Owns the register entry and the review date. | Builds the register schema and the entry discipline. |
| Monitor and respond to capability change | Answers when the alert fires on their server. | — | Owns the diff, the alert routing and the re-approval decision. | Designs the trigger so it fires on capability change rather than configuration change. |
| Deprovision | Requests removal, or the register review finds it disused. | Owns. Revokes the credential at the source. | Confirms revocation happened, not merely that the entry was deleted. | Writes the revocation step into the offboarding and review routines. |
| Evidence at audit | Answers requests about their own server. | Produces the scope and role exports. | Owns the population and the reconciliation. | Prepares the evidence and coordinates the examination. Does not test and does not opine. |
An em dash means that party produces nothing at that step. The structural point is in the fourth row: the credential is minted by the owner of the system being reached, not by the team that wants the integration and not by security. That is what makes least privilege a decision by someone who understands what the scopes mean, and it is the difference between a scope set that matches the tool list and one that matches whatever the vendor documented as the default.
A thirty-day sequence that produces evidence
The common failure is starting with the policy. A policy written before you know what is connected describes an estate you have not seen, and its first audit finding is the gap between the two.
Week one — enumerate. The collection query has two halves. On managed endpoints, have device management search for the per-client JSON configuration files — commonly claude_desktop_config.json for Claude Desktop, .mcp.json at repository roots and a user-level file for Claude Code, .cursor/mcp.json plus its global equivalent for Cursor, and .vscode/mcp.json plus a user-level file for VS Code — and return the file contents, not just a yes or no. Confirm the current paths for your versions before writing the query. These move. On the tenant side, pull connected-application and OAuth grant reports from the identity provider, the connector or maker-portal admin logs, and every major SaaS platform in scope. Ask teams as well, but treat what they tell you as a supplement to what you collected, never as the population. The output is a list of servers, the clients they are connected in, and the credential each is using. Expect the collected list to be longer than the list people describe, and expect at least one credential nobody remembers granting — the gap between the two is the finding, and its size is the argument for doing enumeration before policy.
Week two — tier and triage. Assign a tier to everything on the list. Anything landing at Tier 3 or Tier 4 that has never been reviewed is the week’s work. Tier 0 and Tier 1 get recorded and left alone. Publish the allowlist at the end of the week even if it is short, because an allowlist that exists on day ten shapes behaviour that a perfect one on day ninety does not.
Week three — credentials and baselines. Move anything above Tier 1 off personal tokens onto purpose-created identities, narrow the scopes to the approved tool set, and export the tool manifest for every server on the list using the fields set out above. This is the week that produces the artefacts an assessor will test, and usually the week that surfaces a vendor whose scope set cannot be narrowed — a procurement conversation, not a security one, and better had now.
Week four — monitoring and the trigger. Schedule the manifest diff, route its alert to a named owner, confirm that tool-call logging is on and retains longer than your assessment period, and write the re-approval trigger into the change policy. Only now write the policy, because by this point every clause in it describes something you have actually done.
On effort and cost: for a mid-sized estate this is a few days a week for one owner over the month, plus a short burst from the identity and endpoint teams in weeks one and three — materially cheaper than discovering the estate during fieldwork. ISO 42001 pricing is all-inclusive and indicative: from $4,000 (₹3–3.5 Lakh) for small organisations, $5,000–6,000 (₹4.5–5 Lakh) for growing companies and $8,000 (₹7–10 Lakh) for large enterprises. It includes the accredited certification body’s audit fee. The certificate is issued by that certification body, not by Tranquility Cybersecurity, and the final figure depends on the certification body you choose.
One server, two tools later
An illustrative composite, not a client. A 400-person B2B software company running an enterprise assistant, an ISO 42001 management system in its second year, and an annual SOC 2 Type 2 with a period ending 30 September 2026. Read the June row first — it is the only one that tests anything.
| Request | 3 March 2026 | Support engineering asks for a helpdesk MCP server so the assistant can look up ticket history. The published tool list has four tools, all reads. The requested scopes include ticket write, because the vendor ships one scope set. |
| Approval | 24 March 2026 | Approved as Tier 1 with the scope set narrowed to read at the authorisation server, running under a purpose-created service identity rather than any engineer’s account. The four-tool manifest is exported and attached to the register entry as the baseline. |
| Capability change | 11 June 2026 | The vendor ships an update. The server now advertises six tools: the original four plus close_ticket and issue_refund. The nightly manifest diff alerts the named owner the following morning. |
| Decision | 12–19 June 2026 | The read approval is unaffected because the read credential cannot reach the new tools. The refund tool is assessed as Tier 3 and declined for this deployment, and close_ticket is approved as Tier 2 on a second identity with a confirmation prompt, recorded as a separate register entry. |
| Fieldwork | October 2026 | The assessor selects this server from a population of nineteen. The baseline manifest, the diff alert, the two approval records and the two scope exports reconcile. The June change is evidence that the control worked, not an exception. |
Three cheap moves did the work. The scope narrowing at approval meant that when the vendor added a refund tool, the deployment could not call it — the credential, not the policy, was the control. The exported manifest gave the diff something to compare against, turning an invisible capability change into a dated alert. And splitting the two new tools into separate decisions meant the useful one shipped in a week while the consequential one was declined on its own merits.
Consider the counterfactual, because it is the common case. Had the original approval accepted the vendor’s combined scope set, an assistant used daily by support staff would have acquired the ability to issue refunds on 11 June with no decision, no record and no notification — and the first anyone would have known is when someone asked it to make a customer happy. Nothing in that sequence involves a vulnerability, a breach or a mistake by the vendor. It is a governance gap with a date on it.
The approval described the tool set on 24 March. Nothing in it described the tool set on 11 June. Every MCP approval carries that expiry, and only the ones with a baseline manifest notice.
What the assessor actually requests
Whether the examination is a SOC 2 performed by a licensed CPA firm or an ISO 42001 certification audit performed by an accredited certification body, the shape of the ask is the same and it starts in the same place: not with your policy, but with a population. A sample drawn from a list you assembled by hand proves nothing about the list.
| The request | What satisfies it | Typical selection | What gets rejected |
|---|---|---|---|
| The population of MCP servers in use | A system-generated enumeration — endpoint management or client configuration collection across managed devices, plus the gateway or broker record for remote servers — produced before any sample is drawn, with the query and record count visible. | Not sampled. The population is itself the test: the full list is reconciled to the register, and any variance is explained rather than averaged away. | The approval register offered as the population. It lists what was approved, which is a different set from what is running. |
| The approval record for a selected server | A dated decision naming the requester, the use case, the tier assigned, the tools approved, the scopes granted, the identity used and the approver — someone other than the requester. | A sample drawn from the full server population. For a population under about 40, teams commonly plan for 5–15 items. Where the population is under about 10, expect it to be tested in full. | A chat message saying yes. A ticket where requester and approver are the same account. An approval dated after the server was already in use. |
| Tools as approved versus tools as running | The baseline manifest captured at approval and a current export from the same server, with the diff explained and any addition traced to a re-approval. | The full alert population where the diff fired fewer than about 25 times in the period. Otherwise a sample of alerts, with every one that led to a re-approval traced end to end. | A current tool list with no baseline to compare it to, which proves what the server does today and nothing about the period. |
| The credential and its actual permissions | The granted scope set or role definition from the authorisation server or target system, reconciled to the tools approved. | A two-point test per selected server: one export near the start of the period and one near the end, so scope drift between them is visible rather than inferred. | A screenshot of the consent screen. It shows what was requested at one moment, not what is held now. |
| Evidence of monitoring and human oversight | Tool-call logs for the period showing timestamp, server, tool, principal and the human session. The confirmation prompts recorded for consequential actions. At least one instance where something was declined or investigated. | A defined number of days or sessions per quarter rather than a share of calls — a handful of days per quarter over a 12-month period is a common plan — plus every recorded decline or investigation. | Logs retained for thirty days against a six-month period. A confirmation control described in policy with no record that it ever fired. |
| Deprovisioning | For each removed server, evidence that the credential was revoked at the authorisation server or target system, not merely that the client entry was deleted — with dates. | Usually the full population of removals, because it is small. Where a period produced dozens, a sample of them, reconciled to leaver records and register reviews. | A removal ticket with no revocation evidence behind it. The token is the access. The config file is only the pointer. |
Read the third column as planning figures, not entitlements. Sample sizes are the practitioner’s judgement under the relevant attestation or certification standard — a function of population size, control frequency, automation and risk — not a published table anyone can hold you to. What is durable is the shape: MCP approval and re-approval are event-driven rather than calendar-driven controls, so the selection is drawn from the population of events in the period, which means the population has to be enumerable before a sample is possible at all. The mechanics are set out in SOC 2 sampling and sample sizes.
The completeness argument is where this gets uncomfortable. Your register is management’s assertion about what exists. The auditor wants information produced by a system, which is why the reconciliation between the two is the test rather than either one alone. Where the difference is not zero, the explanation matters more than the number: a reconciliation that finds three unregistered servers and closes them out reads far better than a register that has never been tested against reality.
Log retention is the second trap, and it has the same shape as everywhere else in assurance work: tool-call logs have to retain for longer than the period plus the lag before anyone asks for them, and retention on the platforms involved is usually a plan or edition setting rather than a property of the product. List every log you cite in a control description, write its retention window beside it, and export monthly to your own storage anywhere the window is shorter than the period plus ninety days. On the SOC 2 side the relevant criteria are the familiar ones — CC6.1 to CC6.3 on access, CC6.7 on where information is allowed to move, CC7.2 on monitoring for anomalies, CC8.1 on change, CC9.2 on vendors. On the ISO 42001 side, A.10.3 covers suppliers, A.10.2 the allocation of responsibilities, A.9.2 and A.9.4 responsible and intended use, and A.6.2.8 the recording of event logs.
The cases that generate the real questions
The model above covers the common eighty per cent. These are the situations where a sensible engineering team and a sensible security team genuinely disagree, and where settling the answer in advance saves a fortnight of argument.
The server you did not install
A vendor ships MCP support inside a product you already own, and the capability arrives through a routine product update rather than through your approval process. Nobody made a decision, so nobody recorded one. Two practical controls: add a question to supplier reviews — does this product expose or consume MCP servers, and can we disable that — and make the enablement of an MCP surface in an existing tool a reassessment trigger in its own right. This is the case that defeats a register maintained by asking people what they installed.
The internal server whose author has left
Internal servers are often written in an afternoon by one engineer to scratch one itch, and they accumulate scopes as they grow. When the author leaves, what remains is a running integration with a credential, no owner, no version discipline and no documentation of what its tools do. Treat internally built servers as software with an owner rather than as scripts: a repository, a pinned release, a named owner recorded in the register, and reassignment as a step in the offboarding checklist rather than an afterthought.
The server that is really a proxy
Many servers do not hold data themselves. They front a third-party API, and that architecture is where the confused deputy problem in the risk table above actually lives. The distinction that matters here is directional. If you operate a proxy server, the mitigations named in that row are your obligations and a customer will eventually ask you to evidence them. If you consume one, they are questions for the publisher, and a publisher who cannot answer them has told you something about how the server was built.
Read-only that reads hostile content
The riskiest read-only servers are the ones reading text written by people outside your organisation — inbound mail, support tickets, public issues, scraped pages. The read itself is harmless. The problem is that the returned text lands in a context window next to tools that can act. A read-only ticket server plus a write-capable mail server is a materially different deployment from either alone. Assess the session, not the server.
Local servers on developer machines
Engineers will run servers locally, and mostly should. One specific is worth adding to the stdio point made earlier: a local server bound to an HTTP port can be reachable by other processes on the machine and by browser-based attacks, and the guidance is to prefer stdio, or else to require an authorisation token and restrict the socket to loopback. The governance answer is a curated internal allowlist, no production credentials on endpoints, and secrets held in a manager rather than pasted into a configuration file that a backup or a screen-share will eventually expose.
The personal client outside your tenant
Someone connects an approved internal server to a client running under a personal account, or connects a personal server to a work client. The first exports your data to an identity you do not control. The second imports an unreviewed capability into a session that holds your credentials. Neither is caught by reviewing servers alone. Enforce on the client side too — managed clients, tenant-restricted sign-in, and a policy that names the client as well as the server — and read this alongside shadow AI governance, because the motivation is usually convenience rather than evasion.
Tools are not the only surface
A server can expose more than callable tools. It can publish resources the client may read, and prompt templates a user can invoke, and both put server-controlled text into a context window that also holds your material. A review that inspects the tool list alone understates the surface, sometimes considerably: a server with two innocuous tools and a resource that returns a large body of externally sourced text is a content-injection question, not an action question. Capture what a server exposes across all of its surfaces at approval, and let the tier follow the widest one.
You are the publisher
If your product ships an MCP server to customers, everything above becomes an inbound questionnaire rather than an outbound one. Prepare six things: a published tool list with each tool classified read or write, the rationale for each scope you request, a statement that you validate token audience and do not forward tokens downstream, retention and sub-processor detail for anything the server sees, a changelog for tool additions with a notification path, and a documented revocation route. Publishing those turns a two-week security review into a two-day one, and their absence is increasingly a lost deal rather than a follow-up email.
Where a server ends up in the hands of a coding agent with repository and shell access, the questions change again — see coding agents and production access and coding agents, .env files and secrets.
What gets pushed back on and the answer
Half of these come from your own engineers and half from a customer’s security team. The answers are the same either way, because the underlying question is the same: what exactly did you decide, and what would the record show.
“It authenticates with OAuth, so it is fine.”
Then you have established who is connecting, which is one of four judgements and not the hard one. Ask the person making this argument to state, from the consent screen alone, whether the scopes are minimal, whether the tools do what their descriptions claim, and whether this capability should exist here at all. The screen answers none of the three, because it was never asked to.
“It is marked read-only.”
Tool annotations are declarations made by the server, and the specification is explicit that clients must consider them untrusted unless they come from a trusted server. So a read-only flag is a claim by the party whose trustworthiness is the open question — which is circular, and the circularity is the whole objection. Read it as documentation of intent, useful for understanding what the publisher thinks the tool does, and take your assurance from the credential instead.
“It is open source — we can read the code.”
Someone reading the repository once is not a control, and it is the wrong artefact in any case. What executes is the published package or image at the version your start command resolves — for an unpinned command, whatever was published most recently. Source availability supports a review, but it does not replace pinning, a registry you already proxy and scan, and treating a version bump as a change.
“We already approved the vendor.”
Vendor approval and use-case approval answer different questions, and MCP separates them further still, because a supplier agreement does not enumerate the tools a server exposes or the scopes it will hold. The workable structure is that the vendor decision covers the contract, retention and sub-processors, while the server decision covers the tool set, the credential and the tier. One is renewed annually. The other is re-opened whenever capability changes.
“This is just an API integration. We have done those for years.”
The mechanics are familiar, but two properties are not. The caller is a model choosing which tool to invoke from a description, so the selection logic is probabilistic rather than coded, and it can be influenced by content the model reads during the session. And the capability set is discovered at runtime and may change without a deployment on your side. A conventional integration does exactly what its code says until someone ships a release. That is the gap the review has to cover.
“A review process will just push people to install things quietly.”
That is the correct risk to worry about, and it is a design constraint rather than an argument against governance. If every server needs a committee, the register becomes fiction within a month — which is what the tier model exists to prevent. The commitment that matters is a published turnaround you will actually meet, because a review with a stated two-day floor gets used and one with an unstated queue gets bypassed.
“Our client prompts the user before every tool call, so we are covered.”
Confirmation is a real control and the specification asks for it — there should always be a human able to deny a tool invocation, and clients are advised to show the tool inputs before the call is made. It stops being a control when it fires on everything, because a prompt that appears forty times a day is answered by reflex. Make it selective: no prompt for reads, a prompt showing the actual arguments for anything that writes, and a harder confirmation for anything irreversible or externally visible. Then check the record for at least one instance where somebody declined — a control that has never once said no has not been tested.
“We will simply block MCP.”
That is a legitimate position for a narrow estate — a regulated environment with a small approved tool set and no developer population — and it is honest only when three conditions hold. You can enforce it technically on managed devices rather than by policy alone. You can detect the capability arriving inside a product you already licence, because that is how it will arrive. And you have somewhere for people to take the work they were trying to do, because a block without an approved path produces personal accounts rather than compliance. Where those do not hold, a tier model with a fast self-service floor governs more of the estate than a prohibition does.
Frequently Asked Questions
What is an MCP server, in governance terms rather than technical ones?
Is OAuth enough to approve an MCP server?
How do I know a server is really read-only?
Should read-only and write-capable servers be approved separately?
What happens when a server adds new tools after we approved it?
Can we let engineers install MCP servers themselves?
Does listing in the official MCP Registry mean a server has been vetted?
What are the biggest MCP-specific security risks to plan around?
How should MCP servers be authorised — per user, or centrally?
What evidence will an auditor ask for on MCP governance?
Related reading: approving MCP tools and handling capability change, prompt injection once tools are connected, when a tool becomes an AI agent, building an AI system and agent inventory, vendor approval is not use-case approval, the ten questions that govern any AI agent, and the ISO 42001 hub.
Tranquility Cybersecurity advises on AI governance design, builds the register and approval machinery described here, prepares the evidence, and coordinates the examination. ISO/IEC 42001 certificates are issued by accredited certification bodies and SOC reports by licensed CPA firms. TCSA does not certify, attest, audit or sign.
Related Reading
Approving MCP Tools and Handling Capability Change
Read-only search and destructive admin actions must not share a blanket approval.
Read morePrompt Injection Once Tools Are Connected
Injection stops being a content problem and becomes an action problem. The controls that reduce blast radius.
Read moreAI Agent Identity and Delegated Authority
Human authority and authority-to-delegate are different things. Why agents need their own identity.
Read moreThe Ten Questions That Govern Any AI Agent
Scope, ownership, data, capability, identity, oversight, failure detection, evidence, reassessment and how to stop it.
Read moreISO 42001 Knowledge Hub
AIMS controls, EU AI Act mapping, risk assessment and guides.
Read moreISO 42001 (AI Management)
The world's first AI management system standard, for AI builders.
Read more