AgentStack
MCP verified MIT Self-run

Mcp Zero

mcp-abwaters-mcp-zero · by abwaters

Enterprise MCP (Model Context Protocol) Gateway — governance, auditing, and data protection for MCP traffic in regulated environments

No reviews yet
0 installs
9 views
0.0% view→install

Install

$ agentstack add mcp-abwaters-mcp-zero

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Mcp Zero? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

mcp-zero

[](https://github.com/abwaters/mcp-zero/actions/workflows/ci.yml) [](https://github.com/abwaters/mcp-zero/actions/workflows/codeql.yml) [](https://securityscorecards.dev/viewer/?uri=github.com/abwaters/mcp-zero) [](LICENSE) [](pyproject.toml)

An open-source gateway that sits between your enterprise AI tools and MCP servers to enforce the security controls that compliance teams require before approving MCP adoption.

Without it, AI tools can call any MCP server with no access control, no audit trail, and no data protection — a non-starter in regulated environments. mcp-zero adds the missing governance layer: it validates user identity, checks policy rules, masks sensitive data, and logs every action — all inline, before requests ever reach downstream servers.

Deploy it as a single Python service. Configure it with a YAML policy file. No agents to install, no SaaS dependency, no vendor lock-in.

Enterprise AI Tool ──► MCP Gateway ──► MCP Servers
                         │
              ┌──────────┴──────────┐
              │   Hook Pipeline     │
              │                     │
              │   Identity  (core)  │
              │   Governance (core) │
              │   ◇ Plugins  (ext)  │
              │   Audit     (core)  │
              └─────────────────────┘

Features

  • Identity — Okta OAuth2 JWT validation with configurable claim mapping (user_id, email, groups)
  • Governance — YAML policy files with default-deny rules scoped to server, tool, user, and group
  • Data Protection — Inline PII and secret masking via Microsoft Presidio on both inputs and outputs
  • Auditing — Structured logs with user attribution, correlation IDs, and policy decisions
  • Transport — Streamable HTTP (primary), legacy inbound SSE (optional), and upstream HTTP/SSE/stdio server connectivity under the same policy pipeline
  • Pipeline — Hook-based request lifecycle with ordered execution and short-circuit support
  • Plugins — Entry-point based plugin architecture for extending the pipeline with custom hooks (masking, rate limiting, metrics, etc.)

Quick Start

Prerequisites

  • Python 3.12+
  • An Okta tenant (for identity validation)

Security Notice

IMPORTANT: The gateway is designed with fail-closed defaults but requires proper configuration to enforce security:

  • Policy file strongly recommended: Set MCP_POLICY_FILE to enable governance and plugin configuration.
  • Fail-closed startup by default: If neither identity nor a policy file is configured, the gateway exits with code 78.
  • Development-only bypasses:
  • MCP_RELAX_STARTUP_CHECKS=true allows startup without security controls.
  • MCP_SKIP_TLS_VALIDATION=true allows non-HTTPS identity/server/OBO URLs.
  • Strict production hardening: MCP_STRICT_SECURITY=true requires both identity and governance to be active.
  • Masking dependencies: Presidio masking requires presidio-analyzer and presidio-anonymizer (included in default install).

Known Limitations (see [security review](docs/securityreviewmcp_gateway.md) for broader analysis):

  • Legacy/development modes can still be enabled intentionally via MCP_RELAX_STARTUP_CHECKS=true and/or MCP_SKIP_TLS_VALIDATION=true; these must not be used in production.
  • OBO token exchange requires explicit environment variables (OKTA_TOKEN_ENDPOINT, OKTA_CLIENT_ID, OKTA_CLIENT_SECRET) and per-server policy configuration.
  • Inbound SSE support remains available for compatibility but is deprecated; disable with MCP_SSE_ENABLED=false if not needed.

Never run production deployments with relaxed startup checks or TLS validation disabled.

Install

# Clone and install
git clone https://github.com/abwaters/mcp-zero.git
cd mcp-zero
python -m venv .venv

# Linux/macOS
source .venv/bin/activate

# Windows
.venv\Scripts\activate

pip install -e ".[dev]"

On Windows, convenience scripts are provided:

scripts\install.bat    # Creates venv and installs everything

Configure

Create a policy file (e.g., policy.yaml):

version: 1
default: deny

identity:
  provider: okta
  issuer: https://your-org.okta.com
  audience: your-app-audience

servers:
  - name: my-mcp-server
    transport: http
    url: https://mcp-server.internal.corp/mcp

policies:
  - id: allow-devs
    description: Allow developers to use read tools
    effect: allow
    subjects:
      groups:
        - developers
    mcp_servers:
      - name: my-mcp-server
        tools:
          - read_*
          - list_*

masking:
  presidio:
    enabled: true
    entities:
      - PERSON
      - EMAIL_ADDRESS
      - PHONE_NUMBER
      - CREDIT_CARD
      - API_KEY
      - PASSWORD

Run

# Set the policy file path
export MCP_POLICY_FILE=policy.yaml

# Start the gateway
python -m mcp_zero
# or
mcp-zero

Or with environment variables for simple setups:

export MCP_UPSTREAM_URL=http://localhost:9000
export OKTA_ISSUER=https://your-org.okta.com
export OKTA_AUDIENCE=your-app-audience
python -m mcp_zero

The gateway starts on 0.0.0.0:8080 by default (configurable via MCP_HOST and MCP_PORT).

Configuration

Environment Variables

| Variable | Description | Default | |---|---|---| | MCP_POLICY_FILE | Path to YAML/JSON policy file | (none) | | MCP_UPSTREAM_URL | Single upstream MCP server URL (legacy fallback) | (none) | | MCP_HOST | Host to bind the gateway | 0.0.0.0 | | MCP_PORT | Port to bind the gateway | 8080 | | MCP_RELAX_STARTUP_CHECKS | Allow startup without required security controls (dev/testing only) | false | | MCP_SKIP_TLS_VALIDATION | Allow http:// issuer/server/OBO URLs (dev/testing only) | false | | MCP_STRICT_SECURITY | Require both identity and governance at startup | false | | MCP_SSE_ENABLED | Enable deprecated inbound SSE endpoints (/mcp/sse*) | true | | LOG_LEVEL | Logging level (DEBUG, INFO, WARNING, ERROR) | INFO | | LOG_FORMAT | Log output format (json or text) | json | | OKTA_ISSUER | Okta token issuer URL (fallback if no policy file) | (none) | | OKTA_AUDIENCE | Expected JWT audience claim (fallback if no policy file) | (none) | | OKTA_TOKEN_ENDPOINT | Okta token exchange endpoint (for OBO) | (none) | | OKTA_CLIENT_ID | Gateway client ID (for OBO) | (none) | | OKTA_CLIENT_SECRET | Gateway client secret (for OBO) | (none) | | ANALYTICS_REDIS_URL | Redis connection URL (enables analytics when set) | (none) | | ANALYTICS_REDIS_CLUSTER | Use Redis Cluster client | false | | ANALYTICS_REDIS_PASSWORD | Redis authentication password | (none) | | ANALYTICS_ENVIRONMENT | Analytics key namespace (e.g. production) | default | | ANALYTICS_GATEWAY_ID | Unique gateway instance ID | (auto-generated) | | ANALYTICS_KEY_PREFIX | Redis key prefix for analytics | mcpgw | | ANALYTICS_RETENTION_SECONDS | TTL for analytics keys in seconds | 3600 | | MCP_CORS_ORIGINS | Comma-separated allowed CORS origins (enables CORS when set) | (none) | | MCP_CORS_ALLOW_CREDENTIALS | Allow credentials in CORS requests | false | | MCP_CORS_MAX_AGE | Preflight cache duration in seconds | 600 |

When MCP_POLICY_FILE is set, its identity section takes precedence over OKTA_* env vars. CORS and analytics env vars override policy values.

Policy File

See [docs/enterprise_mcp_gateway_policy_schema_example.md](docs/enterprisemcpgatewaypolicyschema_example.md) for a full annotated example.

Working examples are available in the [policies/](policies/) directory:

| File | Description | |------|-------------| | [policies/everything.yaml](policies/everything.yaml) | stdio transport with @modelcontextprotocol/server-everything | | [policies/filesystem.yaml](policies/filesystem.yaml) | stdio transport with @modelcontextprotocol/server-filesystem | | [policies/filesystem-redacted.yaml](policies/filesystem-redacted.yaml) | Filesystem server with Presidio masking plugin | | [policies/time.yaml](policies/time.yaml) | stdio transport with @modelcontextprotocol/server-time | | [policies/all.yaml](policies/all.yaml) | Multiple stdio servers combined | | [policies/remote-github.yaml](policies/remote-github.yaml) | Remote GitHub MCP server via Streamable HTTP | | [policies/remote-github-readonly.yaml](policies/remote-github-readonly.yaml) | GitHub server with explicit read-only tool allowlist |

Key concepts:

  • version: Must be 1
  • default: deny (recommended) or allow
  • servers: Downstream MCP server definitions (HTTP or stdio)
  • policies: Ordered rules evaluated top-down; explicit deny overrides allow
  • cors: CORS configuration for browser-based clients (disabled by default)
  • masking: Presidio entity detection configuration (legacy — see plugins below)
  • plugins: Plugin declarations for extensible pipeline hooks (masking, rate limiting, etc.)
CORS Configuration

Add a cors section to the policy file to allow browser-based MCP clients:

cors:
  allow_origins:
    - https://web-ide.corp.com
    - https://dashboard.corp.com
  allow_methods: ["GET", "POST", "OPTIONS"]
  allow_headers: ["Authorization", "Content-Type"]
  allow_credentials: false
  max_age: 600

CORS is disabled by default (fail-closed). Only allow_origins is required; all other fields have safe defaults. Environment variables (MCP_CORS_ORIGINS, MCP_CORS_ALLOW_CREDENTIALS, MCP_CORS_MAX_AGE) override policy file values.

Server Types

HTTP servers — remote MCP servers accessed over Streamable HTTP:

servers:
  - name: remote-api
    transport: http
    url: https://mcp-server.corp/mcp

SSE servers — remote MCP servers over SSE:

servers:
  - name: legacy-sse-server
    transport: sse
    url: https://mcp-server.corp/sse

stdio servers — local processes spawned and managed by the gateway (configured in policy files):

servers:
  - name: local-filesystem
    transport: stdio
    command: npx
    args:
      - -y
      - "@modelcontextprotocol/server-filesystem"
      - /workspace
    env:
      NODE_ENV: production

Development

# Run tests
python -m pytest                          # all tests
python -m pytest tests/masking/ -v        # specific module
python -m pytest tests/test_main.py -v    # specific file

# Lint and format
ruff check src tests
ruff format src tests

# Run the gateway
python -m mcp_zero

On Windows, use the provided scripts:

scripts\test.bat           # Run tests
scripts\lint.bat           # Lint
scripts\format.bat         # Format
scripts\run.bat            # Run gateway

Project Structure

src/mcp_zero/
├── main.py              # Application entry point
├── plugin.py            # Plugin protocol and base class
├── plugin_manager.py    # Plugin discovery and lifecycle
├── context.py           # RequestContext, HookContext, UserIdentity
├── identity/            # Okta JWT validation, OBO token exchange
├── governance/          # Policy loading, evaluation, enforcement
├── masking/             # Masking engine interface and hook
├── plugins/             # Built-in plugins (Presidio masking, GitHub repo filter)
├── pipeline/            # Hook lifecycle, registry, execution
├── proxy/               # Starlette app, server management, tool routing
├── analytics/           # Optional Redis-based analytics
└── transport/           # HTTP, SSE, and stdio MCP transport clients

Architecture

The gateway uses a hook-based pipeline with a plugin system. Core hooks handle identity, governance, and audit. Everything else — masking, rate limiting, metrics — is a plugin loaded from the policy file.

Core hooks (always present):

| Priority | Hook | Phase | Purpose | |----------|------|-------|---------| | 10 | IdentityHook | PREVALIDATION | Validates JWT, resolves user identity | | 50 | GovernanceHook | POSTVALIDATION | Evaluates policy rules, allows or denies | | 145 | AnalyticsHook | PREAUDIT | Records metrics to Redis (when configured) | | 150 | AuditHook | PREAUDIT | Emits structured log with full request context |

Plugin hooks (loaded from policy file plugins: section):

| Priority Range | Slot | Examples | |----------------|------|---------| | 20–49 | Pre-governance | Rate limiting, request validation | | 70–99 | Post-governance | Masking (Presidio at 75), transformation | | 100–139 | General | Metrics, caching, custom hooks |

Hooks execute in priority order. Any hook can short-circuit the pipeline (e.g., governance denial stops processing immediately).

Plugin system: Plugins are discovered via Python entry points (mcp_zero.plugins group), configured in the policy file, and registered into the pipeline at startup. See [docs/plugin-architecture-design.md](docs/plugin-architecture-design.md) for details.

Documentation

| Document | Description | |---|---| | [docs/quickstart.md](docs/quickstart.md) | Step-by-step quickstart with Docker Compose and local paths | | [docs/prd.md](docs/prd.md) | Product requirements and acceptance criteria | | [docs/enterprise_mcp_gateway_architecture_diagram.md](docs/enterprisemcpgatewayarchitecturediagram.md) | Logical architecture with component diagram | | [docs/enterprise_mcp_gateway_implementation_plan_epics.md](docs/enterprisemcpgatewayimplementationplanepics.md) | Phased implementation plan | | [docs/enterprise_mcp_gateway_policy_schema_example.md](docs/enterprisemcpgatewaypolicyschemaexample.md) | Full annotated policy file example | | [docs/enterprise_mcp_gateway_security_compliance_positioning.md](docs/enterprisemcpgatewaysecuritycompliancepositioning.md) | Security controls and compliance alignment | | [docs/enterprise_mcp_gateway_threat_model_canvas.md](docs/enterprisemcpgatewaythreatmodelcanvas.md) | Threat model and mitigations | | [docs/okta_obo_for_an_enterprise_mcp_gateway.md](docs/oktaoboforanenterprisemcpgateway.md) | OBO token exchange deep-dive | | [docs/enterprise_mcp_gateway_leadership_explainer.md](docs/enterprisemcpgatewayleadershipexplainer.md) | Non-technical stakeholder overview | | [docs/configuration-architecture.md](docs/configuration-architecture.md) | Configuration loading, env vars, policy schema, precedence rules | | [docs/cors-configuration.md](docs/cors-configuration.md) | CORS setup for browser-based MCP clients | | [docs/plugins/](docs/plugins/) | Plugin quickstart and per-plugin documentation |

Comparison

How mcp-zero compares to other MCP gateways:

| Capability | mcp-zero | AgentGateway | MintMCP | Microsoft MCP Gateway | Lasso MCP Gateway | |---|---|---|---|---|---| | License | ✅ MIT | ✅ Apache 2.0 (Linux Foundation) | ❌ Commercial SaaS | ✅ MIT | ✅ MIT | | Language | Python | Rust / Go | Proprietary | .NET / C# | Python | | Transport | ✅ Streamable HTTP, stdio | ✅ Streamable HTTP, SSE, stdio | ✅ HTTP, SSE, stdio | Streamable HTTP only | stdio only | | Authentication | ✅ Okta OAuth2 JWT | ✅ JWT, API keys, OAuth (Auth0, Keycloak), MCP auth spec | ✅ OAuth 2.0, SAML, SSO (Okta, Azure AD) | Azure Entra ID / OAuth 2.0 | ❌ None built-in | | Governance | ✅ YAML/JSON policy files, default-deny, server/tool/user/group rules | ✅ RBAC, Cedar policy engine, rate limiting | RBAC/ABAC, Virtual MCP role-based endpoints | RBAC via Entra ID roles | ❌ Plugin-based only | | Data protection | ✅ Inline Presidio masking on inputs and outputs | ❌ None built-in | ✅ PII redaction, secrets scanning, content filtering | ❌ None built-in | Presidio PII + regex secret masking | | Auditing | ✅ Structured logs with user attribution, correlation IDs, policy decisions | ✅ OpenTelemetry met

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.