Back to the catalog

mcp-yoshi

Real-time security filter for MCP tool communications. Works as a Claude Code hook to inspect all data sent to and received from MCP servers

Open source Open in the app JSON README (API)

About

Real-time security filter for MCP tool communications. Works as a Claude Code hook to inspect all data sent to and received from MCP servers. Detects prompt injection, API key leakage, tool poisoning, ASCII smuggling, SSRF, Base64-encoded payloads, and Rug Pull attacks. Provides PASS/WARN/BLOCK decisions with per-server configuration, allowlisting, and logging. Zero dependencies, ~60ms latency.

Details

Kind
Plugins
Topic
Developer tools
Publisher
aliksir
Origin
marketplace
Category
ferramentas
Stars
1
Last push
2026-06-24T17:19:51Z
Repository state
ativo
Language
JavaScript
License
MIT
Added
2026-08-30 01:48:58
Updated
2026-08-30 01:48:58
Origin id
aliksir/mcp-yoshi/mcp-yoshi

README

> Japanese version: [README.ja.md](README.ja.md)

# mcp-yoshi

A 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.

## Why

- 97% of MCP tool descriptions are inadequate, and 13% are inconsistent with the actual implementation ([research paper](https://arxiv.org/abs/2602.14878))
- Existing tools (mcp-scan, mcp-drift-detector) only provide static or pre-run checks
- **No real-time communication filter existed**

mcp-yoshi inspects data at the moment of communication and immediately blocks or warns when issues are detected.

## Features

### Outbound Checks (data sent to MCP servers)

| ID | Check | Detection Target |
|----|-------|-----------------|
| OUT-001 | API Key Pattern | API keys for AWS, OpenAI, GitHub, Slack, Google, Stripe, etc. |
| OUT-002 | Private Key | RSA/EC/DSA/OPENSSH private keys |
| OUT-003 | High Entropy String | Random strings of 32+ characters |
| OUT-004 | Env Value Pattern | Environment variable values for PASSWORD, SECRET, TOKEN, etc. |
| OUT-005 | PII Pattern | Email addresses, phone numbers, credit card numbers |
| OUT-006 | Large Payload | Request payloads exceeding 50KB (bulk data exfiltration) |
| OUT-007 | Path Traversal | Sensitive paths such as /etc/passwd, ~/.ssh/, C:\Windows\ |

### Inbound Checks (data received from MCP servers)

| ID | Check | Detection Target |
|----|-------|-----------------|
| IN-001 | Prompt Injection | Instruction overrides like "ignore previous instructions" |
| IN-002 | Shell Command Embedding | Command injection via `$(...)`, `; rm`, `\| bash`, etc. |
| IN-003 | Suspicious URL / SSRF | javascript: URIs, URL shorteners, internal networks, cloud metadata (169.254.169.254, etc.) |
| IN-004 | Script Injection | `<script>`, `eval()`, `document.cookie`, etc. |
| IN-005 | Tool Definition Tampering | Hidden instructions embedded in tool descriptions (12 patterns) |
| IN-006 | ASCII Smuggling | Invisible Unicode characters (U+E0000 Tags Block, Zero-Width characters) |
| IN-007 | Base64 Encoded Payload | Re-inspects decoded Base64 content against existing patterns |
| IN-008 | Response Size Limit | Responses exceeding 512KB (context window poisoning prevention) |
| IN-009 | Hidden Fields | Undeclared fields such as `_hidden`, `$meta` |
| IN-010 | Elicitation Abuse | BLOCKs credential requests and command execution prompts |
| IN-011 | Sampling Injection | Embedded LLM tokenizer markers (`[INST]`, `<<SYS>>`, `<\|im_start\|>`, etc.) |
| IN-012 | Log-To-Leak | Data exfiltration instructions ("send this data to...", "call the logging tool", etc.) |
| IN-013 | Conversation Marker | Conversation markers (`Human:`, `Assistant:`) injected at the beginning of lines |
| IN-014 | Credentials in Response | Residual credentials in stdout/stderr (AWS/OpenAI/GitHub keys, Bearer Tokens, private keys) |
| IN-015 | Parameter Override | `overrideConfig` key co-occurring with `mcpServerConfig`/`NODE_OPTIONS`/`executablePath` for Allowlist Bypass attacks (CVE-2026-40933 related) |
| IN-017 | Path Traversal | `../` directory traversal + sensitive path references in `basePath`/`filePath`/`filename` (`/etc/`, `/root/`, `C:\Windows\`, `/proc/`) |
| IN-018 | Query Injection | SQL/Cypher/NoSQL injection -- BLOCK: `UNION SELECT`, `DROP TABLE`, `MATCH...DELETE`, `;--` / WARN: `' OR '`, `sleep()` |
| IN-019 | Sandbox Escape | vm/Function/global access (`globalThis.process.mainModule.require`, `constructor.constructor()` vm2 escape, etc.) |
| IN-020 | Header Spoofing | Trust boundary bypass (`x-request-from: internal`, `x-forwarded-for: 127.0.0.1`, etc.) |
| IN-021 | Browser Launch RCE | Puppeteer/Playwright `executablePath` pointing to shell binaries (`/bin/sh`, `/usr/bin/nc`, etc.) |

### Rate Limiting (communication patterns)

| ID | Check | Detection Target |
|----|-------|-----------------|
| RATE-001 | Rapid Fire Detection | WARNs when the same tool is called 10+ times within 60 seconds |

### Rug Pull Detection (tool definition tampering)

| ID | Check | Detection Target |
|----|-------|-----------------|
| RUG-001 | Tool Definition Changed | Detects SHA-256 hash changes in tool definitions |
| SHADOW-001 | Tool Shadowing | Detects same-name tool registrations from different servers |

On 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.

### NFKC Normalization (anti-obfuscation)

[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.

### Three-Level Verdicts

| Verdict | Behavior |
|---------|----------|
| **PASS** | No issues found. Execution proceeds normally |
| **WARN** | Warning is added to Claude's context. Execution continues |
| **BLOCK** | Tool execution is blocked (outbound) / warning is displayed (inbound) |

## Requirements

- Node.js 18+

## Installation

```bash
npm install -g mcp-yoshi
```

## Setup

```bash
# Automatically add hook configuration to Claude Code's settings.json
mcp-yoshi init

# For project-level configuration
mcp-yoshi init --project
```

This automatically configures the following hooks:

- `PreToolUse`: matches `mcp__.*` -> outbound checks
- `PostToolUse`: matches `mcp__.*` -> inbound checks

## Usage

After setup, mcp-yoshi operates automatically. Checks run every time an MCP tool is invoked.

### Viewing Logs

```bash
# Show the last 20 log entries
mcp-yoshi logs

# Show the last 50 entries at WARN level or above
mcp-yoshi logs --tail 50 --level warn

# Show BLOCK entries only
mcp-yoshi logs --level block
```

### Statistics Report

```bash
# Show detection statistics for the past 7 days
mcp-yoshi stats

# Past 30 days
mcp-yoshi stats --days 30
```

### View Configuration

```bash
mcp-yoshi config
```

## Allowlist (Trusted Servers)

You can register specific MCP servers as trusted to skip checks.
This operates under **your own responsibility**, but logging continues (severity: SKIPPED).

```bash
# Add a server to the allowlist (reason recommended)
mcp-yoshi allow memory --reason "Internal knowledge graph, trusted"

# Allow with expiry date
mcp-yoshi allow memory --reason "Temporary exception" --expires 2027-01-01

# Allow once only (auto-removed after first use)
mcp-yoshi allow memory --once --reason "One-time migration"

# List the allowlist
mcp-yoshi allow --list

# Remove from the allowlist
mcp-yoshi allow --remove memory
```

You can also configure it directly in `~/.mcp-yoshi/config.json`:

```json
{
  "allowlist": [
    { "server": "memory", "reason": "Internal knowledge graph", "addedAt": "2026-03-12T00:00:00.000Z" },
    { "server": "temp-srv", "reason": "Migration", "expires": "2026-12-31", "allowOnce": true }
  ]
}
```

### SIEM Export

Export blocked events in SIEM-compatible formats:

```bash
# JSONL format (Splunk, Datadog)
mcp-yoshi export --format jsonl --days 30

# CEF format (ArcSight, QRadar)
mcp-yoshi export --format cef

# ECS format (Elastic)
mcp-yoshi export --format ecs
```

### Project-Level Severity Override

Create `.mcp-yoshi.json` in a project root to override severity per-project:

```json
{
  "severity": {
    "BLOCK": ["apiKeys", "privateKeys"],
    "WARN": ["highEntropy"]
  }
}
```

## Configuration

Create `~/.mcp-yoshi/config.json` to override default settings.

```json
{
  "logLevel": "warn",
  "checks": {
    "outbound": {
      "highEntropy": false
    }
  },
  "servers": {
    "*": { "enabled": true },
    "memory": { "enabled": true },
    "trusted-server": { "enabled": false }
  },
  "severity": {
    "WARN": ["highEntropy", "pii", "suspiciousUrls", "base64Payload", "largePayload", "responseSizeLimit", "hiddenFields", "rapidFire"],
    "BLOCK": ["apiKeys", "privateKeys", "promptInjection", "shellCommands", "scriptInjection", "toolTampering", "envValues", "asciiSmuggling", "pathTraversal", "elicitationAbuse"]
  }
}
```

### Per-Server Configuration

Use the `servers` section to control filter on/off and check items per MCP server.

```json
{
  "servers": {
    "*": { "enabled": true },
    "trusted-internal": { "enabled": false },
    "external-api": {
      "enabled": true,
      "checks": {
        "outbound": { "pii": false },
        "inbound": { "promptInjection": true }
      }
    }
  }
}
```

| Key | Description |
|-----|-------------|
| `"*"` | Default settings (applied to undefined servers) |
| `"<server-name>"` | Applied to tools matching `mcp__<server-name>__*` |

- `enabled: false` -> completely skips checks for that server
- `checks` -> overrides global settings on a per-server basis

### Configuration Reference

| Option | Default | Description |
|--------|---------|-------------|
| `logDir` | `~/.mcp-yoshi/logs` | Log output directory |
| `logLevel` | `info` | `info`: log everything, `warn`: WARN and above, `none`: no logging |
| `checks.outbound.*` | `true` | Enable/disable individual outbound checks |
| `checks.inbound.*` | `true` | Enable/disable individual inbound checks |
| `servers` | `{"*": {"enabled": true}}` | Per-server on/off |
| `severity.WARN` | `["highEntropy", "pii", "suspiciousUrls", ...]` | Check IDs classified as WARN |
| `severity.BLOCK` | `["apiKeys", "privateKeys", "promptInjection", ...]` | Check IDs classified as BLOCK |

## Uninstall

```bash
# Remove hook configuration
mcp-yoshi uninstall

# Remove the package
npm uninstall -g mcp-yoshi
```

## Comparison with Existing Tools

| Tool | Timing | Scope |
|------|--------|-------|
| [mcp-scan](https://github.com/invariantlabs-ai/mcp-scan) | Pre-run (static check) | Tool definition safety |
| [mcp-drift-detector](https://github.com/AshishKumar-ops/mcp-drift-detector) | Periodic (change detection) | Tool definition tampering |
| **mcp-yoshi** | **Real-time (during communication)** | **Safety of transmitted/received data** |

## Security Recommendations

### Regarding `.mcp.json` in External Repositories

When 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.

- Do **not** add servers originating from external `.mcp.json` to the allowlist
- Use them with mcp-yoshi checks enabled
- Review logs for suspicious tool invocations

## Notes

- **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`
- **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
- **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)
- **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

## License

MIT

More