{
  "run_id": "ianewsfr-a11y--mcp-guard-claude-haiku-5-5-1792781545288324088",
  "checker": {
    "claims": [
      {
        "claim": "Offline by default: audits a config without starting servers",
        "command": "<guest-path> inspect config_example.json --format json",
        "evidence": "execute_bash_command\",\n    \"server\": null,\n    \"risk\": \"CRITICAL\",\n    \"findings\": [\n      {\n        \"id\": \"fad9054d64b5abca4b3d8419ac2ec834\",\n        \"category\": \"command-execution\",\n        \"risk\": \"CRITICAL\",\n        \"evidence\": \"bash, execute, shell\"\n      },\n      {\n        \"id\": \"6994492e89d4c3a5716087bc51558440\",\n        \"category\": \"privileged-access\",\n        \"risk\": \"CRITICAL\",\n        \"evidence\": \"root\"\n      }\n    ]\n  },\n  {\n    \"kind\": \"tool\",\n    \"name\": \"update_customer_record\",\n    \"server\": null,\n    \"risk\": \"HIGH\",\n    \"findings\": [\n      {\n        \"id\": \"0773e4a328e89cfd104d",
        "expected": "JSON audit listing execute_bash_command",
        "input": "config_example.json",
        "kind": "claim",
        "outcome": "Real input produced the expected result: execute_bash_command",
        "returncode": 0,
        "source": "By default it runs entirely offline and never executes the servers it audits.",
        "source_checked": true,
        "source_file": "README.md",
        "verdict": "yes"
      },
      {
        "claim": "--live starts the server and audits its real tools (memory server quick start)",
        "command": "<guest-path> inspect --live --yes --server 'npx -y @modelcontextprotocol/server-memory' --format json",
        "evidence": "delete_entities\",\n    \"server\": \"server-memory\",\n    \"risk\": \"HIGH\",\n    \"findings\": [\n      {\n        \"id\": \"15bbe97fbbcc2c91b67f5876a704eec9\",\n        \"category\": \"write-operation\",\n        \"risk\": \"HIGH\",\n        \"evidence\": \"delete\"\n      }\n    ]\n  },\n  {\n    \"kind\": \"tool\",\n    \"name\": \"delete_observations\",\n    \"server\": \"server-memory\",\n    \"risk\": \"HIGH\",\n    \"findings\": [\n      {\n        \"id\": \"2ab73595feb0ebea35c99155b8995d06\",\n        \"category\": \"write-operation\",\n        \"risk\": \"HIGH\",\n        \"evidence\": \"delete\"\n      }\n    ]\n  },\n  {\n    \"kind\": \"tool\",\n    \"name\": \"delete_rel",
        "expected": "JSON audit listing the real delete_entities tool",
        "input": "npx -y @modelcontextprotocol/server-memory",
        "kind": "claim",
        "outcome": "Real input produced the expected result: delete_entities",
        "returncode": 0,
        "source": "mcp-guard starts the server once, performs the MCP handshake, reads the tools it really exposes and audits each one:",
        "source_checked": true,
        "source_file": "README.md",
        "verdict": "yes"
      },
      {
        "claim": "inspect flags hidden instructions as tool poisoning",
        "command": "<guest-path> inspect examples/poisoned_tools.json",
        "evidence": "TOOL POISONING DETECTED \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e\n\u2502 4 tool(s) carry hidden instructions for the model: get_weather, add_numbers, \u2502\n\u2502 translate_text, format_date.                                                 \u2502\n\u2502 Any agent connected to this server reads them as if they came from you. Do   \u2502\n\u2502 not enable these tools until their descriptions and parameter descriptions   \u2502\n\u2502 have been reviewed.                                                          \u2502\n\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f\n",
        "expected": "TOOL POISONING DETECTED alert",
        "input": "examples/poisoned_tools.json",
        "kind": "claim",
        "outcome": "Real input produced the expected result: TOOL POISONING DETECTED",
        "returncode": 0,
        "source": "prints a **TOOL POISONING DETECTED** alert under the table",
        "source_checked": true,
        "source_file": "README.md",
        "verdict": "yes"
      }
    ],
    "cycle_checks": [
      {
        "claim": "Scheduled or looping main behavior",
        "command": "",
        "evidence": "Inspected README (no cron, schedule, --once or --now, webhook or loop features) and mcp_guard source. The only loops are stdio/proxy message pumps (mcp_guard/live/*, runtime/proxy.py, runtime/journal.py, runtime/recorder.py, runtime/inspector.py), which serve one request stream and are not product cycles. mcp-guard runs one audit per invocation.",
        "expected": "identify the product trigger",
        "input": "source inspection",
        "kind": "cycle",
        "outcome": "Inspected README (no cron, schedule, --once or --now, webhook or loop features) and mcp_guard source. The only loops are stdio/proxy message pumps (mcp_guard/live/*, runtime/proxy.py, runtime/journal.py, runtime/recorder.py, runtime/inspector.py), which serve one request stream and are not product cycles. mcp-guard runs one audit per invocation.",
        "source": "repository entry points",
        "verdict": "yes"
      }
    ],
    "details": {
      "argv": [
        "<guest-path>",
        "inspect",
        "config_example.json",
        "--format",
        "json"
      ],
      "kind": "cli",
      "needs_browser": false,
      "needs_credentials": false,
      "returncode": 0,
      "scope": "product operation",
      "stderr": "",
      "stdout": "[\n  {\n    \"kind\": \"server\",\n    \"name\": \"ops-toolbox\",\n    \"server\": null,\n    \"risk\": \"CRITICAL\",\n    \"findings\": [\n      {\n        \"id\": \"99d47e387fac685c88458e9c10c13132\",\n        \"category\": \"privileged-access\",\n        \"risk\": \"CRITICAL\",\n        \"evidence\": \"sudo\"\n[excerpt truncated]",
      "working": true
    },
    "evidence_strength": "readme_checked",
    "example_checks": [
      {
        "claim": "Tool poisoning detection on the shipped sample",
        "command": "<guest-path> inspect examples/poisoned_tools.json",
        "deferred": false,
        "evidence": " 0   HIGH  4   MEDIUM  0   LOW  1\n\u256d\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 TOOL POISONING DETECTED \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e\n\u2502 4 tool(s) carry hidden instructions for the model: get_weather, add_numbers, \u2502\n\u2502 translate_text, format_date.                                                 \u2502\n\u2502 Any agent connected to this server reads them as if they came from you. Do   \u2502\n\u2502 not enable these tools until their descriptions and parameter descriptions   \u2502\n\u2502 have been reviewed.                                                          \u2502\n\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f",
        "expected": "TOOL POISONING DETECTED alert",
        "input": "examples/poisoned_tools.json",
        "kind": "example",
        "outcome": "command completed successfully",
        "returncode": 0,
        "source": "README.md Tool poisoning section (examples/poisoned_tools.json)",
        "verdict": "yes"
      },
      {
        "claim": "Custom rules file (--rules) applied to a config",
        "command": "<guest-path> inspect --rules examples/rules.yaml config_example.json --format json",
        "deferred": false,
        "evidence": "\"update\"\n      },\n      {\n        \"id\": \"1b25a8ab4e22246c65c777ebbfa39be8\",\n        \"category\": \"database\",\n        \"risk\": \"MEDIUM\",\n        \"evidence\": \"database, query, sql, table\"\n      },\n      {\n        \"id\": \"e5efd8045e9a7c12789b1a68b6cdf766\",\n        \"category\": \"customer-data\",\n        \"risk\": \"HIGH\",\n        \"evidence\": \"customer, customers\"\n      }\n    ]\n  },\n  {\n    \"kind\": \"server\",\n    \"name\": \"filesystem\",\n    \"server\": null,\n    \"risk\": \"LOW\",\n    \"findings\": []\n  },\n  {\n    \"kind\": \"tool\",\n    \"name\": \"fetch_url\",\n    \"server\": null,\n    \"risk\": \"LOW\",\n    \"findings\": []\n  }\n]",
        "expected": "JSON audit with privileged-access finding",
        "input": "examples/rules.yaml with config_example.json",
        "kind": "example",
        "outcome": "command completed successfully",
        "returncode": 0,
        "source": "README.md --rules: custom rules (examples/rules.yaml)",
        "verdict": "yes"
      },
      {
        "claim": "Documented test suite",
        "command": "",
        "deferred": false,
        "evidence": "Ran the documented command with the venv pytest: 945 passed, 1 failed (tests/test_proxy.py::test_pins_never_store_secrets_or_the_home_directory). The failure is environmental: the test expects the venv python under the home directory, but the venv is at <guest-path> and resolves to /usr/bin/python3.12. Not a product defect as far as observed.",
        "expected": "documented command completes successfully",
        "input": "",
        "kind": "example",
        "outcome": "Ran the documented command with the venv pytest: 945 passed, 1 failed (tests/test_proxy.py::test_pins_never_store_secrets_or_the_home_directory). The failure is environmental: the test expects the venv python under the home directory, but the venv is at <guest-path> and resolves to /usr/bin/python3.12. Not a product defect as far as observed.",
        "source": "README.md Development section (pytest --cov=mcp_guard)",
        "verdict": "blocked"
      }
    ],
    "status": "PASS"
  },
  "diagnosis": null
}
