Most MCP security advice stops at “here are the risks.” That’s the easy half. The hard half, the part that actually keeps a production deployment safe, is deciding who gets to call which tool, with which parameters, under whose authority, and who checks that afterward. This article covers both halves, using the current Model Context Protocol (MCP) specification revision 2026-07-28 as the protocol baseline.
One thing up front, because it shapes everything that follows: MCP is a connection protocol, not a security product. It defines how a host application, a model, and a set of tool-exposing servers talk to each other. It does not ship a policy engine, a secrets manager, a sandbox, or an incident-response process. Those are things you build. This article treats that distinction as the organizing idea, not a footnote.
What this article does not claim: it does not declare one transport universally safer than another, it does not report an ecosystem-wide incident rate, and it does not assume every MCP client implements the same consent or isolation behavior. Where the evidence is a practitioner’s personal account rather than a verified fact, that’s stated explicitly.
Quick Takeaways
Click any topic to expand or collapseProtocol Scope vs. Security Features
MCP defines the wire protocol between hosts, models, and tool servers ā it does not automatically supply consent UI, sandboxing, secrets storage, or policy enforcement.
Granular Tool-Level Permissions
Permissions belong on individual tools and actions, not on entire servers. A single “approved server” can still contain a destructive, unscoped tool.
HTTP Authorization Profile (MCP 2026-07-28)
HTTP authorization in MCP 2026-07-28 is an OAuth 2.1-based profile with PKCE, resource indicators, and mandatory audience validation ā and it is optional at the protocol level.
UI Transparency vs. User Consent
A user clicking “Approve” is not the same as authorization. If the UI can’t show the real parameters and destination, the click means less than it looks like.
Demo vs. Production Controls
The riskiest pattern in the research is treating a demo integration as a finished production control. Governance, audit, and revocation are usually retrofitted, not designed in from day one.
What MCP Actually Is, in One Definition
Model Context Protocol (MCP) is an open protocol that lets a host application connect a language model to external tools, data resources, and prompts through a standardized client-server interface, according to the official MCP architecture specification. A host (the application a person uses, such as an IDE or chat client) manages one or more clients, each of which holds a single connection to one server. Servers expose tools (callable actions), resources(readable data), and prompts (reusable templates) to the model, through the host.

