Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

Ops Copilot

БесплатноНе проверен

A self-hosted MCP server providing a governed interface for AI agents to interact with local Docker infrastructure, featuring a two-phase confirm protocol for s

GitHubEmbed

Описание

A self-hosted MCP server providing a governed interface for AI agents to interact with local Docker infrastructure, featuring a two-phase confirm protocol for state-changing operations and append-only audit logging.

README

A self-hosted MCP server (TypeScript / Node.js) that gives an AI agent (Claude Code, Claude Desktop) a governed interface to local infrastructure. MVP scope: Docker only.

The point is not "an agent can call Docker" — it's the control model.

The control model

  • Read freely. The agent lists containers and reads logs with no ceremony — reads have no side effects.
  • Mutate only with a human-confirmed token. A state-changing tool (restart_container) uses a two-phase confirm protocol: the first call only previews and returns a single-use token; nothing changes until a second call supplies that token.
  • Deny-by-default. Operations are explicitly classified as read or mutate. Anything not classified is refused — capability is opt-in, not opt-out.
  • Append-only JSONL audit log. Every invocation — read, preview, allow, deny — is written as one JSON line. This is the primary, incident-safe record, not a mirror of some other store. Each line is independently valid, so a crash mid-write can never corrupt history.

This is the portfolio story: not raw capability, but governed capability.

The confirm-token protocol

Agent ──restart_container{container}──────────────▶  Phase 1: preview
                                                     • resolve target (id-prefix or name)
                                                     • issue single-use token, TTL 120s,
                                                       bound to (operation, target)
                                                     • audit: preview
        ◀──"About to restart web-1 (a1b2c3)…       • NO side effect
            confirmToken=9f3a… within 120s"

Agent ──restart_container{container, confirmToken}─▶  Phase 2: execute
                                                     • token must exist, be unexpired,
                                                       unused, and match (op, target) exactly
                                                     • on success → restart, audit: allowed
                                                     • else → refuse, audit: denied

The token comes from crypto.randomBytes(16), lives only in memory, is deleted on consume (single-use), and is bound to an exact (operation, target) pair — a token issued to restart container A can never restart container B, and a reused or expired token is refused with no side effect.

Tools

Tool Type Input Behavior
ping read Health check; returns pong.
list_containers read { all?: boolean = false } Compact text table; running only, or all incl. stopped.
get_container_logs read { container: string, tail?: number = 100 } Last N log lines; resolve by id-prefix or exact name.
restart_container mutate { container: string, confirmToken?: string } Two-phase confirm (see above).

Tool outputs are short, fixed-width, and explicit about errors (prefixed Error: with isError: true) so the LLM routes reliably on them.

Running locally

Prerequisites: Node.js LTS (>= 20) and a running Docker daemon (Docker Desktop on Windows/macOS, or the socket on Linux).

npm install
npm run dev        # tsx src/index.ts — runs the server over stdio
npm run build      # tsc -> dist/
npm start          # node dist/index.js — runs the compiled build
npm test           # vitest — unit tests for the confirm-token store

The server speaks MCP over stdio: stdout is the JSON-RPC protocol channel, and all logs go to stderr. You normally don't run it by hand — an MCP client (Claude Code) launches it.

The audit log is written to ./audit/audit-<yyyyMMddUTC>.jsonl by default; override the directory with the AUDIT_DIR environment variable. Files roll per UTC day.

Point Claude Code at it

A project-scoped .mcp.json at the repo root registers this server:

{
  "mcpServers": {
    "ops-copilot-mcp": {
      "command": "npx",
      "args": ["tsx", "src/index.ts"]
    }
  }
}

Claude Code launches the command from the project directory. To use the compiled build instead of tsx, run npm run build first and change the entry to:

{ "command": "node", "args": ["dist/index.js"] }

Then:

  1. From this project directory, start Claude Code.
  2. Approve the project MCP server when prompted (or run /mcp to inspect it).
  3. Confirm the tools are listed. Try: "list all containers", then "restart X" — the agent will preview and hand you a token before anything changes.

If the server won't connect, the cause is almost always stdout pollution — a stray console.log corrupts the protocol stream. Every log line must go to stderr (console.error).

Architecture

MCP Tools      src/tools/*.ts      thin registerTool wrappers; shape text, write audit; no logic
   │
Policy         src/policy/*.ts     deny-by-default classification; issues/consumes confirm tokens
   │
Adapter        src/adapters/*.ts   the only code that talks to Docker (dockerode); plain types out
   │
Audit          src/audit/*.ts      append-only JSONL sink; called at every decision point

Dependency rule: tools know Policy/Adapter/Audit; the adapter knows only dockerode; Policy/Audit know nothing of MCP or Docker. SDK types live only in src/index.ts and src/tools/*. Dependencies are constructed by hand in src/index.ts and injected — no container, no decorators. This keeps the core unit-testable with no transport and makes the future stdio→HTTP swap a one-file change.

Security note

The stdio transport inherits the trust of the local user who launches the server. There is no network listener, no authentication layer, and no sandbox: the server runs with your OS permissions and talks to your Docker daemon over its local socket / named pipe — which on most setups is equivalent to root on the host. The confirm-token protocol is a guardrail against an agent acting without human intent; it is not a security boundary against a hostile operator or hostile code already running as you. Run it only on infrastructure you own, keep the audit log, and treat the future HTTP transport (which does cross a trust boundary) as requiring real authentication before exposure.

Roadmap (post-MVP — NOT yet built)

The following are deliberately out of scope for the MVP and are not implemented:

  • Streamable HTTP transport, config-switched (TRANSPORT=stdio|http). Today: stdio only.
  • More adapters — GitHub (PRs, workflow runs), Traefik (routers, health).
  • Postgres as a queryable mirror of the JSONL audit log (the JSONL file stays the primary store; Postgres would only be a read-optimized projection).
  • Scoped policy per operation/target patterns, and richer preview diffs.

from github.com/mariuszbyahoo/ops-copilot-mcp

Установка Ops Copilot

У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.

▸ github.com/mariuszbyahoo/ops-copilot-mcp

FAQ

Ops Copilot MCP бесплатный?

Да, Ops Copilot MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для Ops Copilot?

Нет, Ops Copilot работает без API-ключей и переменных окружения.

Ops Copilot — hosted или self-hosted?

Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.

Как установить Ops Copilot в Claude Desktop, Claude Code или Cursor?

Открой Ops Copilot на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Похожие MCP

Compare Ops Copilot with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории development