Metadata-Version: 2.4
Name: agentic-shield
Version: 1.0.0b1
Summary: Security scanner and runtime firewall for AI agents and MCP servers
Project-URL: Homepage, https://github.com/ewibrahim/agentshield
Project-URL: Documentation, https://github.com/ewibrahim/agentshield#readme
Project-URL: Repository, https://github.com/ewibrahim/agentshield
Project-URL: Issues, https://github.com/ewibrahim/agentshield/issues
Project-URL: Changelog, https://github.com/ewibrahim/agentshield/blob/main/CHANGELOG.md
License-Expression: MIT
License-File: LICENSE
Keywords: ai-agents,firewall,guardrails,llm,mcp,scanner,security,tool-poisoning
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: httpx>=0.24.0
Requires-Dist: mcp>=1.0.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: rich>=13.0.0
Requires-Dist: typer>=0.9.0
Provides-Extra: dev
Requires-Dist: mypy>=1.10.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Description-Content-Type: text/markdown

# AgentShield

**Security scanner and runtime firewall for AI agents and MCP servers.**

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![CI](https://github.com/ewibrahim/agentshield/actions/workflows/ci.yml/badge.svg)](https://github.com/ewibrahim/agentshield/actions/workflows/ci.yml)

AgentShield protects your AI coding tools (Claude Code, Cursor, Windsurf, VS Code, Cline, Continue) from malicious MCP servers, tool poisoning, supply chain attacks, and configuration vulnerabilities.

## The Problem

MCP servers are the plugins of AI coding tools. Developers install them from npm, give them access to their codebase, API keys, and databases — and **nobody checks if they're safe**.

- A plugin's tool description can contain **hidden instructions** that trick the AI into exfiltrating your data
- A typosquatted package like `mcp-sevrer-semgrep` silently installs malware
- Hardcoded API keys in config files get committed to git
- A trusted plugin gets **silently updated** with a malicious payload

AgentShield catches all of this.

## Quick Start

```bash
pip install agentshield
```

**Scan your MCP config:**
```bash
# Auto-detect and scan .mcp.json in current directory
agentshield scan

# Scan a specific config file
agentshield scan mcp-config -f .mcp.json

# Scan all AI tool configs in a project
agentshield scan project --dir .
```

**Output:**
```
+-------------------------------- AgentShield --------------------------------+
| Scan Results                                                                |
| Target: .mcp.json                                                           |
| Servers: 4 scanned                                                          |
| Findings: 3 high, 1 medium                                                  |
+-----------------------------------------------------------------------------+

! CFG-NPX-server  Unverified npx install: server
  Uses 'npx -y' which auto-installs packages without verification.
  Fix: Pin the package version explicitly.

! CFG-SECRET-api-KEY  Hardcoded secret in config: API_KEY
  Has env var 'API_KEY' with a hardcoded value.
  Fix: Use environment variable references (${VAR}).
```

## Features

### Scanner (14 Security Checks)

| Check | What it Detects | OWASP Ref |
|-------|----------------|-----------|
| Tool Poisoning | Hidden instructions, invisible unicode, exfiltration URLs, prompt injection | ASI04 |
| Config Audit | `npx -y`, hardcoded secrets, missing binaries, no version pinning | ASI04 |
| Auth Gaps | Destructive tools without auth, unauthenticated HTTP endpoints | ASI03 |
| Transport | Plaintext HTTP, secrets in CLI args | — |
| Tool Exposure | Admin/debug tools, overly broad permissions (shell, file access) | ASI07 |
| Rug Pull | Silent tool definition changes (baseline tracking) | ASI04 |
| Code Execution | Tools enabling arbitrary code execution | ASI05 |
| Data Leakage | PII fields in schemas, bulk data exposure | ASI08 |
| Permission Scope | Dangerous tool combinations (read_file + exec = RCE) | ASI03+07 |
| Cross-Origin | Cross-server escalation, external service interaction | ASI01+09 |
| Schema Validation | Missing schemas, injection-prone fields, unbounded strings | ASI04 |
| Resource Exposure | Sensitive URIs (database://, file://), internal paths | ASI08 |
| Tool Shadowing | Name impersonation via Levenshtein distance, leet-speak | ASI04 |
| npm Verify | Typosquat detection, npm 404 check, deprecated packages | ASI04 |

### Runtime Proxy (Firewall for AI Tool Calls)

AgentShield can sit **between your AI client and MCP servers**, intercepting every tool call:

```bash
# Generate a protected config
agentshield shield --config .mcp.json

# Wraps every server with the proxy:
#   "command": "agentshield"
#   "args": ["proxy", "--server", "name", "--config", ".mcp.json"]
```

Define guardrails in `.agentshield.yml`:

```yaml
guardrails:
  default_action: allow
  rules:
    - name: block-destructive
      action: deny
      tools: ["delete_*", "rm_*", "drop_*"]
      message: "Destructive operations blocked"

    - name: audit-file-writes
      action: audit
      tools: ["write_*", "create_*", "edit_*"]

    - name: block-ssrf
      action: deny
      args_pattern: "169\\.254\\.169\\.254"
      message: "SSRF attempt blocked"

    - name: rate-limit
      action: rate_limit
      tools: ["*"]
      rate: "100/minute"
```

View the audit log:
```bash
agentshield audit
```

### Policy Engine

```yaml
# .agentshield.yml
version: 1
profile: standard  # strict | standard | minimal

checks:
  disabled:
    - transport-security

severity_overrides:
  "CFG-BINARY-*": low

ignore:
  - check_id: config-audit
    server: local-dev-server

custom_rules:
  - name: no-localhost
    pattern: "localhost"
    target: args
    severity: high
    message: "No localhost in production configs"

fail_on: medium
```

### More Commands

```bash
# Auto-fix security issues
agentshield fix -f .mcp.json
agentshield fix -f .mcp.json --no-dry-run  # Apply fixes

# Compare scan results over time
agentshield scan mcp-config -f .mcp.json --format json -o baseline.json
# ... make changes ...
agentshield scan mcp-config -f .mcp.json --format json -o current.json
agentshield diff baseline.json current.json

# Watch for config changes in real-time
agentshield watch -f .mcp.json

# Machine-wide inventory of all MCP servers
agentshield inventory

# Convert configs between AI tools
agentshield convert -f .mcp.json --from claude --to cursor

# List compliance profiles
agentshield profiles

# Generate a secure config template
agentshield init --format claude
```

### Output Formats

| Format | Flag | Use Case |
|--------|------|----------|
| Text | `--format text` | Terminal (default) |
| JSON | `--format json` | Programmatic consumption |
| SARIF | `--format sarif` | GitHub Security tab |
| HTML | `--format html` | Shareable reports |
| Markdown | `--format markdown` | PR comments, docs |

## CI/CD Integration

### GitHub Action

```yaml
- uses: ewibrahim/agentshield@v1
  with:
    file: .mcp.json
    fail-on: high
    sarif-output: agentshield.sarif

- uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: agentshield.sarif
```

### Pre-commit Hook

```yaml
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/ewibrahim/agentshield
    rev: v1.0.0
    hooks:
      - id: agentshield
```

### CI Pipeline

```bash
pip install agentshield
agentshield scan mcp-config -f .mcp.json --ci --fail-on high
```

## Supported AI Tools

| Tool | Config Path | Auto-detected |
|------|------------|---------------|
| Claude Code | `.mcp.json` | Yes |
| Cursor | `.cursor/mcp.json` | Yes |
| Windsurf | `.windsurf/mcp.json` | Yes |
| VS Code | `.vscode/mcp.json` | Yes |
| Cline | `.cline/mcp_settings.json` | Yes |
| Continue | `.continue/config.json` | Yes |

## Plugin System

Create custom checks and distribute them as pip packages:

```python
# my_plugin/checks.py
from agentshield.checks.base import BaseCheck, CheckContext
from agentshield.core.models import Finding

class MyCustomCheck(BaseCheck):
    id = "my-custom-check"
    name = "My Custom Check"
    requires_connection = True

    async def run(self, context: CheckContext) -> list[Finding]:
        # Your check logic here
        return []
```

```toml
# pyproject.toml
[project.entry-points."agentshield.checks"]
my_check = "my_plugin.checks:MyCustomCheck"
```

## Testing

```bash
pip install -e ".[dev]"
pytest tests/ -v
```

Full test suite covering all 14 security checks, policy engine, guardrails, proxy, converter, and diff engine.

## Architecture

```
agentshield/
  cli.py               # Typer CLI (13 commands)
  core/
    scanner.py          # Orchestrator
    models.py           # Pydantic data models
    mcp_client.py       # MCP connection (read-only, never calls tools)
    guardrails.py       # Runtime rule engine
    proxy.py            # MCP stdio proxy
    policy.py           # .agentshield.yml loading
    scoring.py          # Risk scoring (0-100)
    report.py           # Text/JSON/SARIF formatters
    ...
  checks/
    base.py             # BaseCheck ABC
    mcp/                # 14 security checks
  db/
    known_tools.json    # Known MCP tool definitions
    known_mcp_packages.json  # Known npm packages
```

**Safety constraint:** AgentShield **never calls `call_tool()`** on MCP servers. It only reads metadata via `list_tools()`, `list_resources()`, and `list_prompts()`.

## Contributing

Contributions welcome! Please open an issue first to discuss what you'd like to change.

## License

[MIT](LICENSE)