That architecture puts three separate trust decisions in play every time a tool call happens: does this server deserve to be connected at all, does this specific tool deserve to run with these specific parameters, and does the downstream system on the other end of that tool call agree to do what’s being asked. MCP standardizes the conversation. It does not make any of those three decisions for you.
MCP is the interaction layer between model, host, and tool server, production security still depends on identity, permission, and downstream authorization that you design separately.
Map the Trust Boundaries Before You Choose Controls
Security teams that jump straight to a risk checklist tend to bolt controls onto the wrong layer. Before picking tools or policies, draw the boundaries. The official MCP architecture documentation and the protocol’s security best-practices guidance describe six places where untrusted input can cross into a trusted decision.
| Boundary | Typical untrusted input | Failure if ignored | Independent control |
|---|---|---|---|
| User / identity | Issuer, tenant, scopes, redirect URI, consent state | Wrong principal acts, or a confused-deputy request slips through | Issuer, audience, and resource validation; per-client consent |
| Host / model | User text, tool descriptions, resource content, tool results | Prompt injection or an unsafe action gets proposed | Provenance labeling; a policy layer that sits outside the model; human approval for high-impact actions |
| Transport / gateway | Origin header, metadata URLs, session or state handles | Server-side request forgery, misrouting, cross-tenant mix-ups | Origin/TLS/auth checks; egress policy; complete mediation at every hop |
| Server / tool | Tool schemas, dependencies, update channels, local process | Poisoning, remote code execution, data exfiltration | Provenance registry, signed digests, sandboxing, schema validation |
| Downstream resource | The actual API, file, or database request | Unauthorized action or data leak, regardless of what the model intended | Last-hop authorization enforced by the resource itself |
| Operations | Logs, package versions, alerts | No accountability trail, no way to recover from an incident | SIEM ingestion, redaction, rollback plans, a written incident playbook |
Local stdio servers and remote Streamable HTTP servers change which of these boundaries matter most, not whether they matter at all. A stdio server inherits the client process’s privileges directly; a remote server adds network exposure, Origin validation, and (usually) OAuth. Neither pattern is categorically safer, the MCP transports specification and its Streamable HTTP definition describe different exposure surfaces, not a safety ranking.
(outside the model)
stdio or Streamable HTTP
file, or database
Conceptual diagram, not a wire-protocol trace. The model proposes an action; policy, server-side authorization, and the downstream resource each independently decide whether it happens.
Draw the six boundaries first. Controls chosen without this map usually end up protecting the wrong hop.
Offline Architecture Pack: MCP Threat Matrix & Trust Boundaries
Keep the 6 trust boundaries, permission tuple formulas, and OAuth verification flow as a printable reference sheet. No sign-up or email required.
Build Permissions Around Tools and Actions, Not Server Names
Here’s the uncomfortable insight the community research keeps landing on: “we approved this server” is not a permission model. One detailed self-reported account on r/mcp, from a builder describing work across several MCP integrations, put it plainly, once you’re past a couple of servers, the pain isn’t connecting them, it’s answering who can call which tool, with credentials scoped how, approved by whom, and audited where (r/mcp thread).
That’s one practitioner’s experience, not a measured industry statistic, but it matches the structural gap in the protocol itself: MCP tells you a tool exists and what its schema looks like. It has no opinion on whether this identity should be allowed to call this tool with these arguments right now.
The fix is a permission tuple that treats the tool call as the unit of authorization, not the server connection:
actor ā client/agent ā server ā tool ā action ā resource ā parameters ā environment ā approval ā audit identity
This is a deployment policy model, not a feature MCP hands you. You enforce it in the host, a gateway, or the tool wrapper, wherever your architecture puts a decision point between “model proposes” and “system executes.” The idea connects directly to non-human identity design; see this walkthrough of delegated authority and revocation for non-human identities for how to scope and revoke the credentials an agent actually uses.
Not every tool deserves the same scrutiny. A read-only lookup and a “delete customer record” tool shouldn’t clear the same bar:
| Tier | Examples | Minimum control |
|---|---|---|
| Read | Query public or already-authorized internal data | Narrow scope, resource-level authorization, audit logging |
| Sensitive read | PII, credential-adjacent metadata, confidential documents | Field-level minimization or masking, explicit resource policy, audit |
| Write | Create or update records, modify code | Separate capability grant, typed input validation, approval scaled to impact |
| Destructive | Delete, revoke, modify infrastructure | Independent authorization, explicit confirmation or dual control, rollback/idempotency |
| External side effect | Send email, publish content, transfer data, call an arbitrary destination | Destination allowlist, data-loss-prevention checks, full action preview before approval |
| Privileged administration | IAM changes, secrets, tenant configuration | Separate identity, step-up authentication, dual control, immutable audit trail |
This is an editorial heuristic for prioritizing review effort, built from the risk tiers above ā it is not a measured industry benchmark or an MCP protocol feature. Use it to triage, not to certify a deployment as safe.
Authorize the tool call, not the server. A permission tuple bound to actor, action, and resource closes the gap that server-level approval leaves open.
Implement HTTP Authorization Without Confused-Deputy or Token-Passthrough Errors
When MCP does use authorization, it’s HTTP-specific, and it’s built on a real OAuth 2.1 profile, not an ad hoc scheme. The MCP authorization specification states that authorization is optional at the protocol level, and when it’s used, an MCP server acts as an OAuth resource server and the MCP client acts as an OAuth client.
Note the qualifier: for stdio transport, the specification says clients should obtain credentials from the environment rather than following this HTTP-oriented flow, the two transports do not share one authorization story.
What Is the MCP OAuth 2.1 Authorization Flow?

