Claude Code Security: How to Protect Your Tool Calls
Claude Code Security: How to Protect Your Tool Calls
Claude Code is a capable development assistant. It can read and write files, run shell commands, search codebases, call external APIs, and interact with any MCP server you have configured. That breadth of access is what makes it useful. It is also what makes the security posture of your Claude Code deployment worth thinking carefully about.
This post covers what the attack surface actually looks like, what the CVE findings in the MCP SDK mean for Claude Code specifically, and how to enforce policy on every tool call before it reaches the servers Claude Code is configured to talk to.
What Claude Code Actually Does When It Calls a Tool
When you give Claude Code a task, the model reasons about which tools it needs and issues tool calls to the MCP servers in its configuration. Each tool call is a structured request — a tool name and a set of arguments — that the MCP server receives, executes, and returns a result for.
From the MCP server's perspective, a tool call from Claude Code is indistinguishable from a tool call from any other MCP client. The server does not know whether the instruction came from a well-formed user request, a confused model, or a prompt injection embedded in a file Claude Code was asked to read. It executes the call and returns the result.
This is the fundamental property that makes MCP call-layer security necessary: the authority boundary is at the call layer, not at the model layer. By the time a call reaches the MCP server, the decision to make it has already been made.
The Attack Surface: Which MCP Servers Does Claude Code Reach?
Claude Code reads its MCP server configuration from a project-level config file on startup. Any server listed in that configuration is reachable from every task Claude Code runs in that project.
In practice, developers tend to configure MCP servers for the tools they use most — filesystem access, code search, GitHub, web fetch, and so on. The cumulative tool surface across even a modest set of MCP servers can include reading arbitrary files, making network requests, executing shell commands, and pushing code to remote repositories.
The question worth asking is: for the task you are running right now, how many of those tools actually need to be reachable? If you are running a documentation task, does Claude Code need access to the tool that pushes to GitHub? If you are doing a code search, does it need web fetch?
The answer is usually no, and the gap between what is configured and what is needed is the attack surface.
The CVE Problem: @modelcontextprotocol/sdk Has 3 HIGH CVEs
As of May 2026, @modelcontextprotocol/sdk — Anthropic's Node.js SDK for MCP, which underlies the majority of MCP servers Claude Code connects to — carries 3 HIGH-severity CVEs. The vulnerability classes are:
ReDoS (Regular Expression Denial of Service): Certain input patterns cause the SDK's regex-based parsing to enter catastrophic backtracking, consuming CPU proportional to input length and potentially causing the server to become unresponsive. An attacker who can influence what Claude Code reads and passes to an affected tool can trigger this path.
DNS rebinding: The SDK's HTTP transport is vulnerable to DNS rebinding attacks, where an attacker-controlled domain resolves first to an external IP (bypassing same-origin checks) and then to a local address. This allows attacker-controlled web content to make requests to locally-running MCP servers as if it were a trusted client.
Cross-client data leak: A session management flaw allows data from one MCP client session to leak to another. In multi-tenant or multi-session deployments, this can expose context from one agent's session to a different agent.
The mcp Python SDK carries 3 HIGH CVEs in the same vulnerability families. Together, these two packages affect 54–68% of the MCP ecosystem. npm audit in CI will flag the Node SDK findings; pip-audit will flag the Python SDK findings. Both checks should be in your CI pipeline.
Where patches are not yet available, runtime enforcement provides a compensating control — policy and detection rules can block the call patterns that would exploit these vulnerabilities even before the underlying CVEs are patched.
How Navil Wraps Claude Code's MCP Config
Navil works by wrapping your existing MCP server configuration. When you run navil secure, it reads your MCP config file, inserts itself as a proxy in front of each configured server, and writes an updated config that routes all tool calls through the Navil enforcement layer before they reach the server.
Claude Code and Cursor use different config file paths. Claude Code maintains its own configuration; Cursor stores MCP server config in ~/.cursor/mcp.json. navil secure auto-discovers both config paths and wraps them independently. You do not need to specify which client you are using — the discovery is automatic.
After wrapping, the workflow is unchanged from Claude Code's perspective. It starts, reads its config, and connects to the same MCP servers it was connected to before. The difference is that every tool call now passes through the Navil proxy, where it is evaluated against your policy before reaching the server.
pip install navil
navil secure
# Navil discovers claude code and cursor configs automatically
# Completes in ~47 secondsWriting a Policy for Claude Code
Policy is defined in navil.yaml at the root of your project. A minimal policy for a Claude Code development workflow that needs code search, file read, and test execution but should not be making external network requests or pushing to remote repositories:
# navil.yaml
policy:
allow:
- tool: search_codebase
- tool: read_file
scope: "./**"
- tool: run_tests
- tool: write_file
scope: "./src/**"
deny:
- tool: "*"
default: trueKeep the allowlist narrow. If a task requires a tool that is not in the policy, Claude Code will return a policy-blocked error rather than silently failing, which makes it immediately obvious that the policy needs updating rather than leaving the agent to attempt workarounds.
Policy enforcement adds 2.7 µs overhead per message at p50 and 6.1 µs at p99. For a development workflow where tool calls take tens to hundreds of milliseconds to execute, the enforcement overhead is not measurable in practice.
The 94% schema token reduction from policy scoping has a secondary benefit for Claude Code specifically: a smaller tool surface means the model's context is less crowded with tool descriptions it will never use, which tends to improve the quality of tool selection for the tools that remain.
Monitoring Claude Code in Production
"Production" for Claude Code typically means an automated pipeline — a CI workflow, a scheduled agent run, or an agent triggered by external events rather than a human at a keyboard. In these contexts, there is no human watching the terminal output, and a misbehaving agent can run for a long time before anyone notices.
Navil logs every tool call — allowed and blocked — with the tool name, arguments (redacted according to your log policy), the policy decision, and a timestamp. For automated Claude Code deployments, pipe these logs to your existing observability stack. Alerts on blocked calls are particularly useful: a burst of policy blocks in an automated run usually means either the agent is encountering an unexpected situation or something in the input has changed in a way that is pushing the model toward calls it should not be making.
Navil's detection layer evaluates each call against 568 patterns across 36 categories. For Claude Code pipelines, the most relevant categories are prompt injection indicators — which fire when the content being processed contains patterns consistent with an attempt to redirect the model's behavior — and data exfiltration patterns, which fire when the call structure matches known patterns for moving data to external destinations.
The starting point is the same two commands regardless of which client you are securing:
pip install navil
navil secureFor the Claude Code-specific integration details — how config discovery works, how to scope policy per-project versus globally, and how to handle multi-server configurations — see the Claude Code section of the integrations page. The quickstart covers the general setup flow in under five minutes.
Enforce policy on every tool call
Navil wraps your MCP servers in under 60 seconds — no changes to agent code. 568 detection patterns, 2.7 µs overhead.