Home » Auditing an MCP Server Before Connecting It

Auditing an MCP Server Before Connecting It

2 comments
A closed black instrument case floats inside a metal inspection ring, with a plain circular token outside it.

Before connecting an MCP server, establish who operates or distributes it, where its code runs, what credentials it receives, what each exposed tool can do, and how to revoke the connection. Then verify those claims in a restricted test environment before granting useful access.

The audit should produce a decision about a specific server version, endpoint, host configuration, and permission set. “Supports MCP” describes interoperability. It does not establish trustworthy code, appropriate data handling, or authority to act on your behalf.

This is a documentary audit method based on MCP 2026-07-28, checked on October 28, 2026. The worked example is fictional. No third-party server was installed, authenticated, or penetration-tested for this article.

Identify the thing you are connecting

Write down the server's owner, official distribution or endpoint, selected version, and update mechanism. For a package launched locally, inspect the command and its arguments before running it. An instruction that downloads and executes the latest package combines installation and execution with a moving dependency.

For a remote endpoint, verify its origin through the operator's official documentation. Record which organization receives requests and what data may appear in its logs. A familiar product name in a tool listing is insufficient evidence that the endpoint belongs to that product.

Keep host behavior separate from server behavior. The MCP architecture documentation distinguishes the host application, its clients, and servers. In version 2026-07-28, discovery uses server/discover, and the protocol is described in terms of stateless, self-contained requests. Check the versions actually supported on both ends; an older initialization transcript is not proof of compatibility with the current revision.

Local and remote servers cross different boundaries

A local stdio server is an executable process. Inspect the files, environment, working directory, network destinations, and operating-system privileges available to that process. “Local” does not mean isolated. A server launched as your user may be able to read far more than the project folder unless the host or operating system constrains it.

A remote HTTP server introduces an operator and transport boundary. Review where data is sent, which identity authenticates the call, and how account and tenant selection work. For a server acting as a proxy to another service, map both credential relationships rather than assuming that one login covers the whole chain safely.

The MCP authorization specification defines an HTTP authorization flow while treating authorization as optional at the protocol level. It directs stdio implementations toward credentials from their environment instead of that HTTP flow. Your data policy can require authenticated access even where the protocol permits a public server.

Review authority tool by tool

Suppose a fictional issue-tracker server exposes these operations:

Tool Claimed purpose Question before enabling it
search_issues Search project issues Which projects, private fields, and result contents can it return?
create_issue Add an issue Which account and project receive it, and can retries duplicate it?
attach_file Upload a local file Which paths may be read, where does the file go, and what size/type limits apply?
run_query Execute a query Is it constrained to reads and permitted resources, or is it a general execution surface?

A read-oriented task might justify enabling only search_issues with a synthetic project and a narrowly scoped credential. Disabling write tools in the UI is useful, but also verify what the credential and server enforce. A general query tool can make a seemingly small tool list surprisingly powerful.

Inspect input schemas, defaults, output types, pagination, maximum sizes, error behavior, and the handling of uncertain outcomes. Ask for the account or destination to be visible before a consequential call. Tool descriptions should make the effect understandable without requiring the model to infer hidden defaults.

The MCP tools specification warns that annotations are untrusted unless supplied by trusted servers. Treat labels such as read-only or non-destructive as reviewable claims. Require server-side enforcement for the boundary that matters to you.

Verify the authentication boundary

For protected HTTP servers, inspect the authorization-server and resource-server relationship. The MCP authorization security requirements require clients to identify the intended resource and servers to validate that presented tokens were issued for them. They also specify PKCE protections and secure token handling.

In an authorized test environment, a useful negative test presents a token intended for a different resource and verifies rejection. Another checks that a narrow scope cannot invoke a write operation. These tests need synthetic accounts and an approved test setup; do not probe someone else's production service or share live tokens to make an audit convenient.

The MCP security best-practices guide discusses token passthrough, confused deputies, server-side request forgery, local-server compromise, and scope minimization. Select tests from the server's architecture. A proxy needs review of downstream consent and credentials; a URL-fetching tool needs restrictions on reachable destinations; a local package needs containment and supply-chain review.

Document the difference between evidence types. Reading an implementation that validates token audience is source-review evidence. Observing a rejected wrong-audience token is runtime evidence. Seeing “OAuth supported” in a README is a product claim that still requires verification.

Keep returned content below the authorization boundary

Issue text, documents, and tool results may contain instructions written by other people. A successful server response does not authorize an agent to follow those instructions. Preserve their source and keep them separate from the user's request and the application's policy.

For the fictional issue server, test a harmless issue body that claims approval for an unrelated write. The expected behavior is to use the issue as data while refusing to derive permission from it. Then test the write restriction at the tool or service boundary as well. Model behavior and authorization enforcement are separate checks.

End with a bounded decision

A useful audit result might be: “Permit issue search against the synthetic project with this server version and read scope; keep attachment and write tools disabled until destination review and negative authorization tests pass.” That decision identifies what is allowed and what evidence remains missing.

Record the revoke path, credential owner, package or endpoint identity, reviewed tools, test results, and update triggers. Revisit the decision when tools, schemas, scopes, server code, host permissions, or data-handling terms change. A successful connection on one day is a starting observation, not a permanent trust grant.

You may also like