A compliant HTTP authorization flow runs through six steps:
- The client discovers the server’s protected-resource metadata, per RFC 9728, which points to the correct authorization server.
- The authorization server publishes its own metadata under RFC 8414 or OIDC discovery, exposing endpoints and supported PKCE methods.
- The client sends an authorization request that includes the RFC 8707 resource parameter, a PKCE challenge (using S256 when the server supports it), and an exact, pre-registered redirect URI; the MCP authorization security considerations require all three.
- In proxy or dynamic-client-registration topologies, the authorization server obtains per-client consent, identifying the specific client, scopes, and redirect URI, before forwarding authorization, rather than reusing one static upstream client ID for every downstream client.
- The resource server validates the returned token’s issuer, audience/resource, expiry, scopes, and tenant before honoring any request. A resource parameter in the request is not proof the token was actually checked; the validation step still has to happen.
- When the MCP server itself needs to call an upstream API, it uses a separate upstream credential rather than the token it just received, the next section explains why that step is non-negotiable.
- Client ā discovers protected-resource metadata from the MCP resource server
- Resource server ā returns the authorization-server metadata URL
- Client ā sends authorization request: resource parameter + PKCE + exact redirect URI
- Authorization server ā shows the user a per-client consent screen naming scopes and redirect
- User ā approves
- Authorization server ā returns an authorization code, after issuer/state checks
- Client ā exchanges the code plus PKCE verifier plus resource parameter for a token
- Authorization server ā issues an audience-bound token
- Client ā sends the MCP request with that token
- Resource server ā validates issuer, audience/resource, expiry, scope, tenant ā then calls the upstream API using a separate, distinct credential (never the inbound MCP token)
Conceptual sequence based on the official MCP authorization and security-considerations pages. Exact implementation varies by SDK and identity provider.
What Is Token Passthrough in MCP, and Why Is It Dangerous?

Token passthrough happens when an MCP server accepts the token a client sent it and forwards that same token, unchanged, to an upstream API instead of minting or holding a separate upstream credential. The MCP authorization security considerations explicitly prohibit this.
It matters because a token issued for one resource server was never validated for the upstream service’s audience, forwarding it collapses two separate trust decisions into one, which is the textbook definition of a confused-deputy vulnerability.
It also wrecks your audit trail: the upstream system now sees the MCP server’s token instead of the identity that actually made the request, so you lose the ability to say who did what. The fix is architectural, not a configuration flag: the MCP server must act as its own OAuth client toward the upstream API, using credentials scoped to itself.
Common MCP OAuth Anti-Patterns and How to Fix Them
The same source material maps out six specific ways this flow breaks in practice, worth checking against your own architecture:
| Anti-pattern | Why it fails | Corrected pattern |
|---|---|---|
| Static upstream client ID shared by every MCP client | Consent granted for one client can be silently reused by another | Register and bind client identity; obtain per-client consent |
| Wildcard or loosely matched redirect URI | An authorization code can be redirected somewhere the user didn’t intend | Require exact, pre-registered redirect matching |
| Accepting any syntactically valid bearer token | A token minted for a different resource or tenant still “looks” valid | Validate issuer, audience/resource, expiry, scope, and tenant explicitly |
| Forwarding the received MCP token to an upstream API unchanged | Breaks the trust boundary and destroys audit-identity accuracy | Mint or hold a separate upstream token/credential |
| Treating a session or state handle as proof of identity | A handle can be replayed or mixed across tenants if it isn’t bound to a principal | Bind opaque, high-entropy, expiring handles to the authenticated principal |
| Relying on prompt text to express authorization | Model-generated text is not a policy decision | Enforce authorization at the host, gateway, server, or downstream resource ā never in the prompt |
Note on the state-handle row: MCP 2026-07-28 uses a stateless-first, per-request metadata model rather than the session-based behavior in earlier revisions. The MCP security best practices treat a session or state handle as an ordinary application argument, not a protocol-level authentication mechanism, so possession of a handle proves nothing on its own.
OAuth correctness in MCP comes down to five checks, resource parameter, PKCE, exact redirects, full token validation, and never forwarding a token upstream. Skip one and you’ve reopened confused deputy.
Treat Tool Metadata and Model Context as Untrusted Input
This is where the contrarian point in this article lives, and it’s worth stating directly because most guides soften it: a human clicking “Approve” does not make an action authorized. It’s a necessary control, not a sufficient one. Approval only works when the interface shows the effective tool name, the real parameters, the destination, and the side effects, and when a downstream system still checks authorization independently. If a poisoned tool description hides what a call actually does, the click means far less than the UI implies.
This isn’t speculation. Invariant Labs documented a specific tool-poisoning technique where a malicious MCP server embedded hidden instructions inside a tool’s description field, text the model reads but a typical approval UI never surfaces to the user. The tool still passed a human-in-the-loop approval step, because the human was never shown the part that mattered.
Case Study: The Invariant Labs Tool-Poisoning Disclosure

