# Mcp Gateway

> Zero trust gateway for MCP servers. Aggregate, filter, and securely access MCP tools from anywhere without VPNs, open ports, or exposed endpoints. Built on OpenZiti, zrok, and Agora with cryptographic identity, mTLS, per-client isolation, and tool-level permission control.

- **Type:** MCP server
- **Install:** `agentstack add mcp-openziti-mcp-gateway`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [openziti](https://agentstack.voostack.com/s/openziti)
- **Installs:** 0
- **Category:** [Security](https://agentstack.voostack.com/c/security)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [openziti](https://github.com/openziti)
- **Source:** https://github.com/openziti/mcp-gateway

## Install

```sh
agentstack add mcp-openziti-mcp-gateway
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# MCP Gateway

**Zero-trust access to MCP tools over OpenZiti**

MCP Gateway lets AI assistants securely access internal tools without exposing public endpoints. Built on OpenZiti, zrok, and [Agora](https://github.com/openziti/agora), it provides cryptographically secure, zero trust connectivity with no attack surface.

MCP Gateway is sponsored by [NetFoundry](https://netfoundry.io) as part of its portfolio of solutions for secure workloads and agentic computing. NetFoundry is the creator of [OpenZiti](https://netfoundry.io/docs/openziti/) and [zrok](https://netfoundry.io/docs/zrok/getting-started).

## The Trifecta

Three simple components that work together:

| Component | Purpose |
|-----------|---------|
| **mcp-tools** | Connects MCP clients to remote zrok shares or Agora tunnels (stdio or HTTP) |
| **mcp-gateway** | Aggregates multiple backends into one secure endpoint over zrok and/or Agora |
| **mcp-bridge** | Exposes a single MCP server to the network over zrok or Agora |

```mermaid
flowchart LR
    A[Agent] -->|stdio| B[mcp-tools]
    B -->|zrok or Agora| C[mcp-gateway]
    C -->|stdio / zrok / Agora / HTTP| D[MCP Servers]
    C -->|https| E[Remote MCP APIs]
```

## Why?

**Problem:** MCP servers typically run locally via stdio. To access tools on remote machines or share them across a team, you need to expose endpoints—creating security risks. Securing exposed MCP tooling can be complicated.

**Solution:** MCP Gateway uses OpenZiti's overlay network to create "dark services" that:
- Never listen on public IPs
- Require cryptographic identity to access
- Work through NATs and firewalls without port forwarding
- Can publish and serve through Agora catalogs and Layer 1 tunnels
- Are incredibly simple to deploy securely

## Quick Start

> **New to MCP Gateway?** See the [Getting Started Guide](docs/current/getting-started.md) for a complete walkthrough.

### 1. Install

```bash
go install github.com/openziti/mcp-gateway/cmd/...@latest
```

### 2. Enable zrok

> **Note:** mcp-gateway requires zrok `v2.0.x` or later. Currently the best release is [zrok v2.0.0-rc7](https://github.com/openziti/zrok/releases/tag/v2.0.0-rc7)

```bash
zrok2 enable   # get token at https://api-v2.zrok.io
```

### 3. Run a Gateway

Create `config.yml`:
```yaml
aggregator:
  name: "my-gateway"
  version: "1.0.0"

backends:
  - id: filesystem
    transport:
      type: stdio
      command: npx
      args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/documents"]

  - id: github
    transport:
      type: stdio
      command: npx
      args: ["-y", "@modelcontextprotocol/server-github"]
      env:
        GITHUB_TOKEN: "ghp_xxx"
```

```bash
mcp-gateway run config.yml
# outputs: {"share_token":"abc123..."}
```

### 4. Connect from Agent

Add to agent config:
```json
{
  "mcpServers": {
    "my-tools": {
      "command": "mcp-tools",
      "args": ["run", "abc123..."]
    }
  }
}
```

That's it. Your agent can now use tools from both backends through a single secure connection.

## Use Cases

### Aggregate Multiple Tool Servers

Combine filesystem, GitHub, database, and custom tools into one connection:

```yaml
backends:
  - id: fs
    transport: { type: stdio, command: mcp-server-filesystem, args: ["/data"] }
  - id: github
    transport: { type: stdio, command: mcp-server-github }
  - id: postgres
    transport: { type: stdio, command: mcp-server-postgres }
```

Tools are namespaced automatically: `fs:read_file`, `github:create_issue`, `postgres:query`.

### Expose a Remote Tool Server

Run mcp-bridge on a remote machine to expose a local MCP server:

```bash
# on remote server
mcp-bridge mcp-server-custom --config /etc/custom.yml
# outputs share token

# from anywhere
mcp-tools run 
```

### Chain Bridges and Gateways

Gateway can connect to remote bridges (or other gateways) as backends:

```yaml
backends:
  - id: remote-tools
    transport:
      type: zrok
      share_token: "token-from-bridge"
```

### Serve and Discover Through Agora

Gateway, bridge, and tools can use Agora Layer 1 tunnels in addition to zrok. A gateway can serve over zrok and Agora at the same time, publish a catalog advertisement, and connect to backends exposed by `mcp-bridge --network=agora`.

```yaml
agora:
  enabled: true
  serve:
    enabled: true
  advertisement:
    publish: true

backends:
  - id: remote-filesystem
    transport:
      type: agora
      agora_tunnel: filesystem-relay
```

```bash
mcp-tools run --agora mcp-gateway-engineering
```

See [Agora Integration](docs/current/agora.md) for configuration, CLI flags, integration files, and smoke scenarios.

### Connect to HTTP and HTTPS MCP Servers

Gateway can aggregate remote MCP servers over HTTP(S), using either SSE or streamable HTTP transport. `type: https` is strict and only accepts `https://` endpoints. `type: http` supports both `http://` and `https://`, but plaintext HTTP requires explicit opt-in.

```yaml
backends:
  - id: remote-api
    transport:
      type: https
      endpoint: "https://mcp.example.com/sse"
      headers:
        Authorization: "Bearer sk-abc123"

  - id: internal-api
    transport:
      type: https
      endpoint: "https://mcp.internal.corp/mcp"
      protocol: "streamable"
      tls:
        ca_cert_file: "/etc/ssl/certs/internal-ca.pem"
```

This works alongside stdio and zrok backends — mix and match as needed.

For local development or trusted internal networks, you can opt into plaintext HTTP explicitly:

```yaml
backends:
  - id: local-dev
    transport:
      type: http
      endpoint: "http://localhost:8080/sse"
      allow_insecure: true
```

### Persistent Shares

By default, `mcp-gateway` and `mcp-bridge` create an ephemeral share that disappears when the process exits. **Persistent shares** are stored server-side in zrok, so a gateway or bridge can stop and restart without changing the share token.

```bash
# create a persistent share with a chosen name
zrok2 create share my-gateway
# outputs the share token

# use the token in a gateway config (share_token: my-gateway) or bridge
mcp-gateway run config.yml
mcp-bridge --share-token my-gateway npx -y @modelcontextprotocol/server-filesystem /home/user

# the gateway/bridge can restart and reconnect to the same share

# when done, delete the share
zrok2 delete share my-gateway
```

If you omit the name, zrok generates a random token:

```bash
zrok2 create share
# outputs the share token
```

The token name must be 3–32 characters, lowercase alphanumeric and hyphens (`[a-z0-9-]`).

### HTTP Transport

All components support HTTP-based MCP transport in addition to stdio.

**Serve via HTTP with mcp-tools:**
```bash
# expose a zrok share as a local HTTP server
mcp-tools http  --bind 127.0.0.1:8080

# expose an Agora tunnel as a local HTTP server
mcp-tools http --agora  --bind 127.0.0.1:8080
```

Options:
- `--stateless` - Stateless mode (no session persistence)
- `--json-response` - Prefer JSON responses over SSE streams

The gateway and bridge natively serve MCP over HTTP/SSE through zrok. Use `mcp-tools http` when you need a local HTTP endpoint for clients that don't support the `stdio` transport provided by `mcp-tools` directly.

## Tool Filtering

Control which tools are exposed per backend:

```yaml
backends:
  - id: filesystem
    transport: { type: stdio, command: mcp-server-filesystem }
    tools:
      mode: allow
      list:
        - "read_file"
        - "list_directory"
        # write operations not exposed

  - id: github
    tools:
      mode: deny
      list:
        - "delete_*"
        # everything except delete operations
```

## Architecture

MCP Gateway creates isolated sessions for each connecting client:

```mermaid
flowchart LR
    subgraph Clients
        A[Client A]
        B[Client B]
    end

    A --> G[Gateway]
    B --> G

    subgraph Session A
        G --> A1[Backend 1]
        G --> A2[Backend 2]
    end

    subgraph Session B
        G --> B1[Backend 1]
        G --> B2[Backend 2]
    end
```

Each client gets dedicated backend connections—no shared state, no cross-talk.

## Building from Source

```bash
git clone https://github.com/openziti/mcp-gateway.git
cd mcp-gateway
go build ./cmd/mcp-gateway
go build ./cmd/mcp-bridge
go build ./cmd/mcp-tools
```

## Documentation

- [Example Configuration](etc/mcp-gateway.yml) - Fully documented configuration file
- [Agora Integration](docs/current/agora.md) - Agora serving, backend connects, mcp-tools dialing, and smoke scenarios
- [OpenZiti Documentation](https://openziti.io/docs)
- [zrok Documentation](https://docs.zrok.io)
- [MCP Specification](https://modelcontextprotocol.io)

## License

Apache 2.0 - see [LICENSE](LICENSE)

## Source & license

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

- **Author:** [openziti](https://github.com/openziti)
- **Source:** [openziti/mcp-gateway](https://github.com/openziti/mcp-gateway)
- **License:** Apache-2.0

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

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-openziti-mcp-gateway
- Seller: https://agentstack.voostack.com/s/openziti
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
