Metadata-Version: 2.4
Name: mcpshield
Version: 0.2.5
Summary: MCPShield - Secure access for AI agents with deterministic policy enforcement
Author-email: MCPShield <support@mcpshield.xyz>
License: MIT
Project-URL: Homepage, https://mcpshield.xyz
Project-URL: Documentation, https://mcpshield.xyz/docs
Project-URL: Issues, https://github.com/thisise/mcpshield/issues
Keywords: mcp,security,postgres,ai,gateway,policy
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Classifier: Topic :: Database
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: PyYAML>=6.0
Requires-Dist: psycopg[binary]>=3.1.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: sqlparse>=0.4.4
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
Requires-Dist: build>=1.0.0; extra == "dev"
Requires-Dist: twine>=4.0.0; extra == "dev"
Dynamic: license-file

# MCPShield

Secure PostgreSQL access for AI agents with deterministic policy enforcement and comprehensive auditing.

## Features

- **MCP Server**: Claude Code compatible stdio protocol
- **PostgreSQL Tools**: Safe, policy-enforced database access
- **Fail-Closed Policy Engine**: YAML-based security rules with default deny
- **Centralized Policy Management**: Policies authored in dashboard, automatically synced
- **Audit Trail**: Complete event logging to MCPShield control plane with policy_hash tracking
- **Event Spooling**: Never lose audit events, even when offline
- **Developer-Friendly**: Clear logs, helpful errors, easy configuration

## Quick Start

### Installation

```bash
pip install mcpshield
```

### Super Quick Setup (Interactive)

The easiest way to get started:

```bash
mcpshield init
```

This interactive wizard will:
- Configure your PostgreSQL connection
- Set up your MCPShield API key
- Automatically integrate with Claude Code and/or Cursor
- Test your configuration

### Setup (Environment Variables - Recommended)

**No configuration file needed!** Just set environment variables and run.

1. **Create project and policy in MCPShield dashboard**:
   - Go to https://app.mcpshield.xyz
   - Create project → Get Project ID
   - Create policy → Define security rules
   - Create API key

2. **Set environment variables**:

   **macOS/Linux:**
   ```bash
   export PG_DSN="postgresql://user:pass@localhost:5432/dbname"
   export MCPSHIELD_API_KEY="mcps_your_key"
   export PROJECT_ID="proj_your_id"
   export API_BASE_URL="https://api.mcpshield.xyz"  # Optional, this is the default
   ```

   **Windows (PowerShell):**
   ```powershell
   $env:PG_DSN = "postgresql://user:pass@localhost:5432/dbname"
   $env:MCPSHIELD_API_KEY = "mcps_your_key"
   $env:PROJECT_ID = "proj_your_id"
   $env:API_BASE_URL = "https://api.mcpshield.xyz"  # Optional, this is the default
   ```

   **Or use a .env file:**
   ```bash
   # .env
   PG_DSN=postgresql://user:pass@localhost:5432/dbname
   MCPSHIELD_API_KEY=mcps_your_key
   PROJECT_ID=proj_your_id
   API_BASE_URL=https://api.mcpshield.xyz
   POLICY_SOURCE=remote
   ```

3. **Verify setup**:
   ```bash
   mcpshield doctor

   # Or with .env file:
   mcpshield doctor --env-file .env
   ```

4. **Run the gateway**:
   ```bash
   mcpshield serve

   # Or with .env file:
   mcpshield serve --env-file .env
   ```

### Setup (YAML Config - Optional)

For advanced users who prefer a configuration file, you can create `mcpshield.yaml`:

```yaml
database:
  dsn: null  # Set via PG_DSN env var

api:
  base_url: "https://api.mcpshield.xyz"
  project_id: null  # Set via PROJECT_ID env var
  api_key: null  # Set via MCPSHIELD_API_KEY env var

policy:
  source: "remote"
  refresh_seconds: 60

# Optional: local policy file for fallback
# policy:
#   source: "remote_with_fallback"
#   file: "policy.yaml"
```

Then run with `--config`:
```bash
mcpshield doctor --config mcpshield.yaml
mcpshield serve --config mcpshield.yaml
```

### Claude Code Integration

Add to your Claude Code MCP configuration (`~/.claude/mcp.json`):

**Option 1: Environment Variables Only (Recommended)**
```json
{
  "mcpServers": {
    "mcpshield": {
      "command": "mcpshield",
      "args": ["serve"],
      "env": {
        "PG_DSN": "postgresql://user:pass@localhost:5432/db",
        "MCPSHIELD_API_KEY": "mcps_...",
        "PROJECT_ID": "proj_...",
        "API_BASE_URL": "https://api.mcpshield.xyz"
      }
    }
  }
}
```

**Option 2: With .env File**
```json
{
  "mcpServers": {
    "mcpshield": {
      "command": "mcpshield",
      "args": ["serve", "--env-file", "/path/to/.env"]
    }
  }
}
```