- What happened: A researcher demonstrated that MCP tool descriptions, plain metadata fields, not code, can carry instructions a model will follow, invisible to a user who only sees the tool’s name and a short summary.
- Why it happened: The MCP specification itself warns that tool annotations should be considered untrusted unless they come from a server you’ve established as trustworthy, but many client UIs at the time did not surface full tool descriptions or parameters during approval.
- Outcome: The disclosure pushed client builders and the OWASP GenAI Security Project to formalize tool/schema poisoning as its own attack category, OWASP MCP03:2025, with recommended controls: provenance checks, metadata diffing, and runtime revalidation.
- Lesson for readers: Approval workflows need to render the effective action, full tool description, resolved parameters, and destination, not just a tool name, or the approval step is theater.
What Is Prompt Injection and Tool Poisoning in MCP?

This connects to two well-documented, related risks. Direct and indirect prompt injection, as defined by OWASP’s LLM01:2025 guidance, can alter model behavior through content the model reads, a tool result, a fetched document, a resource. OWASP is explicit that there is no foolproof prevention; mitigations reduce impact, they don’t guarantee safety.
Tool and schema poisoning, per OWASP MCP03:2025, extends the same idea to the tool’s own schema, description, or manifest, including “rug pulls,” where a tool’s behavior changes silently after it was reviewed and approved.
How to Prevent MCP Tool Poisoning: Layered Controls That Help

What actually helps (layered, not any single fix):
- Provenance and integrity ā pin server endpoints, validate TLS, and prefer signed or reviewed manifests over unverified listings.
- Metadata diffing ā alert when a previously approved tool’s description, schema, or declared side effects change.
- Full-context approval ā show the resolved parameters and destination, not a truncated tool name.
- Output sanitization and typed schemas ā validate tool inputs and outputs against a strict schema rather than trusting free text.
- Least privilege at the tool level ā scope credentials so that even a manipulated call can’t reach beyond its intended blast radius.
If your architecture also does retrieval, the same untrusted-input logic applies to documents, not just tools, see this piece on document-level access control in RAG for why semantic relevance is never the same thing as authorization to read a document.
Layered controls reduce the impact of prompt injection and tool poisoning. None of them, alone or combined, is a guarantee, design as if a bypass is possible, because the evidence says it is.
Harden Local and Remote Execution Differently
Local and remote MCP servers don’t fail the same way, so they don’t harden the same way either. Treat the two as separate threat models rather than one generic “lock it down” checklist.
How to Sandbox Local stdio MCP Servers

Local stdio servers run as a subprocess the client launches directly. That has one real advantage, no network exposure by default, and one real cost: the official security guidance is direct that a local server can execute with the client’s own privileges. An untrusted or compromised local server is not automatically sandboxed just because it’s local. Recommended controls include:
- Running the server in a container, microVM, or restricted process rather than directly on the host.
- Granting minimal filesystem access, a fixed workspace root, not the full user directory.
- Restricting network access to only the destinations the tool actually needs.
- Running as a non-root identity with restricted syscalls where the platform supports it.
- Keeping ambient credentials out of the process’s environment variables unless that specific tool needs them.
How to Secure Remote Streamable HTTP MCP Servers

Remote Streamable HTTP servers add a different set of obligations. The Streamable HTTP specification requires servers to validate the Origin header and return HTTP 403 for an invalid one, and recommends binding local instances to loopback rather than 0.0.0.0. Origin validation is not authentication, though it stops some cross-origin abuse, not unauthorized access from a legitimate origin.
A remote server also needs its own egress restrictions, tenant-aware routing, and cancellation handling, since it can be reached by more than one client at once.
Preventing SSRF, Path Traversal, and Resource Exhaustion in MCP

Both transport types share a real risk during discovery and authorization: server-side request forgery. A client or authorization server that fetches attacker-controlled metadata URLs, redirect targets, or discovery documents can be tricked into reaching internal services, cloud metadata endpoints, or localhost.
The OWASP SSRF prevention guidance recommends validating every hop, blocking private IP ranges, checking redirect targets, and pinning DNS resolution,Ā an allowlist alone is not a complete defense.
Two more runtime concerns deserve explicit controls rather than being folded into “sandboxing” generally:
- Path traversal ā any tool that touches a filesystem needs canonicalized paths, a fixed workspace root, and opaque resource identifiers rather than raw paths from user or model input, per OWASP’s path traversal guidance.
- Resource exhaustion ā rate limits, timeouts, recursion or fan-out ceilings, and response-size limits, since an agent loop can call a tool far more aggressively than a human ever would.
Local and remote MCP servers fail differently, privilege inheritance versus network exposure, so harden each against its own actual threat model instead of applying one generic “sandbox everything” answer.
Operate a Governed Server and Tool Supply Chain

