Detection rules reference

Hecate checks MCP client configs and tool definitions with eight deterministic rules. Critical and high findings exit with code 1, so the same run can block a merge.

Rules that need tool definitions (MCP001, MCP003, MCP004, MCP005) see them in a tools file, or with --connect, which starts each server in a config and lists its tools. Config rules (MCP006, MCP007, MCP008) work on the config alone. Pass everything one agent uses in one run so the cross-server rules can see it.

RuleFindsSeverity
MCP001Tool poisoningCritical
MCP002Rug pulls against a pinned lockfileHigh (low for removed tools)
MCP003Tool shadowing and name collisionsHigh / medium
MCP004Excessive scopeCritical / high / medium
MCP005Lethal trifectaHigh
MCP006Secrets exposureHigh / medium
MCP007Known-bad and disallowed serversCritical / high
MCP008Unpinned or insecure server sourcesHigh / medium

MCP001: Tool poisoning

Critical. A tool description contains instructions aimed at the model, or text hidden from the user: injection phrasing (“ignore previous instructions”, “before using any other tool”, “do not tell the user”, sending data to a URL or address), hidden HTML comments, zero-width, bidi and Unicode tag characters, and terminal control characters. Control or invisible characters in a tool name are flagged too.

Fix: read the full definition and the server’s source; remove the server unless the text is benign and expected. Guide: MCP tool poisoning.

MCP002: Rug pull

High. Reported by hecate check when a tool’s definition no longer matches the hash in hecate.lock.json, or a tool appears that was not pinned. A pinned tool that is no longer served is low.

Fix: diff the new definition against the approved one. Re-approve an expected change with hecate pin; otherwise stop using the server. Guide: MCP rug pull attacks.

MCP003: Tool shadowing

High when a tool or parameter description mentions another server’s tool with directive language (“whenever send_email is used, …”); medium for a plain mention, or when the same tool name is served by more than one server.

Fix: tools should only describe themselves. Remove the server, or rename colliding tools. Guide: MCP tool shadowing.

MCP004: Excessive scope

  • A tool that runs commands or code: high, or critical when the same agent also reads untrusted content.
  • A server that can write files while the agent reads untrusted content, which could plant shell profiles, git hooks or CI config: medium.
  • A stdio server given the filesystem root (high) or a home directory (medium) as an argument.

Fix: scope servers to a project or scratch directory, drop command-execution tools the agent does not need, or require approval before they run.

MCP005: Lethal trifecta

High. Across every server passed in one run, the agent has tools for untrusted content, private data and external communication. Tools are classified by name, parameters and description; the finding lists which tools make up each leg, and hecate graph draws it as a Mermaid diagram.

Fix: remove a leg for this agent, split the work across agents, or require approval before outbound tools run. Correct a misclassified tool with a capabilities entry in the policy. Guide: the lethal trifecta.

MCP006: Secrets exposure

High for known token formats (AWS, GitHub, Slack, Stripe, OpenAI and others) anywhere in a config or tool definition. Medium for literal values of secret-named keys and flags, passwords in connection URLs, and secrets in URL query strings. Findings name the location and the kind of secret; the value is never printed.

Fix: move the secret into the environment and reference it ("${env:NAME}" in VS Code and Cursor, "${NAME}" in Claude Code’s .mcp.json). Rotate it if the file was ever committed or shared.

MCP007: Known-bad or disallowed server

Critical for packages known to be malicious, such as postmark-mcp 1.0.16 and later; high for versions with a known exploitable vulnerability, such as mcp-remote before 0.1.16 (CVE-2025-6514). The built-in list is small and every entry is sourced. High as well for servers on your policy’s servers.deny list, or missing from its servers.allow list, matched by package, image, URL or command.

Fix: remove or upgrade the server and rotate anything it could reach.

MCP008: Unpinned or insecure source

High for a remote server reached over plain http://. Medium for an npm or PyPI package run without an exact version, and for a container image with no tag or tagged latest.

Fix: pin exact versions (server@1.2.3, server==1.2.3), prefer images by digest, and use https://.

Recording reviewed exceptions

Findings you have reviewed and accepted go in hecate.policy.json, with a reason and optionally an expiry date. They still appear in the output, marked as accepted, but no longer fail the run. Unknown keys and rule IDs are errors, so a typo cannot silently disable a check.

{
  "version": 1,
  "ignore": [
    {
      "rule": "MCP005",
      "reason": "Sandboxed agent, no credentials; reviewed by @alice",
      "expires": "2026-12-31"
    }
  ]
}