Files
zernie__vigiles/docs/rules/mcp-hook-target-resolves.md
zernie ff542b7c4b refactor!: vigiles audit — Lighthouse-style harness report (rename scan→audit)
Rename the read-only scan verb to `vigiles audit` — a local, zero-config Lighthouse-style report scoring a harness across four deterministic rings (Truthfulness/Triggering/Structure/Tested) with each finding's fix inline + a shareable HTML report and a versioned AuditReport JSON.

audit is a local report, not a CI step (CI uses `vigiles lint`). The executing checks (live MCP resolution + trigger-rate + the adoption preview) run only behind one interactive consent; there is no execution flag. The safety battery is not an audit ring — it lives in the vigiles/testing API.

Adds the adoption-gateway preview ("what would vigiles catch in your repo?"): the model drafts a spec from the instruction file, the cross-reference engine verifies every drafted ref deterministically.

BREAKING CHANGE: the `scan` verb is renamed to `audit` (no alias); the `--check-hooks`/`--verify-mcp`/`--trigger`/`--fix-plan`/`--explain`/`--deep`/`--measure`/`--fast`/`--no-measure` flags are removed.
2026-06-28 02:34:50 +05:00

2.8 KiB

mcp-hook-target-resolves

Cross-reference a type: "mcp_tool" hook action against the plugin's declared MCP servers. Claude Code hooks support five action types (command / http / mcp_tool / prompt / agent); an mcp_tool action calls a tool on an already-connected MCP server and requires a server + tool field. This rule flags two ways it silently never dispatches. Same detector vigiles audit uses (verifyMcpHookTargets in src/core/mcp-hook.ts).

It extends the tool cross-reference to the hook surface — sibling of mcp-tool-resolves (a subagent's mcp__server__tool) and mcp-config (a server that can't start).

What it flags

"hooks": {
  "PreToolUse": [{ "matcher": "Bash", "hooks": [
    { "type": "mcp_tool", "server": "github", "tool": "search" },  // ✓ declared
    { "type": "mcp_tool", "server": "linear", "tool": "create" },  // ✗ undeclared server
    { "type": "mcp_tool", "server": "github" }                      // ✗ incomplete (no tool)
  ]}]
}
  1. Incomplete — an mcp_tool action missing server or tool. Unambiguous (it can't dispatch), so always flagged, like mcp-config.
  2. Undeclared server — the server isn't in the plugin's mcpServers. High-precision: only flagged when the plugin ships a declared set (else the server may be user-global/project, unknowable), and harness built-ins (ide) are allowlisted — exactly the mcp-tool-resolves calibration.

A command/http/prompt/agent action is ignored. The matcher surface (a mcp__server__.* matcher naming an undeclared server) is a separate regex-shaped concern left to a future hook-matcher rule.

Configuration

{ "rules": { "mcp-hook-target-resolves": "warn" } }

Severity

Value Behavior
"error" vigiles lint exits non-zero (2) on an offending hook action
"warn" (default) Prints a warning, exits 0
false Skip the check

Scope

Hook actions in .claude/settings.json and the plugin manifest (.claude-plugin/plugin.json); declared servers read from .mcp.json + the manifest mcpServers.

Why

An mcp_tool hook is deterministic machinery that depends on an MCP server being present; one pointed at a server the plugin never declares (or missing its target fields) is a silent no-op — the author believes the automation runs when it can't.

See also