Why Ungoverned MCP Server Adoption Creates Security Risk
The demo-to-production gap shows up most clearly here. A second Reddit account, a poster identifying as a network engineer with an enterprise security background, described watching a company accumulate roughly a dozen and a half MCP server integrations with no visible record of who approved each one or what data it could reach, until they found data flowing to a poorly vetted third-party server (r/cybersecurity thread).
This is worth stating plainly: it’s a single, second-hand anecdote, not an audited incident report, and it should not be read as a rate or a typical outcome. But it illustrates a structural failure mode that shows up across the research, integrations get added faster than governance catches up.
Case study: ungoverned MCP adoption, as one practitioner described it
- What happened: MCP servers were connected incrementally, each one solving an immediate problem, with no central record of ownership or scope.
- Why it happened: Nothing in the protocol forces an inventory step, connecting a new server is as easy as adding a config entry, and that ease outpaces most teams’ existing change-management process.
- Outcome (self-reported, not independently verified): The account describes eventually discovering that internal data was reaching a server that hadn’t been through security review.
- Lesson for readers: Treat “connect a new MCP server” as a change that requires the same intake process as adding a new third-party API integration, because functionally, that’s what it is.
How to Vet and Govern MCP Servers Before Deployment
A governed supply chain answers a fixed set of questions for every server before it ships, and again before every update:
- Who owns this server, and what’s its documented business purpose?
- What data classification and side-effect classification apply to its tools?
- What version or digest is pinned, and is there an SBOM or dependency scan on file? (See CISA’s SBOM guidanceand the NIST Secure Software Development Framework for the underlying supply-chain controls.)
- Has the tool’s scope been reviewed against the permission tiers above?
- Does an update trigger a metadata diff and a staged rollout rather than an automatic pull?
- Is there a tested rollback and an emergency revocation path?
- Is there a decommissioning step, so an unused server doesn’t sit around as a live credential holder?
Before vs. After: What a Governed MCP Supply Chain Looks Like
Before: servers get added ad hoc, credentials live in whatever config file was fastest, nobody can list which tools exist across the estate, and an update ships without anyone noticing the tool’s description changed.
After: every server has a named owner and a data/side-effect classification on file, tool scopes map to the risk tiers above, updates go through a metadata diff before rollout, and there’s a tested one-command way to disable a server the moment something looks wrong.
The failure mode isn’t a missing firewall rule, it’s treating server intake as a two-minute config change instead of a reviewed supply-chain decision.
Make Audit and Incident Response Actionable
MCP does not define an audit schema. The MCP tools specification says clients should log tool usage, that’s guidance, not a wire-format standard, and it leaves the actual schema to you. NIST SP 800-92 gives the broader process context for enterprise log management: what to collect, retain, and protect.

