Skip to main content
ClaudeWave

The safety gate between AI agents and your servers. An MCP server for structured, policy-checked, audited infrastructure operations.

MCP ServersRegistry oficial1 estrellas0 forks● GoMITActualizado today
ClaudeWave Trust Score
95/100
✓ Verified
Passed
  • ✓Open-source license (MIT)
  • ✓Actively maintained (<30d)
  • ✓Clear description
  • ✓Topics declared
  • ✓Documented (README)
Last scanned: 10/18/2026
Install in Claude Code / Claude Desktop
Method: Manual · opsgate
Claude Code CLI
git clone https://github.com/polymatx/opsgate
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "opsgate": {
      "command": "opsgate"
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
💡 Install the binary first: go install github.com/polymatx/opsgate@latest (make sure it ends up on your PATH).
Casos de uso

Resumen de MCP Servers

<div align="center">

# opsgate

**The safety gate between AI agents and your servers.**

An MCP server that lets Claude, Cursor, or any AI agent operate real infrastructure —
without handing it a root shell.

[![CI](https://github.com/polymatx/opsgate/actions/workflows/ci.yml/badge.svg)](https://github.com/polymatx/opsgate/actions/workflows/ci.yml)
[![Go Report Card](https://goreportcard.com/badge/github.com/polymatx/opsgate)](https://goreportcard.com/report/github.com/polymatx/opsgate)
[![Go Reference](https://pkg.go.dev/badge/github.com/polymatx/opsgate.svg)](https://pkg.go.dev/github.com/polymatx/opsgate)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Go 1.26+](https://img.shields.io/badge/Go-1.26%2B-00ADD8?logo=go&logoColor=white)](https://go.dev)
[![MCP](https://img.shields.io/badge/MCP-server-6E56CF)](https://modelcontextprotocol.io)

[What it looks like](#what-it-looks-like) ·
[30-second try](#try-it-in-30-seconds-no-server-needed) ·
[Break it yourself](#break-it-yourself) ·
[Tools](#tools) ·
[Security model](#security-model) ·
[Contributing](#contributing)

<img src="docs/demo.gif" alt="An agent's calls to opsgate: a shell injection, a path traversal and a restart in observe mode are all refused, nothing runs, and each attempt is in the hash-chained audit log" width="820">

</div>

---

## What it looks like

You ask a question. The agent investigates with read-only tools and answers.

> **You:** Something's listening on port 8000 on my server and I don't remember what. Check it.

```
▸ listening_ports(host: "hetzner")

  Netid State  Recv-Q Send-Q  Local Address:Port  Process
  tcp   LISTEN 0      511         0.0.0.0:443     users:(("nginx",pid=249619),…)
  tcp   LISTEN 0      511         0.0.0.0:80      users:(("nginx",pid=249619),…)
  tcp   LISTEN 0      4096        0.0.0.0:22      users:(("sshd",pid=237597),…)
  tcp   LISTEN 0      151       127.0.0.1:3306    users:(("mysqld",pid=237695),…)
  tcp   LISTEN 0      5         127.0.0.1:8000    users:(("python3",pid=237608),…)

▸ service_list(host: "hetzner", state: "running")

  docker.service       loaded active running  Docker Application Container Engine
  mysql.service        loaded active running  MySQL Community Server
  nginx.service        loaded active running  A high performance web server…
  php8.3-fpm.service   loaded active running  The PHP 8.3 FastCGI Process Manager
  pm2-root.service     loaded active running  PM2 process manager
```

> **Claude:** Port 8000 is a bare `python3` process (pid 237608) bound to localhost only, so
> it isn't reachable from outside. It's not managed by systemd — no unit owns it — which
> means it won't survive a reboot. It's most likely something started by hand in a shell.

Now something that changes state. In `operate` mode the agent cannot just do it:

> **You:** OK, nginx config changed. Reload it.

```
▸ nginx_test(host: "hetzner")
  nginx: configuration file /etc/nginx/nginx.conf test is successful

▸ nginx_reload(host: "hetzner")

  ┌─ opsgate: approval required ─────────────────────────────────┐
  │ allow nginx_reload on host "hetzner"?                        │
  │                                                             │
  │ The nginx configuration passed validation.                  │
  │ This will reload nginx.                                     │
  │                                                             │
  │ Command: 'nginx' '-s' 'reload'                               │
  │                                        [ Approve ]  [ Deny ] │
  └─────────────────────────────────────────────────────────────┘
```

You click Deny, and nothing happens — the agent is told the operator refused. Approve, and
it runs and lands in the audit log. Either way you saw the exact command first.

*(Tool output above is real output from a live server; the prompt is rendered by your MCP
client, so it looks however that client draws it.)*

## Try it in 30 seconds (no server needed)

opsgate runs with **no config file at all** — local machine, read-only:

```bash
go install github.com/polymatx/opsgate/cmd/opsgate@latest
opsgate serve
```

```
opsgate dev | mode=observe | default_host=local | audit=~/.opsgate/audit.jsonl
```

That's it. No config, no SSH, and it defaults to `observe` — so it can read your disk usage
and journal, and it will refuse to change anything:

```
▸ disk_usage()          → works
▸ service_restart(...)  → Refused by opsgate policy: host is in observe mode
```

Point your client at it and ask "what's using disk space on this machine?" When you're
ready for real hosts, add a config with `opsgate init`.

### Which clients can reach it

opsgate runs **on your machine** (or on the server itself) and holds your SSH key, so the
transport you need depends on where your client actually executes:

| Client | Transport | Works because |
|---|---|---|
| Claude Code (terminal) | stdio | Runs natively on your machine and launches the binary |
| Claude Desktop, Cursor, VS Code | stdio | Same — a local process |
| Cloud or sandboxed surfaces (web chat, VM-backed agents) | **HTTP** | They cannot launch a local process, or even see your SSH key — they can only reach a URL |

If your client reports it has no access to your servers, it is almost certainly one of the
sandboxed kind. Serve over [HTTP](#any-client-over-http) instead of stdio.

Before publishing that endpoint, read the warning there: it puts an
infrastructure-management API on whatever network you expose it to.

### Wire it up to your client

<details>
<summary><b>Claude Code</b></summary>

As a plugin: the MCP server, a `server-ops` skill that teaches the agent to diagnose before
it acts and to treat refusals as final, and a read-only `/opsgate:health-check [host]` command.

```
/plugin marketplace add polymatx/opsgate
/plugin install opsgate@opsgate
```

The plugin runs `opsgate serve`, which reads `./opsgate.yaml`, then `~/.opsgate/config.yaml`.
Or add just the MCP server:

```bash
claude mcp add opsgate -- opsgate serve --config ~/.opsgate/config.yaml
```
</details>

<details>
<summary><b>Claude Desktop / Cursor</b> (<code>claude_desktop_config.json</code> or <code>.cursor/mcp.json</code>)</summary>

```json
{
  "mcpServers": {
    "opsgate": {
      "command": "opsgate",
      "args": ["serve", "--config", "/absolute/path/to/opsgate.yaml"]
    }
  }
}
```
</details>

<details>
<summary><b>Docker</b> (<code>ghcr.io/polymatx/opsgate</code>)</summary>

For hosts reached over SSH. Inside a container, `local` is the container itself.

```bash
docker run -i --rm \
  -v ~/.opsgate:/root/.opsgate \
  -v ~/.ssh:/root/.ssh:ro \
  ghcr.io/polymatx/opsgate serve
```

The image is also how opsgate is listed in the [MCP Registry](https://registry.modelcontextprotocol.io)
as `io.github.polymatx/opsgate`.
</details>

<details id="any-client-over-http">
<summary><b>Any client, over HTTP</b> (needed for cloud/sandboxed clients)</summary>

```yaml
http:
  addr: "127.0.0.1:8080"
  auth_token: "a-long-random-token"   # sent as: Authorization: Bearer <token>
```

```bash
opsgate serve --http 127.0.0.1:8080
```

The tidiest deployment is to run opsgate **on the server it manages** — then it needs no SSH
key at all (`default_host: local`) — behind a TLS-terminating reverse proxy:

```
client ──HTTPS──▶ nginx / Caddy ──▶ 127.0.0.1:8080  opsgate
                  + Bearer token
```

> [!WARNING]
> Exposing this endpoint puts an infrastructure-management API on that network, and the
> bearer token becomes the only thing protecting it. If you must publish it: keep
> `mode: observe`, generate 32+ bytes of randomness for the token, require TLS, and add an
> IP allowlist at the proxy. Binding it to a VPN interface (WireGuard, Tailscale) instead of
> the public internet is strictly safer — your own devices reach it, nobody else can.
>
> Note also that `operate` mode expects a human who can answer an approval prompt. An
> unattended HTTP deployment usually means `observe`.

</details>

## The problem this solves

Letting an AI agent run your servers today means giving it `exec("<any string>")` over SSH.
The usual mitigation is a denylist of commands that *look* dangerous.

That does not work. Denylists are guesswork against an adversary with infinite phrasings:

```
rm -rf /                              →  blocked
r''m -rf /                            →  not blocked
echo cm0gLXJmIC8K | base64 -d | sh    →  not blocked
```

And "dangerous-looking" isn't even the hard part. `systemctl restart nginx` is a perfectly
ordinary command that is catastrophic at 3pm on Black Friday.

## The approach

opsgate does not filter strings. **It never gives the agent a string to fill in.**

The agent gets 25 typed tools — `service_restart(name)`, `docker_logs(container)`,
`journal_tail(unit, since, priority)` — and opsgate builds the command itself as an `argv`
array. There is no shell to inject into, because no shell string is ever assembled from
agent input.

```go
// What opsgate does — the name is one argv element, whatever it contains
argv := []string{"systemctl", "restart", in.Name}

// What it never does
argv := []string{"sh", "-c", "systemctl restart " + in.Name}
```

Send `nginx; rm -rf /` as the service name and `systemctl` receives it as a single literal
argument and fails as an unknown unit. Nothing else runs.

Every call then passes through four gates:

```mermaid
flowchart LR
    A[Agent calls a tool] --> B{Policy<br/>mode + allowlist}
    B -->|deny| X[Refused<br/>+ audited]
    B -->|allow| D[Build argv]
    B -->|needs approval| C{Human}
    C -->|deny| X
    C -->|approve| D
    D --> E[Execute]
    E --> F[Audit<br/>hash-chained]
```

| Layer | What it does |
|---|---|
| **Structured tools** | Commands are built as `argv`, never string-concatenated. Injection is impossible by construction, not by filtering. |
| **Deny-by-default policy** | Three modes — `observe` (read-only), `operate` (writes need approval), `full`. Per-host overrides
ai-agentsaiopsaudit-logclaudeclaude-codedevopsdockergolanghacktoberfestinfrastructure-as-codemcpmcp-servermodel-context-protocolobservabilityplatform-engineeringsecuritysresshsysadminsystemd

Lo que la gente pregunta sobre opsgate

¿Qué es polymatx/opsgate?

+

polymatx/opsgate es mcp servers para el ecosistema de Claude AI. The safety gate between AI agents and your servers. An MCP server for structured, policy-checked, audited infrastructure operations. Tiene 1 estrellas en GitHub y su última actualización registrada es del 2026-10-17.

¿Cómo se instala opsgate?

+

Puedes instalar opsgate clonando el repositorio (https://github.com/polymatx/opsgate) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.

¿Es seguro usar polymatx/opsgate?

+

Nuestro agente de seguridad ha analizado polymatx/opsgate y le ha asignado un Trust Score de 95/100 (tier: Verified). Revisa el desglose completo de comprobaciones superadas y flags en esta página.

¿Quién mantiene polymatx/opsgate?

+

polymatx/opsgate es mantenido por polymatx. La última actividad registrada en GitHub es del 2026-10-17, con 4 issues abiertos.

¿Hay alternativas a opsgate?

+

Sí. En ClaudeWave puedes explorar mcp servers similares en /categories/mcp, ordenados por popularidad o actividad reciente.

Despliega opsgate en tu cloud

Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.

¿Mantienes este repo? Añade un badge a tu README

Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.

Featured on ClaudeWave: polymatx/opsgate
[![Featured on ClaudeWave](https://claudewave.com/api/badge/polymatx-opsgate)](https://claudewave.com/repo/polymatx-opsgate)
<a href="https://claudewave.com/repo/polymatx-opsgate"><img src="https://claudewave.com/api/badge/polymatx-opsgate" alt="Featured on ClaudeWave: polymatx/opsgate" width="320" height="64" /></a>

Más MCP Servers

Alternativas a opsgate