LetterMCP

Unauthorized MCP Tool Calls and Audit Trail Requirements

Enterprises lack visibility into AI tool calls because MCP was built for convenience, not security.

Staff Writer · · 12 min read
Cover illustration for “Unauthorized MCP Tool Calls and Audit Trail Requirements”
Agent Security · September 11, 2026 · 12 min read · 2,736 words

Unauthorized MCP tool calls are the fastest-growing blind spot in enterprise AI security, and the reason is structural: the Model Context Protocol was never built with an audit trail in mind. That gap matters more every month, because MCP isn't a developer novelty anymore. It's load-bearing infrastructure now, with servers already wired into production environments across many organizations.

Here's the basic setup. MCP is a client-server protocol. A host, say Claude Desktop, Cursor, or some internal orchestration platform, connects to one or more MCP servers, and each server exposes a set of tools, resources, and prompts the model can call. That sounds a lot like a REST API on paper, but it isn't one in practice. With a REST API, a developer decides which endpoint gets hit and when. With MCP, the model itself picks the tool, builds the arguments, and decides the moment to fire, all without a human in the loop at execution time.

Underneath all of that sits JSON-RPC 2.0, a messaging format that's easy to extend and simple to reason about, but comes with no built-in authentication or encryption by default. So every hop in the chain, from user to AI host to MCP client to MCP server to whatever system sits downstream, carries an assumption about identity, consent, and scope that nothing in the protocol actually enforces. This wasn't an oversight patched quietly after launch. MCP got built for integration convenience first. Enterprise security came later, if at all.

What makes a tool call unauthorized, a working definition

Four separate conditions can turn a tool call unauthorized, and each needs a different kind of detection. Of the four, intent drift is the one that should worry security teams most, because it produces a call that looks completely clean at every checkpoint and is wrong anyway.

The first is identity failure: the agent isn't who, or what, it claims to be. Maybe the credential was stolen. Maybe it got shared across five different agents. Maybe it was never scoped to this particular task in the first place.

The second is scope violation. Here the credential is real and valid, but the agent uses it to call a tool or touch a resource outside what that credential was ever meant to cover.

The third is intent drift, and it's the hardest to catch. The call sits entirely within the credential's scope, but it serves an attacker's goal instead of the user's. Nothing about the token is wrong. The agent itself got manipulated. At every layer the call looks legitimate: valid token, correct tool, plausible-looking arguments. The only thing wrong is the instruction that triggered it, and that instruction came from a malicious payload, not the user sitting at the keyboard.

The fourth is the approval gap, sometimes called the rug pull condition. A tool gets approved once, at connection time. Later, its definition or behavior changes, silently, and no new approval flow ever triggers. Traditional access control assumes a tool's definition stays fixed once it's authorized. MCP tool definitions are mutable at runtime, which is a genuinely new kind of problem, not a variation on an old one.

Shared credentials make every one of these four categories worse. When multiple agents authenticate through the same service account, there's no way to trace behavior back to a specific agent or a specific user. The log shows the account. It doesn't show who delegated the task or which agent actually pulled the trigger.

The attack classes that produce unauthorized tool calls in practice

Prompt injection is the one most people have heard of by now. Hidden instructions get buried in an email, a document, or a tool's output, and they redirect the agent's behavior without the user ever knowing. Stored prompt injection is the nastier cousin, working a lot like stored XSS in web security: a malicious prompt gets saved in a database somewhere and fires later, whenever the agent processes a request that touches it. That can escalate privileges, pull data out, or trigger tool calls nobody asked for. Automated pipelines that consume prompts on their own, with no human review step, sit especially exposed.

Tool poisoning works differently, and it deserves more attention than it usually gets, because it doesn't require tricking a user at all. Malicious instructions get embedded directly in a tool's metadata, invisible to anyone looking at it by eye, but read and treated as authoritative by the model. An analysis of 1,899 open-source MCP servers, documented by Knostic, found that 5.5% had tool-poisoning vulnerabilities. Invariant Labs showed the real-world stakes in April 2025: a single poisoned tool description pulled out SSH private keys and local config files with zero user interaction, and a companion demo grabbed WhatsApp message histories the same way. A separate proof-of-concept the following month showed private repository contents leaking out through GitHub's MCP server. Research from the Cloud Security Alliance put attack success rates above 60% across more than 45 real-world MCP servers tested. In every one of these cases, the call sat entirely inside the agent's credential scope. Only the intent was wrong.

Rug pull attacks exploit the approval gap directly. A server that looked legitimate at connection time quietly changes its tool definitions afterward, and nothing in the MCP specification forces a re-approval when that happens. CVE-2025-54136 documented exactly this in Cursor IDE's MCP tooling: a tool's behavior could change after initial authorization without triggering a new approval flow. The authorization decision that got made no longer matches the tool that's actually running.