A workable event should carry enough to reconstruct what happened without becoming a second attack surface itself:
JSON ā Redacted MCP Audit Event Example:
{ "timestamp": "2026-09-12T14:03:11Z", "correlation_id": "req_8f2a1c", "actor": { "principal_id": "svc-agent-142", "tenant": "acme-prod", "auth_issuer": "https://idp.example.com" }, "client": "internal-support-agent", "server": "billing-mcp-server", "tool": "issue_refund", "tool_version": "2.3.1", "action": "write", "resource": "invoice:INV-88214", "parameters_hash": "sha256:9c2e...redacted", "policy_decision": "approved_with_dual_control", "approval": { "required": true, "approved_by": "human_reviewer_042" }, "destination": "internal:billing-api", "result": "success", "downstream_identity": "svc-billing-writer" } Notice what’s absent: no bearer token, no authorization code, no API key, no raw customer PII in the event itself, only a hash of the parameters and a resource reference. The MCP authorization security considerations are explicit that stored, cached, or logged tokens can be stolen just like any other credential. A log line that leaks a secret has turned your audit trail into a new incident.
For incident response itself, MCP has no built-in lifecycle, that’s a deliberate limitation to state plainly rather than gloss over. NIST SP 800-61 Revision 3 is the current general-purpose framework, covering preparation, detection, response, and recovery woven through ongoing risk management rather than treated as a one-off checklist.
On top of that general framework, an MCP-specific playbook needs concrete, rehearsed steps: disable the affected server, revoke its tokens, rotate any credential it could have touched, roll back to the last known-good tool schema, preserve evidence before you start cleanup, and where customer data was involved, a notification decision made in advance, not improvised mid-incident.
Connect this to your broader agent-verification approach; harness engineering for reliable AI agents covers independent verification and safe interruption patterns that pair naturally with an MCP kill switch.
Log enough to reconstruct a decision, actor, tool, version, action, resource, policy outcome, and never enough to leak a secret. Build the incident lifecycle yourself; MCP won’t supply one.
Choose a Deployment Pattern Without Pretending There’s One Right Answer
Once an estate grows past a handful of servers, teams start asking whether to connect directly or route through a centralizing layer. There’s no universal winner here, each pattern trades one kind of risk for another, and cost, latency, and uptime numbers aren’t something this research can responsibly quantify without vendor-specific benchmarking.
| Pattern | Strengths | Costs / risks | Best fit |
|---|---|---|---|
| Direct connection | Simple path, fewer moving parts | Policy, inventory, and audit end up fragmented across every client | Small, tightly controlled deployments |
| Gateway / control plane | Central identity, policy, routing, inventory, and audit in one place | A concentrated point of failure, plus routing and log-privacy trade-offs | Multi-server enterprise estates |
| Sidecar | Enforcement lives close to each individual server | Operational sprawl; keeping policy consistent across sidecars takes discipline | Teams that need per-workload isolation |
| Service mesh / network layer | Uniform transport and network-level controls | Doesn’t replace tool-level or downstream authorization ā it’s a different layer entirely | Organizations with existing platform networking to extend |
A gateway centralizes governance at the cost of a concentrated dependency; direct connections stay simple but fragment audit and policy. Pick based on estate size and existing platform investment, not on a universal claim that one pattern is safer.
Common Mistakes and How to Avoid Them
These recur across the official guidance, the threat research, and the practitioner accounts cited above:

