DEV Community

Claude code
Claude code

Posted on

Claude Code MCP Servers Are an Attack Surface — Here Is How to Scope Them

Claude Code MCP Servers Are an Attack Surface — Here Is How to Scope Them

Claude code MCP server security is the discipline of configuring, scoping, and monitoring the Model Context Protocol servers that extend Claude Code's tool capabilities — preventing prompt injection, over-privileged tool access, and unauthorized filesystem or network operations that can occur when untrusted content reaches an MCP-enabled agent session.

MCP was designed to solve a real problem: Claude Code, on its own, has a bounded set of built-in tools. MCP servers let teams plug in custom capabilities — database queries, internal APIs, CI/CD triggers, file processors — without patching the agent runtime. That extensibility is valuable. It is also exactly the kind of open-ended surface that attackers look for.

This article is not a theoretical threat model exercise. It is a practical guide to what MCP servers actually expose, where the injection vectors are, and how to cut the blast radius before you ship Claude Code into a production workflow.

How MCP Servers Extend Claude's Tool Surface

The Model Context Protocol lets external processes advertise tools to Claude Code over a local or remote transport. When a session starts, Claude discovers available MCP servers and their tool schemas. From that point forward, Claude can invoke those tools as naturally as it calls any built-in capability — read a file, query a database, post a webhook.

The default MCP configuration in many team setups registers servers globally, which means every Claude Code session inherits the full tool set regardless of what the user is working on. A developer running Claude Code to review a pull request description inherits the same database write tool that was registered for the migration assistant. That is not a hypothetical misconfiguration — it is the default behavior if you do not explicitly scope servers to contexts.

Each registered MCP server increases the number of capabilities Claude can exercise autonomously. A session with five MCP servers — filesystem, database, Slack, GitHub, and an internal API — gives a single agent the ability to read source files, execute SQL, send messages, push commits, and call internal endpoints. Individually, those are useful. Combined in one unconstrained session, they represent a wide lateral movement surface if the session is compromised or manipulated.

Claude Code MCP Server Security: Prompt Injection in Practice

Prompt injection is the most documented attack class against MCP-enabled agents. The mechanism is straightforward: an attacker embeds instructions inside content that Claude will read during a task. When Claude processes that content, the embedded instructions are interpreted as legitimate directives, and Claude executes them — including calling MCP tools the user never intended.

A concrete example: a developer asks Claude Code to summarize a third-party library's README. That README contains a hidden comment block instructing Claude to call a registered MCP filesystem tool and exfiltrate .env files to a remote endpoint. Claude reads the README, encounters the instruction, and — absent explicit guardrails — may follow it.

This attack class is not speculative. CVE-2025-59536, disclosed in 2025, documented a sandbox escape vector in Claude Code that demonstrated how tool invocation could be triggered through manipulated input. Separately, researchers at Invariant Labs published findings in late 2025 showing that MCP tool calls could be hijacked via document-embedded instructions across multiple agent frameworks, with Claude-based agents among those tested. The attack surface is real and has been demonstrated in controlled conditions against production configurations.

The injection can arrive through any content Claude reads: code comments, markdown files, web pages fetched via a browsing tool, database records returned from a query, or even log files. Any MCP server that reads external content and surfaces it to the agent session is a potential injection delivery path. For a deeper look at how these vectors interact with Claude's permission model, see our coverage in the Claude Code blog.

Principle of Least Privilege Applied to MCP Configuration

The core fix is the same one that applies to any over-permissioned system: give each session only the tools it actually needs for the task it is performing.

In practice, this means moving away from a single global MCP configuration and toward context-specific profiles. Claude Code supports per-project configuration via .claude/settings.json. Use it. A project that only needs filesystem access and a linter tool should not have a registered database MCP server, regardless of what else is configured at the user level.

For MCP servers that do need filesystem access, scope the allowed paths explicitly. Most MCP filesystem servers support path restriction parameters — configure them to the project root or the specific directories the task requires. A Claude Code session processing files in /projects/app/src should not have an MCP filesystem server with access to /.

Network-capable MCP servers require the same treatment. If an MCP server needs to call one internal API endpoint, configure it to reach only that endpoint. A broad "call any HTTP URL" tool is a data exfiltration vector waiting for an injection trigger. Some teams use an allowlist proxy in front of MCP network tools — all outbound calls from the MCP server route through it, and only pre-approved domains pass. That pattern adds one hop but significantly reduces blast radius.

Disable any MCP servers that are not actively used. It sounds obvious, but teams that set up MCP servers during development frequently leave them registered in production profiles. Audit your claude_desktop_config.json and project-level settings files regularly. Every unused server is an attack surface with no upside.

For a full breakdown of how Claude Code's permission model interacts with tool scoping, the Claude Code documentation covers the settings schema in detail, including how project-level overrides interact with user-level defaults.

Audit and Monitoring Hooks for MCP Tool Invocations

Scoping reduces the attack surface. Monitoring catches what slips through.