Tool shadowing takes this further, and it's the one that breaks the "just review each server carefully" instinct. A poisoned tool description can change how the agent behaves toward other, completely trusted servers, meaning the attacker never has to get the user to invoke the malicious tool at all. A 2026 report from Practical DevSecOps documented a cross-server cascade rate of 72.4% when multiple MCP servers were compromised in the same environment. One bad server spreads unauthorized behavior across an entire connected mesh, which is why per-server review alone isn't enough.

Server impersonation adds a supply chain angle. An attacker swaps out a legitimate server in the registry, and agent traffic starts flowing to an endpoint the attacker controls instead. Shadow MCP servers, the ones some developer stands up fast to unblock a demo and never registers or vets, are usually where this starts. Research cited by datasciencedojo.com identified 492 publicly exposed MCP servers lacking basic authentication or encryption altogether.

Then there's the plain old code execution problem. A survey from mcpmanager.ai found 43% of tested MCP servers allowed command injection, 22% had arbitrary file read through path traversal, and 30% were open to SSRF. Enkrypt AI scanned 1,000 MCP servers in October 2025 and found 33% carried critical vulnerabilities. CVE-2025-6514, an OAuth flaw in mcp-remote, allowed command injection through crafted OAuth metadata and sat undiscovered through more than 437,000 downloads before anyone patched it.

Why the protocol's authentication gaps make every category worse

The original MCP spec shipped with no mandatory authentication framework at all. Local servers connecting over STDIO rely on the host process's trust boundary, with no mandatory agent-level authentication required by the original specification.

Things have moved since then, some, but not evenly. The March 2025 spec update made OAuth 2.1 Authorization Code flow with PKCE mandatory for remote MCP server connections, and servers are now treated as OAuth resource servers that check tokens rather than issue them. November 2025 added step-up authorization: a server can respond with a 403 and a WWW-Authenticate header carrying a scope parameter when it needs higher permissions. That's a real fix, but only where teams actually turn it on, and adoption isn't universal. The Enterprise-Managed Authorization extension lets organizations centrally provision MCP server access through an identity provider, and Anthropic, Microsoft, and Okta are among those adopting it, alongside a growing list of MCP servers. Plenty of the ecosystem still hasn't caught up.

Underneath all of that sits a credential sprawl problem that's genuinely staggering. GitGuardian's State of Secrets Sprawl 2026 report found 28,649,024 new secrets exposed on public GitHub in 2025 alone, a 34% jump year over year. AI-service credentials specifically jumped 81.5%. In MCP configuration files specifically, GitGuardian found 24,008 unique exposed secrets in the protocol's first year of widespread adoption. And finding a leak isn't the same as fixing it: per GitGuardian data cited by devfortress.net, 64% of credentials confirmed leaked back in 2022 were still active and exploitable as of January 2026, four years after anyone found them.

Put plainly, the authentication gaps mean MCP has no native way to tell an authorized call from an unauthorized one. That distinction has to get rebuilt after the fact, from logs. Audit trail design isn't a nice-to-have here. It's the main compensating control, arguably the only one that works across every attack class at once.

What a complete audit trail for MCP tool calls must actually contain

Traditional application logs weren't built for this. They'll tell a security team who authenticated and which endpoint got called, but they say nothing about the chain of delegation behind it: which agent acted, on whose behalf, triggered by which prompt, using which version of a tool's definition, touching which downstream system.

MCP changes the audit question itself, and this is the part most logging setups get wrong: they still ask who did what, when the real question has two more parts to it. When an action comes from an AI agent's own decision rather than a direct human click, the log also has to capture why the call happened (the prompt or context that triggered it) and whether the tool definition at the moment of execution actually matched what got approved.

A defensible MCP audit record needs several things at once:

  • Identity chain: user identity tied back to SSO or the identity provider, plus agent identity, MCP client identity, and MCP server identity. All four, not just whichever credential happened to authenticate.
  • Tool call specifics: tool name, server endpoint, the full argument payload, timestamp, and transport type, whether that's a local or remote transport.
  • Tool definition snapshot: a fingerprint or hash of the tool's description at the exact moment it got invoked. This is the only real way to catch a rug pull after it's already happened.
  • Authorization context: OAuth token scope, token lifetime, when step-up authorization was required, and when the credential got issued.

Beyond those fields, the log needs the triggering context itself, meaning the prompt or input that actually led to the call. Without that, there's no way to tell intentional user delegation apart from prompt injection. It needs the result too: what the tool returned, what systems downstream got touched, whether any data left the environment, and a clear read on the outcome, whether the call completed, got blocked by policy, or produced something anomalous.