Approving a server once and never revisiting it
A tool’s description or schema can change on update; without metadata diffing, an approved server can quietly become a different, unreviewed one.
Trusting a session or state handle as identity
Under MCP 2026-07-28’s stateless-first model, a handle is an ordinary argument. Bind it to an authenticated principal, or treat it as untrusted.
Logging the wrong things
Full request/response logging that includes bearer tokens or raw tool arguments turns an audit trail into an exposure. Redact before you store.
Assuming local means safe
A stdio server inherits client privileges; “it’s not on the network” says nothing about whether it can read your filesystem or environment variables.
Passing the MCP token upstream unchanged
This is the single most explicit prohibition in the specification’s security considerations, and it’s also one of the easiest mistakes to make when wiring up a quick integration.
Treating human approval as the finish line
If the UI can’t show the effective action, approval is a formality, not a control.
Skipping the downstream check
Even a perfectly authorized MCP call still needs the receiving API, database, or file system to independently enforce its own authorization, MCP correctness upstream doesn’t substitute for that.
Related Concepts Worth Connecting
MCP security doesn’t sit in isolation. If your agents also retrieve documents, the authorization logic has to extend to enterprise RAG security architecture and access-control lists, a tool call that fetches a document is still subject to the same last-hop-authorization principle as a database write.
If you’re building browser-facing agent tools rather than backend servers, don’t conflate the two threat models; see WebMCP and browser-bound tool security for how origin and consequential-action controls differ in that context.
And if your organization operates under the EU AI Act, the audit fields described above map directly onto the kind of oversight and logging evidence regulators expect to see, though that’s a governance-evidence connection, not legal advice.
For the broader threat-model context this article sits inside, see this agentic AI security and enterprise risk guide.
Release-Gated Verification Checklist
Use this before calling any MCP deployment production-ready. Each item needs an owner, a test, and evidence on file, a checkbox without evidence isn’t a control.
0 of 13 complete
The Bottom Line
MCP gives you a clean way for a model to reach tools and data. It does not give you a finished security posture that still has to be designed, one trust boundary at a time.
Scope permissions to the tool and action, not the server. Get the OAuth details right, especially the resource parameter, PKCE, and the no-token-passthrough rule. Treat every tool description and every approval click with appropriate suspicion, and back both with downstream authorization that doesn't depend on the model having gotten anything right. Do that, and "approval is not authorization" stops being a warning and starts being the design principle that actually holds the system together.
MCP behavior is version-sensitive: this article uses the 2026-07-28 protocol revision, and specific mechanics ā especially around transports, sessions, and authorization discovery ā differ from earlier revisions. Security properties described here depend on the specific host, client, server, SDK, identity provider, and downstream resource in your deployment; they are not guarantees that apply automatically to every implementation. Community accounts cited here (the Reddit threads) are individual, self-reported experiences, not measured incident rates or population-level evidence. Recheck all version-sensitive claims against the live specification and your deployed SDK versions before publishing.
Includes the complete 13-point production release gate, redacted SIEM JSON schema samples, and the emergency revocation playbook. Instant 1-click download.
Frequently Asked Questions about MCP security
What is MCP security, exactly?
It's the set of controls surrounding the Model Context Protocol connection between a host, a model, and tool-exposing servers ā since the protocol itself defines the interaction pattern but not the trust, consent, sandboxing, or policy decisions around it. Those are deployment responsibilities.
Does MCP use OAuth 2.1?
For HTTP transports, yes ā the 2026-07-28 authorization specification is built on an OAuth 2.1 draft, with PKCE, resource indicators, and discovery. Authorization is optional at the protocol level, and stdio transport follows a different path: obtaining credentials from the environment rather than this HTTP flow.
Does MCP require user approval before every tool call?
Hosts must obtain explicit user consent before invoking tools, and the spec recommends confirming and displaying sensitive operations ā but MCP does not mandate one specific approval UI. Implementation quality varies by client, which is why the article treats approval as necessary, not sufficient.
Why is token passthrough dangerous?
Forwarding a token issued for the MCP server on to an upstream API breaks audience validation and audit-identity accuracy ā a classic confused-deputy pattern. The authorization security considerations require a separate upstream credential instead.
Are local stdio MCP servers safer than remote servers?
Not categorically. Stdio avoids network exposure but inherits the client's privileges directly; remote Streamable HTTP servers add network and Origin-validation surface but usually bring OAuth with them. Compare the actual threat model for your deployment rather than assuming one transport wins by default.
How should an enterprise authorize MCP tools?
Bind permission to actor, client, server, tool, action, resource, parameters, environment, approval, and audit identity ā and enforce that at the host, gateway, or downstream resource, since MCP itself doesn't provide a universal policy engine.
Can prompt injection or tool poisoning be fully prevented?
No. OWASP's own guidance is explicit that there's no foolproof prevention for prompt injection. Layered controls ā provenance, metadata diffing, full-context approval, output sanitization, least privilege ā reduce impact; they don't eliminate the risk.
What should MCP audit logs contain?
Actor and tenant identity, the authenticating issuer, client and server/tool version, the action and target resource, the policy decision and approval status, a correlation ID, the result, and the downstream identity used ā with tokens, authorization codes, API keys, and raw secrets explicitly excluded.
Was this article helpful?










[…] For a practical application of these identity and authorization boundaries to MCP servers, tool-level permissions, OAuth flows, and production controls, see our guide to MCP security and enterprise hardening. […]
[…] through an MCP tool: semantic relevance or tool visibility does not establish authorization. The MCP security guide explains how to bind tool calls to identity, resource scope, downstream authorization, and audit […]
[…] tool, arguments, resource, and tenant before an MCP server reaches a downstream system. See our MCP security guide for the corresponding tool-calling and enterprise-hardening […]
[…] tool descriptions, arguments, results, and downstream side effects all cross trust boundaries. Our MCP security guide maps those boundaries to tool permissions, OAuth validation, audit logging, and enterprise release […]
[…] The same distinction applies to MCP itself: exposing a structured tool does not decide whether a principal may invoke it, what arguments are allowed, or whether the downstream resource should execute the request. For the broader server, OAuth, and tool-permission model, see our MCP security and enterprise hardening guide. […]
[…] tool permissions, OAuth boundaries, audit events, and tested disablement procedures. Our MCP security guide provides a deployment-focused checklist for these […]