**Option 3: With YAML Config**
```json
{
  "mcpServers": {
    "mcpshield": {
      "command": "mcpshield",
      "args": ["serve", "--config", "/path/to/mcpshield.yaml"],
      "env": {
        "PG_DSN": "postgresql://user:pass@localhost:5432/db",
        "MCPSHIELD_API_KEY": "mcps_...",
        "PROJECT_ID": "proj_..."
      }
    }
  }
}
```

## How Policy Synchronization Works

```
┌──────────────────────────────────────────────────────────────┐
│                     MCPShield Dashboard                      │
│                                                              │
│  1. Author policy in UI                                      │
│  2. Save policy (stored in database)                         │
│  3. policy_hash computed (SHA-256)                           │
└──────────────────────────┬───────────────────────────────────┘
                           │
                           │ GET /projects/{id}/policy
                           │
                           ▼
                  ┌────────────────────┐
                  │  MCPShield Gateway │
                  │                    │
                  │  On startup:       │
                  │  • Fetch policy    │
                  │  • Cache locally   │
                  │  • Compute hash    │
                  │                    │
                  │  Every 60s:        │
                  │  • Re-fetch policy │
                  │  • Update cache    │
                  │  • Update hash     │
                  └────────────────────┘
                           │
                           │ Every request includes:
                           │ • decision (allow/deny)
                           │ • policy_hash
                           │
                           ▼
                  ┌────────────────────┐
                  │   Audit Events     │
                  │                    │
                  │  {                 │
                  │    decision: allow │
                  │    policy_hash:... │
                  │  }                 │
                  └────────────────────┘
```

## Configuration

### Environment Variables

MCPShield supports configuration via environment variables (no YAML file required):

**Required:**
- `PG_DSN` or `DATABASE_URL` - PostgreSQL connection string
- `PROJECT_ID` - Your MCPShield project ID
- `MCPSHIELD_API_KEY` - Your MCPShield API key

**Optional:**
- `API_BASE_URL` - API endpoint (default: `https://api.mcpshield.xyz`)
- `POLICY_SOURCE` - Policy source: `remote`, `remote_with_fallback`, or `local` (default: `remote`)
- `POLICY_FILE` - Path to local policy file (for fallback)
- `POLICY_REFRESH_SECONDS` - Policy refresh interval (default: `60`)
- `SPOOL_DIR` - Event spool directory (default: `~/.mcpshield/spool`)
- `POLICY_CACHE_DIR` - Policy cache directory (default: `~/.mcpshield/cache`)
- `LOG_LEVEL` - Logging level: `DEBUG`, `INFO`, `WARNING`, `ERROR` (default: `INFO`)
- `LOG_DECISIONS` - Log policy decisions: `true` or `false` (default: `true`)
- `BATCH_SIZE` - Event batch size (default: `10`)
- `BATCH_TIMEOUT` - Event batch timeout in seconds (default: `5`)

### Policy Source Options

**`remote`** (Recommended - Default):
- Fetches policy from MCPShield API only
- **No local policy file needed**
- Fails if API unreachable (fail-closed)
- Always uses latest policy from dashboard
- Policy cached locally at `~/.mcpshield/cache/policy.yaml`

**`remote_with_fallback`**:
- Tries API first
- Falls back to cached policy if API fails
- Falls back to local file if cache unavailable
- Provides resilience during API outages

**`local`**:
- Uses local policy file only
- No API calls
- Useful for offline development
- Requires `POLICY_FILE` to be set

### Fail-Closed Behavior

Gateway WILL NOT start if:
- Policy source is `remote` and API is unreachable (and no cache exists)
- Policy source is `remote_with_fallback` and ALL of: API fails, no cache, no local file
- This ensures gateway never operates without a policy

## Documentation

- **User Guide**: https://mcpshield.xyz/docs
- **Policy Syntax**: https://mcpshield.xyz/docs/policy
- **Troubleshooting**: https://mcpshield.xyz/docs/troubleshooting

## Security

MCPShield is designed with security-first principles:

- **Default Deny**: All operations blocked unless explicitly allowed
- **Read-Only Enforcement**: Blocks destructive SQL keywords
- **Schema Validation**: Only access allowed tables
- **Data Redaction**: Remove sensitive data (emails, phones) from results
- **Rate Limiting**: Enforce query limits and timeouts
- **Audit Everything**: Complete audit trail with policy_hash tracking

## CLI Commands

```bash
# Run the gateway (env vars only)
mcpshield serve

# Run the gateway (with .env file)
mcpshield serve --env-file .env

# Run the gateway (with YAML config)
mcpshield serve --config mcpshield.yaml

# Validate configuration
mcpshield validate
mcpshield validate --env-file .env
mcpshield validate --config mcpshield.yaml

# Run diagnostics
mcpshield doctor
mcpshield doctor --env-file .env
mcpshield doctor --config mcpshield.yaml

# Get version
mcpshield --version
```

## Support

- Documentation: https://mcpshield.xyz/docs
- Issues: Report via MCPShield support channels

## License

MIT License - see LICENSE file for details
