io.github.authzx/mcp-gateway
AuthzX MCP Gateway — policy-enforcing proxy between AI agents and MCP servers
Open source Open in the app JSON README (API)
About
AuthzX MCP Gateway — policy-enforcing proxy between AI agents and MCP servers
Details
- Kind
- MCP servers
- Topic
- AI, RAG & memory
- Publisher
- authzx
- Origin
- official
- Category
- ferramentas
- Transport
- local
- Version
- 1.0.1
- Last push
- 2026-08-14T17:22:41Z
- Repository state
- ativo
- Language
- TypeScript
- License
- Apache-2.0
- Added
- 2026-08-29 03:02:28
- Updated
- 2026-08-29 03:02:28
- Origin id
io.github.authzx/mcp-gateway
README
# Vengtoo MCP Gateway
[](LICENSE)
[](https://nodejs.org)
[](https://www.npmjs.com/package/@vengtoo/mcp-gateway)
**Authorization gateway for AI agents and MCP tool calls.**
> Open-source. Drop-in. Works with any MCP client.
## Why
AI agents connected to MCP servers can call any tool they have access to: read your database, delete files, execute arbitrary SQL. Vengtoo MCP Gateway puts a policy enforcement point between the agent and those tools, so every call is authorized before it executes.
## What it does
- Sits between MCP clients (Claude Code, Cursor, VS Code, GitHub Copilot) and any MCP server
- Intercepts every tool call and checks authorization before forwarding
- Two modes: **cloud** (Vengtoo Cloud API) and **local** (Vengtoo Agent + .rego policy file)
- Full audit trail of every tool invocation: subject, tool name, arguments, and decision are logged as structured JSON:
```json
{"ts":"2026-05-25T10:03:11.482Z","level":"info","msg":"mcp_tool_call","subject":"agent:ai-assistant","tool":"database__query","allowed":true,"latency_ms":0.8}
```
## Quick Start
1. Install and start the [Vengtoo Agent](https://github.com/vengtoo/agent). The agent runs locally and evaluates your authorization policy; no cloud account needed.
```bash
go install github.com/vengtoo/agent/cmd/agent@latest
vengtoo-agent --policy ./policy.rego
```
Create a `policy.rego` to define what your agent can do:
```rego
package vengtoo.mcp
default allow := false
# Allow read-only tools
allow if { input.resource.name == "database__query" }
allow if { input.resource.name == "database__list_tables" }
# Allow writes, but block destructive SQL
allow if {
input.resource.name == "database__execute"
not contains(lower(input.resource.attributes.sql), "drop")
not contains(lower(input.resource.attributes.sql), "delete from")
}
```
See [`demo/policies/`](demo/policies/) for more examples including Kubernetes namespace protection.
2. Create a `gateway.config.json`:
```json
{
"vengtoo": {
"agentUrl": "http://127.0.0.1:8181"
},
"subject": "agent:ai-assistant",
"servers": {
"database": {
"command": "node",
"args": ["./my-database-mcp-server.js"]
}
}
}
```
3. Add to your MCP client (e.g. Claude Code):
```bash
claude mcp add --transport stdio vengtoo-gateway -- \
npx vengtoo-mcp-gateway --config /path/to/gateway.config.json
```
## Configuration
### Config schema
| Field | Type | Required | Description |
| ------------------ | ------ | -------- | -------------------------------------------------------------- |
| `vengtoo.agentUrl` | string | \* | URL of local Vengtoo Agent (local mode) |
| `vengtoo.cloudUrl` | string | \* | URL of Vengtoo Cloud API (cloud mode) |
| `vengtoo.apiKey` | string | | API key from [Vengtoo Cloud](https://console.vengtoo.com) (or set `VENGTOO_API_KEY` env var) |
| `vengtoo.timeoutMs` | number | | Authorization request timeout (default: 5000) |
| `subject` | string | yes | Identity of the agent making tool calls |
| `subjectType` | string | | Subject type (default: `"agent"`) |
| `resourceType` | string | | Resource type for authorization checks (default: `"mcp_tool"`) |
| `servers` | object | yes | Map of downstream MCP servers to proxy |
| `transport` | string | | Caller transport: `"stdio"` (default) or `"http"`, see [Transport](#transport) |
| `http` | object | | HTTP transport settings (used when `transport` is `"http"`) |
\* Provide either `agentUrl` (local mode) or `cloudUrl` (cloud mode).
Each entry in `servers` has:
| Field | Type | Required | Description |
| --------- | -------- | -------- | -------------------------------- |
| `command` | string | yes | Command to spawn the MCP server |
| `args` | string[] | | Command arguments |
| `env` | object | | Additional environment variables |
## Modes
### Cloud mode
Connect to Vengtoo Cloud for managed policies:
```json
{
"vengtoo": {
"cloudUrl": "https://api.vengtoo.com/access/v1/evaluation",
"apiKey": "vgt_..."
},
"subject": "agent:prod-assistant",
"servers": {
"database": {
"command": "node",
"args": ["./db-server.js"]
}
}
}
```
### Local mode
Run the Vengtoo Agent locally with a .rego policy file for offline, self-contained authorization:
```bash
# Start the agent with your policy
vengtoo-agent --policy ./policy.rego
```
```json
{
"vengtoo": {
"agentUrl": "http://127.0.0.1:8181"
},
"subject": "agent:dev-assistant",
"servers": {
"database": {
"command": "node",
"args": ["./db-server.js"]
}
}
}
```
## Transport
The gateway exposes its (policy-enforced) tools to callers over one of two transports.
### stdio (default)
Runs as a local subprocess speaking MCP over stdin/stdout: the right choice for a
single desktop agent (Claude Desktop, Cursor, Claude Code). No network surface.
### HTTP (remote)
Runs a [Streamable HTTP](https://modelcontextprotocol.io/) MCP server at a URL, so a
remote agent (or many concurrent agents) can share one governed gateway. Enable it
with `--http` (or `"transport": "http"` in the config):
```bash
vengtoo-mcp-gateway --config gateway.config.json --http --port 8808
```
```json
{
"vengtoo": { "cloudUrl": "https://api.vengtoo.com/access/v1/evaluation", "apiKey": "vgt_..." },
"subject": "agent:prod-assistant",
"transport": "http",
"http": {
"port": 8808,
"host": "0.0.0.0",
"path": "/mcp",
"authTokens": ["<caller-token>"],
"allowedHosts": ["gateway.example.com"]
},
"servers": { "database": { "command": "node", "args": ["./db-server.js"] } }
}
```
HTTP config (`http.*`):
| Field | Type | Default | Description |
| --------------- | -------- | ------------- | --------------------------------------------------------------------------- |
| `port` | number | `8808` | TCP port to listen on |
| `host` | string | `127.0.0.1` | Interface to bind; `0.0.0.0` accepts remote connections |
| `path` | string | `/mcp` | URL path of the MCP endpoint |
| `callers` | object[] | - | Per-caller identity: `{ "token": "...", "subject": "agent:claude" }`; each bearer token authorizes as its own subject |
| `authTokens` | string[] | - | Anonymous bearer tokens; grant access, run as the global `subject` |
| `allowedHosts` | string[] | - | Enables DNS-rebinding protection; rejects requests with an unlisted `Host` |
| `allowedOrigins`| string[] | - | Enables DNS-rebinding protection; rejects requests with an unlisted `Origin`|
**Per-caller identity.** Give each agent its own token and subject, and your policies
(and audit trail) see each caller's real identity through one shared gateway:
```json
"http": {
"port": 8808,
"callers": [
{ "token": "<claude-token>", "subject": "agent:claude" },
{ "token": "<cursor-token>", "subject": "agent:cursor" }
]
}
```
Also settable via `VENGTOO_GATEWAY_HTTP_CALLERS="<token>=agent:claude,<token>=agent:cursor"`.
Sessions are bound to the token that opened them: a different caller presenting another
caller's session id gets a 401, so identities cannot cross sessions. Tokens listed in
`authTokens` (or callers omitted entirely) run as the config's global `subject`.
**Safety:** the gateway **refuses to bind a non-loopback interface with no caller auth**
(`callers` or `authTokens`). Either configure tokens, or set
`VENGTOO_GATEWAY_ALLOW_UNAUTHENTICATED=true` to knowingly expose an open endpoint. An
unauthenticated `GET /healthz` liveness probe is always served.
> ⚠️ **Security: Vengtoo trusts whichever subject this gateway asserts.** The
> `callers` token→subject mapping above (owned by this gateway's own config) is the
> correct pattern; it is NOT the same as trusting a client-supplied header. Never
> change this to derive the subject from a header/field a calling client sends; that
> would let any caller claim to be any subject and inherit its permissions within
> your tenant. If you front this gateway with another reverse proxy, make sure that
> proxy cannot be made to forward an arbitrary caller-chosen bearer token or subject.
## CLI Flags
| Flag | Description |
| -------------------------- | -------------------------------------------------------------------------------------- |
| `--config <path>` | Path to gateway config file (default: `./gateway.config.json`) |
| `--http` | Serve over HTTP instead of stdio |
| `--port <n>` | HTTP listen port (default: `8808`; implies `--http`-compatible config) |
| `--host <h>` | HTTP bind interface (default: `127.0.0.1`) |
| `--path <p>` | HTTP endpoint path (default: `/mcp`) |
| `--list-tools` | List all tools from configured downstream servers and exit |
| `--generate-policy [path]` | Generate a starter .rego policy file for the configured tools (default: `policy.rego`) |
Environment overrides: `VENGTOO_API_KEY`, `VENGTOO_AGENT_URL`, `VENGTOO_SUBJECT`,
`VENGTOO_GATEWAY_TRANSPORT` (`http`), `VENGTOO_GATEWAY_PORT` / `PORT`, `VENGTOO_GATEWAY_HOST`,
`VENGTOO_GATEWAY_PATH`, `VENGTOO_GATEWAY_HTTP_TOKENS` (comma-separated), `VENGTOO_GATEWAY_ALLOW_UNAUTHENTICATED`.
## MCP Client Setup
The gateway runs as a stdio MCP server. Point your MCP client at it instead of the downstream server directly.
### Claude Code
```bash
claude mcp add --transport stdio vengtoo-gateway -- \
npx vengtoo-mcp-gateway --config /path/to/gateway.config.json
```
### Cursor
Add to `.cursor/mcp.json`:
```json
{
"mcpServers": {
"vengtoo-gateway": {
"command": "npx",
"args": ["vengtoo-mcp-gateway", "--config", "/path/to/gateway.config.json"]
}
}
}
```
### Claude Desktop
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"vengtoo-gateway": {
"command": "npx",
"args": ["vengtoo-mcp-gateway", "--config", "/path/to/gateway.config.json"]
}
}
}
```
### VS Code / GitHub Copilot
Add to `.vscode/mcp.json`:
```json
{
"servers": {
"vengtoo-gateway": {
"type": "stdio",
"command": "npx",
"args": ["vengtoo-mcp-gateway", "--config", "/path/to/gateway.config.json"]
}
}
}
```
See [`demo/`](demo/) for full end-to-end examples with sample policies.
## Roadmap
See [ROADMAP.md](ROADMAP.md) for what's planned: per-caller OAuth, downstream
resilience, dynamic tool lists, metrics, remote downstream servers, and more.
## Feedback
- [GitHub Issues](https://github.com/vengtoo/mcp-gateway/issues): Bug reports and feature requests
- [Documentation](https://docs.vengtoo.com): Guides and API reference
## License
Apache-2.0, see [LICENSE](LICENSE).