Reviewing an MCP Server’s Permissions Before You Connect It to Claude Code

Military cyber operators working at computer stations during a cyber defense exercise

Before connecting a new MCP server to Claude Code, walk through what permissions it’s actually asking for, where its credentials live, and whether it runs sandboxed — not just whether the install command looks legitimate. An MCP server is arbitrary code with access to your tools and, often, your files; the review below turns that into a concrete ten-minute check instead of a gut feeling.

Why This Needs a Checklist, Not a Vibe Check

The official Model Context Protocol specification is blunt about the risk: MCP “enables powerful capabilities through arbitrary data access and code execution paths,” and it puts the burden of safety entirely on the people implementing and installing servers, not on the protocol itself. The spec’s own security section states that “hosts must obtain explicit user consent before invoking any tool” and that tool descriptions and annotations “should be considered untrusted, unless obtained from a trusted server.” That second point is easy to miss: a malicious or compromised server can write a tool description that looks completely reasonable while the tool itself does something else. Reading the package name isn’t review. Reading what the server can actually touch is.

The OWASP MCP Security Cheat Sheet turns those principles into something closer to an audit list, and the walkthrough below follows its structure, adapted for someone connecting a server to Claude Code specifically rather than building one.

Step 1: Confirm the Source Before You Touch the Install Command

Start with the publisher, not the package. Check who maintains the server, whether the npm or PyPI package name matches the project’s actual GitHub repository, and whether the name is close enough to a popular server’s name to be typosquatting it. This takes thirty seconds and catches a meaningful share of malicious servers before you’ve run a single command.

Step 2: Read Every Tool Definition, Not Just the README

Open the server’s source and read each tool’s parameter schema and return schema, not only its one-line description. A server that exposes a “search_files” tool but accepts an arbitrary shell string as one of its parameters isn’t a search tool — it’s a shell. OWASP’s guidance here is specific: treat all tool inputs as untrusted, since they can come from LLM output shaped by malicious context, and favor tools that use a strict JSON Schema with additionalProperties: false and pattern constraints on string fields, which limits what the model (or a prompt-injected document) can actually pass through.

Step 3: Check What Credentials It’s Asking For, and How Narrow They Are

Look at the OAuth scopes or API key permissions the setup instructions request. A server that only needs to read calendar events shouldn’t be asking for a token with write access to your entire email account. Prefer servers that support short-lived, per-server credentials over ones that want a long-lived personal access token you’d also use elsewhere — a compromised server with its own narrow token is a contained incident; a compromised server holding your general-purpose token is not.

Step 4: Decide Whether It Needs Local or Network Access at All

Local MCP servers that talk to Claude Code over stdio avoid opening a network listener, but that alone doesn’t restrict what the process can read on disk or reach over the network — OWASP’s cheat sheet is explicit that stdio transport “does not itself restrict file, network, or credential access.” If a server only needs to read a specific project folder, it shouldn’t have unrestricted filesystem access, and if it doesn’t need the internet to do its job, it shouldn’t have it. For a remote server instead, confirm it’s served over TLS and that the client validates the server’s identity rather than trusting whatever responds on the configured URL.

Step 5: Isolate Anything That Touches Money, Auth, or Personal Data

Don’t connect a payments server, an auth provider’s admin API, or anything holding personal data in the same Claude Code session as a general-purpose or experimental server. If one of the general-purpose servers turns out to be compromised or simply misbehaves under a confusing prompt, isolation is what keeps that incident from reaching the sensitive one. This is also where the permission-mode settings covered in our dontAsk CI walkthrough matter: the broader the auto-approval scope you’ve configured, the more this isolation step is doing the actual protective work, since fewer prompts will stop and ask first.

Step 6: Read the Consent Prompt Before You Click Through It

The MCP specification puts this requirement on the host application directly: “Hosts must obtain explicit user consent before invoking any tool,” and “Users should understand what each tool does before authorizing its use.” In practice this means actually reading the full tool-call parameters Claude Code shows you the first few times a new server’s tools fire, not just the tool name. A tool named update_record that you expected to touch one field but that’s actually sending the entire record payload is something you only catch by reading the call, not the label.

Step 7: Decide What Happens When the Server Updates

A server you reviewed carefully on day one can change its tool definitions on day forty without you noticing, unless your client re-prompts for consent when that happens. OWASP’s pre-connection checklist flags this directly: confirm the client will re-prompt for consent if tool definitions change, and prefer setups that pin reviewed tool definitions with a cryptographic hash covering the full definition — input schema, output schema, and annotations — so a silent change is detectable rather than invisible. If you’re not sure whether your setup does this, treat every server as if it could change behavior without warning, and periodically re-read the tool list for anything you’re actively using.

It’s also worth logging what you can. OWASP recommends logging tool invocations with their parameters and timestamps, with secrets and personal data redacted from the log itself. For a solo developer this doesn’t need to be elaborate — even a local log of which tools fired and roughly what they touched gives you something to check against if a server starts behaving strangely, instead of trying to reconstruct events from memory.

FAQ

Does Claude Code enforce any of this automatically? Claude Code’s permission system controls which actions require your approval versus which run automatically, but the protocol-level guarantees described above — narrow credentials, sandboxing, pinned tool definitions — are the responsibility of the server you’re connecting and how you’ve configured it, not something the client can verify on its own. The review in this post is what fills that gap.

Is a local, stdio-based server automatically safer than a remote one? No. It removes one category of risk — a network listener an attacker could reach directly — but, as the OWASP cheat sheet points out, stdio transport doesn’t itself limit what the process can read, write, or reach on the network. A local server with broad filesystem access and outbound internet access can do as much damage as a poorly secured remote one; it’s just a different attack surface, not a smaller one by default.

The Checklist, Compressed

CheckWhat you’re confirming
SourcePublisher is known, package name matches the real repo, no typosquatting
Tool schemasParameters are narrow and typed, not free-form strings that act as a shell
CredentialsScoped, short-lived, per-server — never a token reused across tools
Sandbox / networkNo unrestricted filesystem access; no internet access unless the tool needs it
Sensitive isolationPayment, auth, and PII-handling servers run separate from general-purpose ones
Consent promptsYou read full tool-call parameters, not just the tool name, before approving

What This Looks Like Next to Reviewing AI-Generated Code

This review sits upstream of two checklists we’ve covered before. Once an MCP server is connected and trusted, Claude Code can use it to write code, and that code still needs the same scrutiny as anything else AI-generated — see our checklist for reviewing an AI-generated GitHub Actions workflow for what changes when the output runs in CI rather than locally. And because a connected MCP server is one of the things a tool description itself can misrepresent, it’s worth applying the same skepticism from our piece on writing tool descriptions Claude won’t misread in the other direction: a vague or overly broad tool description on a server you didn’t write is itself a yellow flag, not just a readability problem.

Common Mistakes

  • Approving the first few tool calls on autopilot. The first several calls from a new server are exactly when you should be reading parameters closely — that’s when you’re least familiar with what “normal” looks like for this tool.
  • Treating a popular GitHub star count as a security review. Popularity tells you a server is widely used, not that its current published version is safe; supply-chain compromises happen to popular packages too.
  • Granting filesystem access to the whole home directory because scoping it to one project folder felt like extra setup work.
  • Running a sensitive-data server and an experimental server in the same session because switching configurations is mildly annoying.

Featured image: U.S. Air National Guard photo by Staff Sgt. Laura Virtue, public domain, via Wikimedia Commons.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top