{
  "markdown": "> Japanese version: [README.ja.md](README.ja.md)\n\n# mcp-yoshi\n\nA real-time security filter for MCP (Model Context Protocol) tool communication. Runs as a Claude Code hook, inspecting data sent to and received from MCP tools to assess safety.\n\n## Why\n\n- 97% of MCP tool descriptions are inadequate, and 13% are inconsistent with the actual implementation ([research paper](https://arxiv.org/abs/2602.14878))\n- Existing tools (mcp-scan, mcp-drift-detector) only provide static or pre-run checks\n- **No real-time communication filter existed**\n\nmcp-yoshi inspects data at the moment of communication and immediately blocks or warns when issues are detected.\n\n## Features\n\n### Outbound Checks (data sent to MCP servers)\n\n| ID | Check | Detection Target |\n|----|-------|-----------------|\n| OUT-001 | API Key Pattern | API keys for AWS, OpenAI, GitHub, Slack, Google, Stripe, etc. |\n| OUT-002 | Private Key | RSA/EC/DSA/OPENSSH private keys |\n| OUT-003 | High Entropy String | Random strings of 32+ characters |\n| OUT-004 | Env Value Pattern | Environment variable values for PASSWORD, SECRET, TOKEN, etc. |\n| OUT-005 | PII Pattern | Email addresses, phone numbers, credit card numbers |\n| OUT-006 | Large Payload | Request payloads exceeding 50KB (bulk data exfiltration) |\n| OUT-007 | Path Traversal | Sensitive paths such as /etc/passwd, ~/.ssh/, C:\\Windows\\ |\n\n### Inbound Checks (data received from MCP servers)\n\n| ID | Check | Detection Target |\n|----|-------|-----------------|\n| IN-001 | Prompt Injection | Instruction overrides like \"ignore previous instructions\" |\n| IN-002 | Shell Command Embedding | Command injection via `$(...)`, `; rm`, `\\| bash`, etc. |\n| IN-003 | Suspicious URL / SSRF | javascript: URIs, URL shorteners, internal networks, cloud metadata (169.254.169.254, etc.) |\n| IN-004 | Script Injection | `<script>`, `eval()`, `document.cookie`, etc. |\n| IN-005 | Tool Definition Tampering | Hidden instructions embedded in tool descriptions (12 patterns) |\n| IN-006 | ASCII Smuggling | Invisible Unicode characters (U+E0000 Tags Block, Zero-Width characters) |\n| IN-007 | Base64 Encoded Payload | Re-inspects decoded Base64 content against existing patterns |\n| IN-008 | Response Size Limit | Responses exceeding 512KB (context window poisoning prevention) |\n| IN-009 | Hidden Fields | Undeclared fields such as `_hidden`, `$meta` |\n| IN-010 | Elicitation Abuse | BLOCKs credential requests and command execution prompts |\n| IN-011 | Sampling Injection | Embedded LLM tokenizer markers (`[INST]`, `<<SYS>>`, `<\\|im_start\\|>`, etc.) |\n| IN-012 | Log-To-Leak | Data exfiltration instructions (\"send this data to...\", \"call the logging tool\", etc.) |\n| IN-013 | Conversation Marker | Conversation markers (`Human:`, `Assistant:`) injected at the beginning of lines |\n| IN-014 | Credentials in Response | Residual credentials in stdout/stderr (AWS/OpenAI/GitHub keys, Bearer Tokens, private keys) |\n| IN-015 | Parameter Override | `overrideConfig` key co-occurring with `mcpServerConfig`/`NODE_OPTIONS`/`executablePath` for Allowlist Bypass attacks (CVE-2026-40933 related) |\n| IN-017 | Path Traversal | `../` directory traversal + sensitive path references in `basePath`/`filePath`/`filename` (`/etc/`, `/root/`, `C:\\Windows\\`, `/proc/`) |\n| IN-018 | Query Injection | SQL/Cypher/NoSQL injection -- BLOCK: `UNION SELECT`, `DROP TABLE`, `MATCH...DELETE`, `;--` / WARN: `' OR '`, `sleep()` |\n| IN-019 | Sandbox Escape | vm/Function/global access (`globalThis.process.mainModule.require`, `constructor.constructor()` vm2 escape, etc.) |\n| IN-020 | Header Spoofing | Trust boundary bypass (`x-request-from: internal`, `x-forwarded-for: 127.0.0.1`, etc.) |\n| IN-021 | Browser Launch RCE | Puppeteer/Playwright `executablePath` pointing to shell binaries (`/bin/sh`, `/usr/bin/nc`, etc.) |\n\n### Rate Limiting (communication patterns)\n\n| ID | Check | Detection Target |\n|----|-------|-----------------|\n| RATE-001 | Rapid Fire Detection | WARNs when the same tool is called 10+ times within 60 seconds |\n\n### Rug Pull Detection (tool definition tampering)\n\n| ID | Check | Detection Target |\n|----|-------|-----------------|\n| RUG-001 | Tool Definition Changed | Detects SHA-256 hash changes in tool definitions |\n| SHADOW-001 | Tool Shadowing | Detects same-name tool registrations from different servers |\n\nOn the first call, tool definition hashes are recorded. Subsequent calls that detect changes will trigger a WARN. Hashes are persisted in `~/.mcp-yoshi/tool-hashes.json`, enabling cross-session detection.\n\n### NFKC Normalization (anti-obfuscation)\n\n[NFKC normalization](https://unicode.org/reports/tr15/) is applied before all inbound/outbound checks. This transparently detects obfuscation via fullwidth characters (e.g., `ignore` encoded as fullwidth) and Unicode compatibility characters.\n\n### Three-Level Verdicts\n\n| Verdict | Behavior |\n|---------|----------|\n| **PASS** | No issues found. Execution proceeds normally |\n| **WARN** | Warning is added to Claude's context. Execution continues |\n| **BLOCK** | Tool execution is blocked (outbound) / warning is displayed (inbound) |\n\n## Requirements\n\n- Node.js 18+\n\n## Installation\n\n```bash\nnpm install -g mcp-yoshi\n```\n\n## Setup\n\n```bash\n# Automatically add hook configuration to Claude Code's settings.json\nmcp-yoshi init\n\n# For project-level configuration\nmcp-yoshi init --project\n```\n\nThis automatically configures the following hooks:\n\n- `PreToolUse`: matches `mcp__.*` -> outbound checks\n- `PostToolUse`: matches `mcp__.*` -> inbound checks\n\n## Usage\n\nAfter setup, mcp-yoshi operates automatically. Checks run every time an MCP tool is invoked.\n\n### Viewing Logs\n\n```bash\n# Show the last 20 log entries\nmcp-yoshi logs\n\n# Show the last 50 entries at WARN level or above\nmcp-yoshi logs --tail 50 --level warn\n\n# Show BLOCK entries only\nmcp-yoshi logs --level block\n```\n\n### Statistics Report\n\n```bash\n# Show detection statistics for the past 7 days\nmcp-yoshi stats\n\n# Past 30 days\nmcp-yoshi stats --days 30\n```\n\n### View Configuration\n\n```bash\nmcp-yoshi config\n```\n\n## Allowlist (Trusted Servers)\n\nYou can register specific MCP servers as trusted to skip checks.\nThis operates under **your own responsibility**, but logging continues (severity: SKIPPED).\n\n```bash\n# Add a server to the allowlist (reason recommended)\nmcp-yoshi allow memory --reason \"Internal knowledge graph, trusted\"\n\n# Allow with expiry date\nmcp-yoshi allow memory --reason \"Temporary exception\" --expires 2027-01-01\n\n# Allow once only (auto-removed after first use)\nmcp-yoshi allow memory --once --reason \"One-time migration\"\n\n# List the allowlist\nmcp-yoshi allow --list\n\n# Remove from the allowlist\nmcp-yoshi allow --remove memory\n```\n\nYou can also configure it directly in `~/.mcp-yoshi/config.json`:\n\n```json\n{\n  \"allowlist\": [\n    { \"server\": \"memory\", \"reason\": \"Internal knowledge graph\", \"addedAt\": \"2026-03-12T00:00:00.000Z\" },\n    { \"server\": \"temp-srv\", \"reason\": \"Migration\", \"expires\": \"2026-12-31\", \"allowOnce\": true }\n  ]\n}\n```\n\n### SIEM Export\n\nExport blocked events in SIEM-compatible formats:\n\n```bash\n# JSONL format (Splunk, Datadog)\nmcp-yoshi export --format jsonl --days 30\n\n# CEF format (ArcSight, QRadar)\nmcp-yoshi export --format cef\n\n# ECS format (Elastic)\nmcp-yoshi export --format ecs\n```\n\n### Project-Level Severity Override\n\nCreate `.mcp-yoshi.json` in a project root to override severity per-project:\n\n```json\n{\n  \"severity\": {\n    \"BLOCK\": [\"apiKeys\", \"privateKeys\"],\n    \"WARN\": [\"highEntropy\"]\n  }\n}\n```\n\n## Configuration\n\nCreate `~/.mcp-yoshi/config.json` to override default settings.\n\n```json\n{\n  \"logLevel\": \"warn\",\n  \"checks\": {\n    \"outbound\": {\n      \"highEntropy\": false\n    }\n  },\n  \"servers\": {\n    \"*\": { \"enabled\": true },\n    \"memory\": { \"enabled\": true },\n    \"trusted-server\": { \"enabled\": false }\n  },\n  \"severity\": {\n    \"WARN\": [\"highEntropy\", \"pii\", \"suspiciousUrls\", \"base64Payload\", \"largePayload\", \"responseSizeLimit\", \"hiddenFields\", \"rapidFire\"],\n    \"BLOCK\": [\"apiKeys\", \"privateKeys\", \"promptInjection\", \"shellCommands\", \"scriptInjection\", \"toolTampering\", \"envValues\", \"asciiSmuggling\", \"pathTraversal\", \"elicitationAbuse\"]\n  }\n}\n```\n\n### Per-Server Configuration\n\nUse the `servers` section to control filter on/off and check items per MCP server.\n\n```json\n{\n  \"servers\": {\n    \"*\": { \"enabled\": true },\n    \"trusted-internal\": { \"enabled\": false },\n    \"external-api\": {\n      \"enabled\": true,\n      \"checks\": {\n        \"outbound\": { \"pii\": false },\n        \"inbound\": { \"promptInjection\": true }\n      }\n    }\n  }\n}\n```\n\n| Key | Description |\n|-----|-------------|\n| `\"*\"` | Default settings (applied to undefined servers) |\n| `\"<server-name>\"` | Applied to tools matching `mcp__<server-name>__*` |\n\n- `enabled: false` -> completely skips checks for that server\n- `checks` -> overrides global settings on a per-server basis\n\n### Configuration Reference\n\n| Option | Default | Description |\n|--------|---------|-------------|\n| `logDir` | `~/.mcp-yoshi/logs` | Log output directory |\n| `logLevel` | `info` | `info`: log everything, `warn`: WARN and above, `none`: no logging |\n| `checks.outbound.*` | `true` | Enable/disable individual outbound checks |\n| `checks.inbound.*` | `true` | Enable/disable individual inbound checks |\n| `servers` | `{\"*\": {\"enabled\": true}}` | Per-server on/off |\n| `severity.WARN` | `[\"highEntropy\", \"pii\", \"suspiciousUrls\", ...]` | Check IDs classified as WARN |\n| `severity.BLOCK` | `[\"apiKeys\", \"privateKeys\", \"promptInjection\", ...]` | Check IDs classified as BLOCK |\n\n## Uninstall\n\n```bash\n# Remove hook configuration\nmcp-yoshi uninstall\n\n# Remove the package\nnpm uninstall -g mcp-yoshi\n```\n\n## Comparison with Existing Tools\n\n| Tool | Timing | Scope |\n|------|--------|-------|\n| [mcp-scan](https://github.com/invariantlabs-ai/mcp-scan) | Pre-run (static check) | Tool definition safety |\n| [mcp-drift-detector](https://github.com/AshishKumar-ops/mcp-drift-detector) | Periodic (change detection) | Tool definition tampering |\n| **mcp-yoshi** | **Real-time (during communication)** | **Safety of transmitted/received data** |\n\n## Security Recommendations\n\n### Regarding `.mcp.json` in External Repositories\n\nWhen cloning external repositories, MCP servers defined in their `.mcp.json` should be treated as **untrusted**. Attacks via malicious `.mcp.json` files that auto-register tools have been reported.\n\n- Do **not** add servers originating from external `.mcp.json` to the allowlist\n- Use them with mcp-yoshi checks enabled\n- Review logs for suspicious tool invocations\n\n## Notes\n\n- **Performance**: Hooks run on every MCP tool call, adding slight latency (around tens of milliseconds). If this is a concern, change `logLevel` to `\"warn\"` or set trusted servers to `enabled: false`\n- **False Positives**: High entropy strings and PII patterns may match legitimate data. If false positives are frequent, disable the relevant check or downgrade its severity to WARN\n- **Detection Limits**: Detection is based on regex pattern matching with NFKC normalization. Highly obfuscated attacks or unknown patterns may not be caught. We recommend using mcp-yoshi alongside other security tools (such as mcp-scan)\n- **Rug Pull Detection**: Tool definition hashes are persisted in `~/.mcp-yoshi/tool-hashes.json`. If the file is corrupted, it automatically restarts from an empty state\n\n## License\n\nMIT\n",
  "bytes": 11331,
  "sha": "97d40b1db6d03fa59207abcb1d8bfc05a75656809a2c9ecdb38dba6e38edaff5",
  "repo_slug": "aliksir/mcp-yoshi",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/plg_aliksir_mcp_yoshi_mcp_yoshi_aa276721/readme"
}