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
Описание
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:
- From this project directory, start Claude Code.
- Approve the project MCP server when prompted (or run
/mcpto inspect it). - 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.
Установка Ops Copilot
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/mariuszbyahoo/ops-copilot-mcpFAQ
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
GitHub
PRs, issues, code search, CI status
автор: GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
автор: mcpdotdirectCompare Ops Copilot with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории development