Claude Code exposes hooks in its settings that fire before and after tool calls — PreToolUse and PostToolUse. These hooks execute shell commands, which means you can pipe every MCP tool invocation to a logging system, an anomaly detector, or a simple audit file. A PreToolUse hook on MCP filesystem tools that logs the requested path, the current session context, and a timestamp gives you a complete record of what the agent accessed and when.

More aggressively, a PreToolUse hook can block tool calls that match suspicious patterns. A script that checks whether the requested path is outside the project directory and exits with a non-zero code will cause Claude Code to abort that tool call. This is not a replacement for proper path scoping at the MCP server level, but it is a useful second layer.

For teams running Claude Code in shared or multi-user environments, centralized log aggregation for MCP tool calls is not optional — it is how you catch injection attempts that succeed past the first line of defense. Forward hook logs to your SIEM. Alert on MCP calls that write to paths outside expected directories, make network requests to domains not on your allowlist, or occur outside normal working hours for a given user.

At CLaude Code, we build our runtime guardrails product specifically around this monitoring layer — giving security teams visibility into agent tool invocations without requiring them to manually audit every Claude Code session. The CLaude Code product overview covers how hook-based monitoring integrates with existing security tooling. The attack surface MCP creates is manageable, but only if you can see it.

What a Hardened MCP Configuration Looks Like

Pull it together into a concrete checklist. A hardened MCP setup for a production Claude Code deployment has these properties:

  • MCP servers registered per-project, not globally, using .claude/settings.json in each repository

    • Filesystem MCP servers configured with explicit path allowlists scoped to the project root
    • Network MCP servers routing through an allowlist proxy with a fixed set of approved domains
    • No MCP servers registered that are not actively required by the project's Claude Code workflows
    • PreToolUse hooks logging every MCP invocation with path, tool name, session ID, and timestamp
    • Anomaly alerts on MCP calls that access paths outside expected directories or contact unapproved network destinations
    • A review process for any new MCP server registration, equivalent to a code review for infrastructure changes

None of this is exotic. These are standard least-privilege and audit patterns applied to a newer attack surface. The teams that get burned are the ones who treat MCP configuration as a developer convenience setting rather than a security boundary.

Frequently Asked Questions

Can a malicious document cause Claude to call an MCP tool without the user prompting it?

Yes. This is the documented prompt injection scenario. If Claude Code reads a file, webpage, or data record that contains embedded instructions directing Claude to invoke a tool, Claude may execute that instruction as if it came from the user. CVE-2025-59536 and the Invariant Labs research (2025) both demonstrated variants of this. The mitigations are scoping tools narrowly so injection has less to trigger, and running PreToolUse hooks that can block anomalous calls before they execute.

Is there a way to whitelist which MCP tools can access the filesystem?

Yes, at two levels. First, most MCP filesystem server implementations accept a path restriction parameter in their configuration — set this to the specific directories the server is allowed to read or write. Second, Claude Code's PreToolUse hook fires before any tool call executes. A hook script that validates the requested path against an allowlist and returns a non-zero exit code will block the call. Using both together gives you defense in depth: the server itself rejects out-of-scope paths, and the hook catches anything that slips past misconfigured server parameters.

How do I restrict which MCP servers Claude Code can call?

Use project-level .claude/settings.json to register only the MCP servers that specific project needs. User-level configuration at ~/.claude/claude_desktop_config.json sets defaults, but project settings can restrict or override them. The safest pattern is to register no MCP servers at the user level by default, and opt each project into exactly the servers it requires. That way a new project with untested MCP servers does not automatically inherit production database tools from a developer's global config.

Can MCP prompt injection be blocked at the protocol level?

Not currently. The MCP protocol itself has no mechanism to distinguish legitimate tool call requests from injected ones — that distinction has to happen at the application level, either through Claude's own judgment or through pre-call hooks. Some teams sandbox the content-reading phase (e.g., have a separate, tool-free agent session summarize documents, then pass the summary to the MCP-enabled session) to reduce injection surface. That architectural pattern adds latency but meaningfully separates untrusted content from the tool-capable session.

What is the safest MCP server configuration for production?

No MCP servers registered unless explicitly required. For servers that are required: filesystem access scoped to specific paths, network access routed through an allowlist proxy, and every tool invocation logged via PreToolUse and PostToolUse hooks. Run a quarterly audit of registered MCP servers across all project configurations to remove any that are no longer actively used. Treat MCP server registration as you would a firewall rule change — require justification and review before adding.

Does using Claude Code in auto-accept mode make MCP injection worse?

Significantly. Auto-accept mode removes the human confirmation step that would otherwise catch an unexpected tool call before it executes. If an injection triggers an MCP tool call in a session running with --dangerously-skip-permissions or equivalent auto-accept configuration, there is no prompt for the user to review. The call executes immediately. For any session that involves reading external content — documents, web pages, third-party data — auto-accept mode with broad MCP tool access is a high-risk combination. Scope MCP servers tightly before enabling auto-accept, and use hooks as a programmatic safety layer in place of the removed human review step.

Top comments (0)