List every tool the server exposes
Write down every tool, prompt, resource, and transport. Separate read operations from write operations. If a tool can write data, change state, or trigger side effects, mark it explicitly.
Checklist
A deploy-ready security review checklist for teams preparing MCP servers for production. Each item includes what to check, why it matters, and what to look for during review.
Section 1
Write down every tool, prompt, resource, and transport. Separate read operations from write operations. If a tool can write data, change state, or trigger side effects, mark it explicitly.
For each write-capable tool, list the systems, files, APIs, or databases it can reach. Include indirect access through library calls or system commands.
What credentials does the server use? Are they scoped to the minimum necessary operations? A server with a service account that has broad permissions is a single point of failure.
Can one tool's output feed another tool's input in a way that bypasses safety checks? Identify cross-tool data flows that could be exploited in sequence.
Section 2
Use typed schemas (JSON Schema, TypeScript types, Pydantic models) for every tool parameter. Reject arguments that do not match the expected type, format, or range.
Tools that accept file paths or URLs must validate against allowlists or strict patterns. Reject traversal sequences, protocol injection, and unexpected scheme values.
Set limits on string lengths, array sizes, and numeric ranges. Attackers often probe boundary values to find validation gaps.
Default argument values should err on the side of doing less. If a tool can operate on a default path or scope, that default should be the narrowest reasonable option.
Section 3
If the server is accessible over HTTP or SSE, every connection must be authenticated. API keys, bearer tokens, or mutual TLS are acceptable mechanisms.
API keys, database credentials, and service account tokens must be loaded from environment variables, secrets vaults, or mounted volumes — never from source code.
Authenticating the client should not grant access to every tool. Implement per-tool authorization that checks whether the authenticated principal is allowed to invoke the specific tool with the specific arguments.
The team should be able to revoke a specific tool, a specific client, or the entire server without redeploying. If revocation requires a code change, the design needs revision.
Section 4
Log the tool name, arguments, authenticated client identity, timestamp, and response status. Structured logging (JSON) makes aggregation and analysis possible.
If a policy enforcement layer evaluated the call, log which rules were checked and the verdict. This turns incidents from "what happened" to "why was it allowed."
Logs should be written to a destination the server cannot modify after writing. Centralized logging with append-only permissions is the baseline.
Set retention periods based on regulatory requirements and incident response timelines. 90 days is a reasonable minimum for production systems.
Section 5
Before the server reaches production traffic, run through these final checks.
Send malformed arguments, unexpected types, and known attack patterns to every tool. Verify that the server rejects them cleanly without crashing or exposing stack traces.
Run a test session and review the logs. Can you reconstruct every tool call, policy decision, and response? If not, add the missing fields before go-live.
Disable a tool or client and confirm the server refuses the next request immediately. If the server caches permissions or requires a restart, fix it before production.
Consider deploying McpVanguard or a similar gateway between clients and the server. This provides deterministic policy enforcement without modifying the server's code.
McpVanguard sits between your MCP clients and servers, adding deterministic policy checks without any server-side changes. Start in audit mode today.