On this page
  1. What should you enumerate first?
  2. How do you assess the credentials it holds?
  3. How do you check what it can reach?
  4. How do you keep it audited after approval?
  5. Where AI coding assistants get this wrong
  6. Checklist
  7. FAQ
    1. Are local MCP servers safer than remote ones?
    2. How do I know if a tool is read-only?
    3. Should the agent see every tool a server exposes?
    4. What belongs in the audit record?
  8. Related topics
  9. Sources
tutorial

How to Audit an MCP Server Before You Connect It

Check what the server exposes, what credentials it holds, where it can reach, and whether you can see what it did. Then pin it.

Quick answer

  • Audit four things: the tools it exposes, the credentials it holds, the network it can reach, and the logs it produces.
  • A tool that can write is a different risk class from one that can read; enumerate both before connecting.
  • Check how the server is launched: a local process inherits your user permissions, a remote server holds its own credentials.
  • Pin the version or image digest, because a server that updates silently can change its tool list after approval.
  • Test with a scoped token and read the server’s logs during a real call.

What should you enumerate first?

The tool list, with each tool’s arguments and side effects. A tool named query that accepts arbitrary SQL is a database console; a tool named update_issue writes to a system of record. The name describes intent, the arguments describe capability.

Then the resources and prompts the server exposes. Resources can include files and configuration; prompts can carry instructions the agent will follow. Both are input to the model and both need review.

# Inspect a local MCP server config before trusting it
cat ~/.config/agent/mcp.json 2>/dev/null || cat .mcp.json 2>/dev/null
# What will it run, with which credentials?
grep -RInE 'command|args|env|token|key|secret' .mcp.json ~/.config/agent/mcp.json 2>/dev/null
# Pin what you reviewed (example: container image by digest)
docker image inspect ghcr.io/example/mcp-server:1.4.2 --format '{{index .RepoDigests 0}}'

How do you assess the credentials it holds?

A local server launched as a subprocess inherits your environment and your user permissions, so a token in your shell profile is available to it. A remote server holds credentials on its side, which means you are trusting its operator as well as its code.

Either way, ask what the token can do. A read-only token for the repository being queried is a different risk from an organisation-wide admin token. If the server needs write access, check whether the tools expose that write capability to the model.

How do you check what it can reach?

Look at the network calls it makes: the base URL, whether it can reach arbitrary hosts, and whether it proxies requests for the model. A server that accepts a URL from the model and fetches it is an SSRF surface, not just a tool.

For local servers, run it in a container or with a restricted network policy and watch the connections. That is the empirical check, and it catches endpoints the documentation does not mention.

How do you keep it audited after approval?

Pin the version or the image digest, record the tool list in the repository, and treat an update as a new review. Servers change their tools between releases, and an added write tool is a capability change nobody approved.

Keep the logs. A server that does not log its calls cannot be investigated after an incident, and an agent incident is exactly when you need to know which tool ran with which arguments.

Where this bites vibecoders

An assistant asked to connect a service will paste a config with npx -y some-server and a personal token. That is an unpinned, auto-installed process with your permissions. Replace it with a pinned version and a scoped token before the first call.

Where AI coding assistants get this wrong

  • Connecting a server without reading its tool list.
  • Using a personal token instead of a scoped service credential.
  • Running an unpinned package with auto-install enabled.
  • Assuming read-only because the name sounds read-only.
  • Ignoring a server that fetches model-supplied URLs.
  • Approving an update without diffing the exposed tools.

Checklist

  • List every exposed tool and its arguments.
  • Classify each tool as read, write, or execute.
  • Check the credentials and their scope.
  • Test what the server can reach on the network.
  • Pin the version or image digest.
  • Confirm the server logs its calls.

FAQ

Are local MCP servers safer than remote ones?

Different, not automatically safer. A local server inherits your permissions and can read your files, but its code is visible and you control the host. A remote server holds its own credentials, but you cannot inspect what it does with them.

How do I know if a tool is read-only?

Read the implementation or the schema, not the name. Check whether the tool accepts a write intent, whether it calls a mutating API, and whether it can delete. If you cannot tell, treat it as write-capable.

Should the agent see every tool a server exposes?

No. Expose the subset the task needs. A server with fifty tools gives the model fifty choices, most irrelevant, and one of them may be able to delete something. Narrow the exposed set where the harness supports it.

What belongs in the audit record?

Server name and version, the tool list at approval, credential scope, network reach, and who approved it. Store it with the repository configuration so the next person can tell what changed when the server updates.

Sources

Share: