MCP Servers
Verify Model Context Protocol servers and tools before agents can use them.
-
What Phylax checks for MCP
Provenance Confirms the server’s origin, publisher identity, and build provenance.Permissions Validates scopes and capabilities requested by the server.Tool surface Inspects tools and resources for unsafe operations or data exfil.Risk signals Detects known CVEs, malware, secrets, and malicious patterns. -
Verify a server
Terminal window phylax mcp verify mcp://acme/postgres-tools -
Client setup
Add Phylax as an MCP server in Claude Desktop or Cursor.
{"mcpServers": {"phylax": {"command": "phylax","args": ["mcp", "serve"],"env": {"PHYLAX_API_TOKEN": "${PHYLAX_API_TOKEN}"}}}} -
Interpreting results
Example verification result.
View full report- verdict:
- allow
- risk score:
- 18 / 100
- provenance:
- verified
- attestation:
- available
-
Policy controls
Define how Phylax should evaluate MCP servers in your environment.
mcpPolicy:defaults: allowrules:- match: "publisher == 'acme'"action: allow- match: "server.name =~ /\b(experimental|beta)\b/"action: warn- match: "tool.permissions contains 'filesystem.write'"action: block -
Next steps
What actually goes wrong with MCP
The four checks above are not generic supply chain hygiene. Each one maps to a named attack in the MCP security specification or the agentic threat literature. This is the model Phylax verifies against.
| Attack | What it looks like | What Phylax checks |
|---|---|---|
| Tool poisoning | Malicious instructions hidden in a tool’s description or metadata, which the model reads as if it were user intent | Tool surface |
| Confused deputy | A proxy server with a static client ID lets an attacker skip the consent screen and collect an auth code | Permissions |
| Token passthrough | A server accepts a token that was not issued for it and forwards it downstream | Permissions |
| State handle hijacking | An attacker guesses a workflow or cart handle and operates on another user’s state | Tool surface |
| Local server compromise | A one-click config runs an arbitrary startup command with your privileges | Provenance, Risk signals |
| SSRF via OAuth discovery | A server returns metadata URLs pointing at 169.254.169.254 to lift cloud credentials | Risk signals |
Tool poisoning is the one to worry about
It is the most prevalent client-side weakness in MCP, and the OWASP Top 10 for Agentic Applications (2026) classifies it under ASI01, Agent Goal Hijack. The mechanism is unglamorous: an agent reads tool descriptions as trusted context, so a description is an injection point. Nothing in the protocol distinguishes “documentation the developer wrote” from “instructions the model should follow”.
This is why the tool surface check reads descriptions and schemas, not just the transport. A
server can be correctly signed, correctly scoped, served over TLS, and still ship a tool whose
description tells the model to read ~/.ssh/id_rsa and pass it as an argument.
A server that verifies clean today can change its tool definitions tomorrow. Re-verify on every version change, and keep the runtime controls below regardless of the verdict.
Hardening the servers you run
If you operate an MCP server, these are the specification’s own requirements. They are normative, not advisory.
- Never accept a token that was not issued for you. Servers MUST NOT accept tokens
lacking a matching audience claim. Validate
audon every request and reject anything minted for another service, even if it is signed and unexpired. - Never forward a token downstream. Token passthrough is explicitly forbidden. Use token exchange when you need to call another service.
- Never treat a handle as authentication. MCP is stateless and has no protocol-level
sessions. Bind state handles server-side to the authenticated user, keyed as
<user_id>:<handle>, and reject a handle presented by anyone else. - Implement per-client consent if you proxy a third-party API. Keep a registry of approved
client_idvalues per user, check it before redirecting, and matchredirect_uriby exact string, never a wildcard. - Prefer
stdiofor local servers. It limits access to the client that spawned the process. If you must use HTTP, require an authorization token or a Unix domain socket.
Hardening the client side
- Block private address ranges when following OAuth discovery URLs:
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.0/8,169.254.0.0/16,fc00::/7andfe80::/10. The link-local range is what protects cloud metadata credentials. Use a library rather than hand-rolling the check, since attackers reach for octal, hex and IPv4-mapped IPv6 encodings. - Allow only
httpandhttpsauthorization URLs, andhttponly on loopback during development. Rejectjavascript:,data:,file:andvbscript:outright. - Never open a URL through a shell. Use a platform API. Shell interpolation of a server-supplied URL is a remote code execution path.
- Show the exact command before running a local server, untruncated, and require explicit approval. This is a MUST for any client offering one-click setup.
- Ask for the narrowest scope that works. Avoid
*,allandfull-access; escalate throughWWW-Authenticatechallenges when a privileged operation is first attempted.
Related guides
Gate loading at runtime with the Agent Runtime Gate, or read the verdict vocabulary in Core Concepts.
The Phylax MCP server is open source at praxi-labs/phylax-mcp.