None of this works if the logs can be touched by the very agent or server being audited. Records have to land in a store the agent can't reach, full stop. And because a single user session can span multiple tool calls across multiple servers, every record needs a shared correlation identifier so the full session can get pieced back together later. Distributed tracing tooling gives teams the technical foundation to do exactly that.

How incomplete logging has played out in confirmed incidents

The consequences of skipping any of this aren't hypothetical. Take the PocketOS incident: a Cursor AI agent deleted an entire production database in 9 seconds after stumbling on a broadly scoped token in a codebase it was never assigned to search in the first place. Nine seconds doesn't leave room for a human to step in. That's exactly why pre-execution controls matter so much, and why post-execution reconstruction ends up being the only investigative path left once something like that happens.

Then there's the Supabase Cursor agent exploit from mid-2025. Researchers showed that an agent operating with privileged service-role access could be manipulated into exposing sensitive integration tokens. Without a log of the triggering context, there's genuinely no way to prove the leak came from a prompt injection rather than just a badly written query. Without a log of the triggering context, there's genuinely no way to prove the leak came from a prompt injection rather than just a badly written query.

The TeamPCP and LiteLLM supply chain compromise is another data point worth sitting with. A malicious package backdoored roughly 47,000 machines, and it sat live on PyPI for something like 40 minutes before anyone caught it. Every tool call made during that window, by any agent using the compromised dependency, counts as suspect. Without tool-definition fingerprinting baked into the audit record, there's no way to know afterward which calls were actually poisoned and which weren't.

The scale problem shows up again in the OX Security MCP CVE cluster: multiple CVEs disclosed together, affecting more than 200,000 vulnerable server instances. Responding to an incident at that scale means being able to query logs by server identity and tool definition version, not just by whichever user account happens to show up.

The pattern across all of these cases is the same. Thin telemetry from MCP servers and agents makes real investigation next to impossible. Token theft, command injection, prompt injection: none of it shows up without proper logging in place. The absence of a log doesn't mean nothing happened. It means nothing can be proven, and that gap got official weight in June 2026, when security advisories have listed structured audit logging on every MCP server connection as an immediate required step, alongside OAuth 2.1 enforcement and tool-description fingerprinting. A regulator is now saying logging isn't optional. It's a control, the same as encryption or access management.

The governance program that turns logging into a repeatable control

None of the logging fixes above mean much if the environment itself is a mystery. An audit trail is only as complete as the server inventory behind it, and shadow MCP servers, the unregistered, unvetted ones someone spun up fast to unblock a demo, generate calls that never show up in any log at all. Building a full inventory, classifying every server as local or remote, and pulling unvetted instances out of production has to come before instrumentation, not after. Get the order backward and the logging program is auditing half the environment while calling it complete.

Tool definition fingerprinting belongs at the proxy layer. Any change to a tool's definition after its initial registration should get flagged, logged, and blocked before it ever reaches the agent. That's what makes rug-pull detection possible after the fact, and prevents it before the fact.

Credential architecture needs to actually support attribution. That means per-task, short-lived credentials, expiring in minutes rather than months, issued through a proper secrets manager. When a credential's scope gets violated, the violation is detectable precisely because the scope was narrow enough to have a real boundary. Shared service accounts make that kind of detection impossible by design, and no amount of logging fixes a boundary that was never drawn in the first place.

Identity has to run through the existing identity provider, whether that's Okta, Azure AD, or Google Workspace, so the extension ties MCP server access back to organizational identity management. The Enterprise-Managed Authorization extension is the mechanism for this. Without it, agent actions float free of whoever actually delegated the task.

Auto-approval needs to come off in production. A tool approved once at connection time can't stay treated as permanently authorized forever after. Policy enforcement has to happen at the level of each individual tool call, not just once at connection, and that's the control that finally closes off the approval-gap category for good.

Guidance from the OWASP MCP Top 10 framework, referenced in a UltraViolet Cyber advisory from May 2026, recommends quarterly red-team exercises aimed specifically at agentic workflows. The threat surface here moves faster than any static policy can keep pace with, so testing whether the audit trail actually catches the attacks it's supposed to catch is part of the job, not an optional extra.

Get all of this right, and security and IT teams stop being the department that says no to AI adoption. They become the reason it's possible at all. Audit and governance, done properly, are what let the rest of the organization run agents safely. They aren't the brakes. They're the reason the car can move at speed in the first place.

Sources

  1. The state of MCP security in 2025: Key risks, attack vectors, and case studies
  2. MCP Security Issues and Best Practices You Need to Know
  3. Threat Advisory: MCP Threats
  4. MCP Tool Poisoning: Adversarial Hijacking of AI Agent Workflows
  5. practical-devsecops.com
Filed underAgent Security

More in Agent Security