{
  "markdown": "# Code Firewall MCP\n\n<!-- mcp-name: io.github.egoughnour/code-firewall-mcp -->\n\n[![PyPI](https://img.shields.io/pypi/v/code-firewall-mcp?style=flat-square&logo=pypi&logoColor=white)](https://pypi.org/project/code-firewall-mcp/)\n[![Claude Desktop](https://img.shields.io/badge/Claude-Desktop-orange?style=flat-square&logo=anthropic&logoColor=white)](https://github.com/egoughnour/code-firewall-mcp/releases/latest/download/code-firewall-mcp.mcpb)\n[![Tests](https://img.shields.io/github/actions/workflow/status/egoughnour/code-firewall-mcp/test.yml?style=flat-square&logo=github-actions&label=Tests)](https://github.com/egoughnour/code-firewall-mcp/actions/workflows/test.yml)\n[![Release](https://img.shields.io/github/actions/workflow/status/egoughnour/code-firewall-mcp/release.yml?style=flat-square&logo=github-actions&label=Release)](https://github.com/egoughnour/code-firewall-mcp/actions/workflows/release.yml)\n[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue?style=flat-square&logo=python&logoColor=white)](https://www.python.org/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)\n\n[![Top Language](https://img.shields.io/github/languages/top/egoughnour/code-firewall-mcp?style=flat-square&color=3379ef)](https://github.com/egoughnour/code-firewall-mcp/languages) [![Code Size](https://img.shields.io/github/languages/code-size/egoughnour/code-firewall-mcp?style=flat-square&color=3379ef)](https://github.com/egoughnour/code-firewall-mcp) [![Last Commit](https://img.shields.io/github/last-commit/egoughnour/code-firewall-mcp?style=flat-square&color=2579ef&logo=github)](https://github.com/egoughnour/code-firewall-mcp/commits/main) [![Repository Size](https://img.shields.io/github/repo-size/egoughnour/code-firewall-mcp?style=flat-square&color=3379ef)](https://github.com/egoughnour/code-firewall-mcp)\n\n\nA structural similarity-based code security filter for MCP (Model Context Protocol). Blocks dangerous code patterns before they reach execution tools by comparing code structure against a blacklist of known-bad patterns.\n\n## How It Works\n\n```mermaid\nflowchart LR\n    A[Code<br/>file/string] --> B[Parse & Normalize<br/>tree-sitter]\n    B --> C[Embed<br/>Ollama]\n    C --> D{Similarity Check<br/>vs Blacklist}\n    D -->|≥ threshold| E[🚫 BLOCKED]\n    D -->|< threshold| F[✅ ALLOWED]\n    F --> G[Execution Tools<br/>rlm_exec, etc.]\n\n    style E fill:#ff6b6b,color:#fff\n    style F fill:#51cf66,color:#fff\n    style D fill:#339af0,color:#fff\n```\n\n1. **Parse** code to Concrete Syntax Tree (CST) using tree-sitter\n2. **Normalize** by stripping identifiers and literals → structural skeleton\n3. **Embed** the normalized structure via Ollama\n4. **Compare** against blacklisted patterns in ChromaDB\n5. **Block** if similarity exceeds threshold, otherwise **allow**\n\n## Key Insight\n\nCode patterns like `os.system(\"rm -rf /\")` and `os.system(\"ls\")` have **identical structure**. By normalizing away the specific commands/identifiers, we can detect dangerous patterns regardless of the specific arguments used.\n\n**Security-sensitive identifiers are preserved** during normalization (e.g., `eval`, `exec`, `os`, `system`, `subprocess`, `Popen`, `shell`) to ensure embeddings remain discriminative for dangerous patterns.\n\n## Installation\n\n### Quick Start\n\n**Option 1: PyPI (Recommended)**\n\n```bash\nuvx code-firewall-mcp\n# or\npip install code-firewall-mcp\n```\n\n**Option 2: Claude Desktop One-Click**\n\nDownload the `.mcpb` from [Releases](https://github.com/egoughnour/code-firewall-mcp/releases) and double-click to install.\n\n**Option 3: From Source**\n\n```bash\ngit clone https://github.com/egoughnour/code-firewall-mcp.git\ncd code-firewall-mcp\nuv sync\n```\n\n### Wire to Claude Code / Claude Desktop\n\nAdd to `~/.claude/.mcp.json` (Claude Code) or `claude_desktop_config.json` (Claude Desktop):\n\n```json\n{\n  \"mcpServers\": {\n    \"code-firewall\": {\n      \"command\": \"uvx\",\n      \"args\": [\"code-firewall-mcp\"],\n      \"env\": {\n        \"FIREWALL_DATA_DIR\": \"~/.code-firewall\",\n        \"OLLAMA_URL\": \"http://localhost:11434\"\n      }\n    }\n  }\n}\n```\n\n## Requirements\n\n- Python 3.10+ (< 3.14 due to onnxruntime compatibility)\n- Ollama (for embeddings)\n- ChromaDB (for vector storage)\n- tree-sitter (optional, for better parsing)\n\n## Setting Up Ollama (Embeddings)\n\nCode Firewall can automatically install and configure Ollama on macOS with Apple Silicon. There are **two installation methods**:\n\n### Method 1: Homebrew Installation\n\n```python\n# 1. Check system requirements\nfirewall_system_check()\n\n# 2. Install via Homebrew\nfirewall_setup_ollama(install=True, start_service=True, pull_model=True)\n```\n\n**What this does:**\n- Installs Ollama via Homebrew (`brew install ollama`)\n- Starts Ollama as a managed background service\n- Pulls nomic-embed-text model for embeddings\n\n### Method 2: Direct Download (No Sudo)\n\n```python\n# 1. Check system\nfirewall_system_check()\n\n# 2. Install via direct download - no sudo, no Homebrew\nfirewall_setup_ollama_direct(install=True, start_service=True, pull_model=True)\n```\n\n**What this does:**\n- Downloads Ollama from https://ollama.com\n- Extracts to `~/Applications/` (no admin needed)\n- Starts Ollama via `ollama serve`\n- Pulls nomic-embed-text model\n\n### Manual Setup\n\n```bash\n# Install Ollama\nbrew install ollama\n# or download from https://ollama.ai\n\n# Start service\nbrew services start ollama\n# or: ollama serve\n\n# Pull embedding model\nollama pull nomic-embed-text\n\n# Verify\nfirewall_ollama_status()\n```\n\n## Tools\n\n### Setup & Status Tools\n\n| Tool | Purpose |\n|------|---------|\n| `firewall_system_check` | **Check system requirements** — verify macOS, Apple Silicon, RAM |\n| `firewall_setup_ollama` | **Install via Homebrew** — managed service, auto-updates |\n| `firewall_setup_ollama_direct` | **Install via direct download** — no sudo, fully headless |\n| `firewall_ollama_status` | **Check Ollama availability** — verify embeddings are ready |\n\n### Firewall Tools\n\n| Tool | Purpose |\n|------|---------|\n| `firewall_check` | Check if a code file is safe to execute |\n| `firewall_check_code` | Check code string directly (no file required) |\n| `firewall_blacklist` | Add a dangerous pattern to the blacklist |\n| `firewall_record_delta` | Record near-miss variants for classifier sharpening |\n| `firewall_list_patterns` | List patterns in blacklist or delta collection |\n| `firewall_remove_pattern` | Remove a pattern from blacklist or deltas |\n| `firewall_status` | Get firewall status and statistics |\n\n### `firewall_check`\nCheck if a code file is safe to pass to execution tools.\n\n```python\nresult = await firewall_check(file_path=\"/path/to/script.py\")\n# Returns: {allowed: bool, blocked: bool, similarity: float, ...}\n```\n\n### `firewall_check_code`\nCheck code string directly (no file required).\n\n```python\nresult = await firewall_check_code(\n    code=\"import os; os.system('rm -rf /')\",\n    language=\"python\"\n)\n```\n\n### `firewall_blacklist`\nAdd a dangerous pattern to the blacklist.\n\n```python\nresult = await firewall_blacklist(\n    code=\"os.system(arbitrary_command)\",\n    reason=\"Arbitrary command execution\",\n    severity=\"critical\"\n)\n```\n\n### `firewall_record_delta`\nRecord near-miss variants to sharpen the classifier.\n\n```python\nresult = await firewall_record_delta(\n    code=\"subprocess.run(['ls', '-la'])\",\n    similar_to=\"abc123\",\n    notes=\"Legitimate use case for file listing\"\n)\n```\n\n### `firewall_list_patterns`\nList patterns in the blacklist or delta collection.\n\n### `firewall_remove_pattern`\nRemove a pattern from blacklist or deltas.\n\n### `firewall_status`\nGet firewall status and statistics.\n\n## Configuration\n\nEnvironment variables:\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `FIREWALL_DATA_DIR` | `/tmp/code-firewall` | Data storage directory |\n| `OLLAMA_URL` | `http://localhost:11434` | Ollama server URL |\n| `EMBEDDING_MODEL` | `nomic-embed-text` | Ollama embedding model |\n| `SIMILARITY_THRESHOLD` | `0.85` | Block threshold (0-1) |\n| `NEAR_MISS_THRESHOLD` | `0.70` | Near-miss recording threshold |\n\n## Usage Pattern\n\n### Pre-filter for massive-context-mcp\n\nUse code-firewall-mcp as a gatekeeper before passing code to `rlm_exec`:\n\n```python\n# 1. Check code safety\ncheck = await firewall_check_code(user_code)\n\nif check[\"blocked\"]:\n    print(f\"BLOCKED: {check['reason']}\")\n    return\n\n# 2. If allowed, proceed with execution\nresult = await rlm_exec(code=user_code, context_name=\"my-context\")\n```\n\n### Integrated with massive-context-mcp\n\nInstall massive-context-mcp with firewall integration:\n\n```bash\npip install massive-context-mcp[firewall]\n```\n\nWhen enabled, `rlm_exec` automatically checks code against the firewall before execution.\n\n### Building the Blacklist\n\nThe blacklist grows through use:\n\n1. **Initial seeding**: Add known dangerous patterns\n2. **Audit feedback**: When `rlm_auto_analyze` finds security issues, add patterns\n3. **Delta sharpening**: Record near-misses to improve classification boundaries\n\n```python\n# After security audit finds issues\nawait firewall_blacklist(\n    code=dangerous_code,\n    reason=\"Command injection via subprocess\",\n    severity=\"critical\"\n)\n```\n\n## Structural Normalization\n\n```mermaid\nflowchart TD\n    subgraph Input\n        A1[\"os.system('rm -rf /')\"]\n        A2[\"os.system('ls -la')\"]\n        A3[\"os.system(user_cmd)\"]\n    end\n\n    subgraph Normalization\n        B[Strip literals & identifiers<br/>Preserve security keywords]\n    end\n\n    subgraph Output\n        C[\"os.system('S')\"]\n    end\n\n    A1 --> B\n    A2 --> B\n    A3 --> B\n    B --> C\n\n    style C fill:#ff922b,color:#fff\n```\n\nThe normalizer strips:\n- **Identifiers**: `my_var` → `_` (except security-sensitive ones)\n- **String literals**: `\"hello\"` → `\"S\"`\n- **Numbers**: `42` → `N`\n- **Comments**: Removed entirely\n\n**Preserved identifiers** (for better pattern matching):\n- `eval`, `exec`, `compile`, `__import__`\n- `os`, `system`, `popen`, `subprocess`, `Popen`, `shell`\n- `open`, `read`, `write`, `socket`, `connect`\n- `getattr`, `setattr`, `__globals__`, `__builtins__`\n- And more security-sensitive names...\n\nExample:\n```python\n# Original\nsubprocess.run([\"curl\", url, \"-o\", output_file])\n\n# Normalized (preserves 'subprocess' and 'run')\nsubprocess.run([\"S\", _, \"S\", _])\n```\n\nBoth `subprocess.run([\"curl\", ...])` and `subprocess.run([\"wget\", ...])` normalize to the same structure, so blacklisting one catches both.\n\n## License\n\nMIT\n",
  "bytes": 10433,
  "sha": "f2f1b99b85101bef40426a8ba4e1b366a37eb808358f8a0e199348c9d95b7ca7",
  "repo_slug": "egoughnour/code-firewall-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_egoughnour_code_firewall_mcp_331d618b/readme"
}