Skip to content
Conduit

mcp server

kontur

Pair-programming for agentic development

industrial-assets/konturcommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

This project does not publish an install method we can turn into a config. Follow the README instead.

README

synced Oct 25, 2026

KONTUR · [КОНТУР]

A brutalist CLI for high-efficiency agentic pair programming.

Two engineers, one console, a fleet of agents — and nothing ships without both keys.



What it is

KONTUR (kohn-toor) is a terminal-native workstation where two engineers jointly supervise a fleet of coding agents on the same codebase. One hosts the agents, one joins to co-sign; both review. Every change an agent makes is gated behind two independent human approvals before it can merge, and the whole session leaves a signed, tamper-evident audit trail.

It exists for the place solo agentic tooling can't go: production environments where the agent wrote it and one person glanced at it isn't good enough, and segregation of duties is the rule, not a nicety.

Install

Kontur is distributed as a Homebrew tap (macOS + Linux):

brew tap industrial-assets/kontur
brew trust industrial-assets/kontur   # once: recent Homebrew requires trusting third-party taps
brew install kontur

Recent Homebrew versions refuse to load formulae from an untrusted third-party tap. Run brew trust industrial-assets/kontur once (after tapping) before installing or upgrading. Older Homebrew versions don't have brew trust and will error harmlessly — skip that line if so.

Upgrade when a new version ships:

brew upgrade kontur

Kontur tells you in a calm footer line when a newer release is available, and nudges you and your co-operator when your two versions differ. To disable the check entirely, set KONTUR_NO_UPDATE_CHECK=1.

One-liner alternative (auto-taps): brew install industrial-assets/kontur/kontur (still run brew trust industrial-assets/kontur first).

The idea

Pair programming assumed a driver at the keyboard and a navigator watching the cursor. Agentic development took the keyboard away — so pairing moves up a layer. The Host runs the session and provides the agents (the Claude Code connection lives on their machine); the Operator joins over the network. Both construct and review instructions, both watch the fleet, and both independently approve every change. Maker-checker, with the agent as maker and two co-equal humans as checkers.

How it works

  • Compose the prompt. Either seat drafts/edits it in-console ([p]) — multi-line (alt+↵), cursor editing, paste-safe; the other seat watches the draft live, keystroke by keystroke; every edit resets both ready marks; both mark ready to dispatch.
  • Split, only if it helps. The agent works solo by default. If the work has genuinely independent parallel streams (e.g. backend and frontend), it proposes a split into a fleet and waits — both operators approve ([y]) or one declines ([n], keeping it solo). Each agent still produces small, single-concern gated chunks, clearly attributed to its agent and task.
  • Clarify first. If the instruction is genuinely ambiguous, the agent asks the operators multiple-choice questions (each with a "provide your own answer" option) and waits — it never assumes. Both operators answer; if they disagree, the question re-asks as [A's answer / B's answer / accept both] until they converge.
  • Plan next. The agent proposes its task list of bounded, single-concern changes and is blocked until both seats approve it — the plan gate is enforced, not advisory. Either seat can select (j/k), edit (e), delete (d), or reorder (</>) tasks; any edit resets both ready flags. The approved list is returned to the agent verbatim; steer-first approach preferred — [r] routes a revision prompt to the agent.
  • One task at a time. Agents work sequentially; each finished change parks at a gate.
  • Step away safely. Either seat can toggle AFK ([z]) when they walk off; the other keeps doing all single-operator work (review, draft, steer, claim, discuss) and the console shows "waiting on … (AFK)". AFK is presence only — nothing needing the away seat's second key merges without them.
  • Two keys, independent. On high-risk gates the first verdict is sealed until the second is cast — no anchoring, no rubber-stamp. A no-go must carry its fix. A hand-edit applies instantly for emergencies but still needs both keys before it merges.
  • Merge with a trail. The approved set lands as one reviewed commit carrying Reviewed-by trailers and an Audit-chain: trailer naming the chain head; the signed, hash-chained gate records are written to .kontur/audit-<head>.json in the repo at session close (merged or abandoned) and verify offline with kontur audit <file>.

The console

 LINK BOTH-STATIONS SYNC || 4-EYES ON || FLEET 3 (1 NEEDS YOU)
 ┌─ AGENT-01 ────────────────────┐ ┌─ AGENT-02 ───┐ ┌─ AGENT-03 ──────┐
 │ analysing parser.py          │ │ editing auth │ │ ▶ NEEDS SIGN-OFF│
 └───────────────────────────────┘ └──────────────┘ └─────────────────┘
 ┌─ GATE-03 · agent-03 · auth/session.ts · +47 -12 · tests ok ────────┐
 │  KEY Operator A [Host]  □ awaiting your verdict                    │
 │  KEY Operator B         ■ cast — sealed                            │
 │  [g] go   [r] no-go +remedy   [e] hand-edit   [d] discuss          │
 └────────────────────────────────────────────────────────────────────┘

Principles

Brutalist: raw, structural, honest. Every element on screen earns its place or it's cut — no decorative telemetry, no confidence theatre, no alarms that don't mean anything. The look is a consequence of supervising many things at once, not a costume applied over it. Calm until it needs you.

Running it

# Build from source (clone required):
cargo install --path crates/kontur-tui

# Primary path — host in your current folder with a real Claude Code agent.
# A fresh/empty folder works: kontur offers to `git init` and makes a base
# commit when there are none. Your terminal becomes the HOST console; the invite
# shows in-console until the operator links ([l] toggles LAN/WAN); compose the
# instruction at the dispatch gate with [p]:
cd your-project && kontur --claude

# Operator: paste the invite the host sends you (one 52-char code — it carries
# a derived operator key and the pinned TLS cert fingerprint):
kontur join kontur://…

# Bring your own key (the host can't forge your second signature): the host runs
# `kontur --byo`; you generate/keep a local key and join with it, then read your
# fingerprint to the host to approve:
kontur id                 # show your operator fingerprint (key stays in ~/.kontur)
kontur join --byo kontur://…

# Host without an agent (attach one manually later), or with the scripted demo agent:
cd your-project && kontur
cd your-project && kontur --demo-agent

# Self-contained local demo (both seats, scripted agent, in-memory workspace):
cargo run -p kontur-tui --bin kontur -- demo

# Explicit repo / in-memory / scripted flags still work:
kontur host --repo /path/to/repo --demo-agent
kontur host --mem --prompt "initial text (editable in-console)"

# Join as operator (legacy plain-TCP test form still works):
kontur join --addr host:7777 --seed 2

Console keys: ? help · y ready · p edit prompt · j/k scroll diff · ↑/↓ scroll log · tab select file · c claim gate · d discuss note · z AFK (away) · a/x approve/reject BYO join · g go (2× if truncated) · r no-go+steer · e edit file · l invite LAN/WAN · K abandon (confirm) · q quit. Press ? any time for a phase-aware keymap.

Invite codes carry the secret the operator's key is derived from — send privately; operator-supplied keys with host-side approval are future work.

The host command also binds an MCP endpoint (default port 7778). Use --claude to have kontur spawn a permission-restricted Claude Code agent automatically once both seats approve the dispatch gate:

# kontur spawns the agent once both seats approve the dispatch gate; the
# instruction is whatever was composed in-console at that gate:
kontur --claude

# The agent launches with native file/shell tools denied at CC's permission level;
# only mcp__kontur__* tools are allowed. Output goes to a session log (path printed
# on startup).

Alternatively, attach Claude Code manually (advanced / alternative):

# 1. Save as kontur-mcp.json (the bridge is kontur itself — no nc needed):
{"mcpServers":{"kontur":{"command":"kontur","args":["mcp-bridge","7778"]}}}

# 2. Run:
claude --mcp-config kontur-mcp.json \
  --allowedTools "mcp__kontur__*" \
  --disallowedTools Write Edit MultiEdit NotebookEdit Bash \
  --permission-mode default \
  -p "<your protocol prompt>"

Agent writes, commands, and gate openings stream live into the operator console as they happen — no keypress needed. Every task completion parks at a four-eyes gate until both operators cast a verdict — the diff is permanently visible in the right pane while the gate is pending; [tab] cycles between per-file diffs, each capped independently (a huge generated file like a lockfile truncates only its own view, never the other files'); if any file's diff was truncated, a second [g] is required to acknowledge before casting. The review depth is recorded truthfully in the signed verdict. Enforcement is permission-level — native mutation tools are denied via CC's --allowedTools/--disallowedTools flags, not an OS-level sandbox. The operator wire is TLS-encrypted, cert pinned via the invite code. An application keepalive parks gates if a seat's link goes silent (and the other console shows a loud HOST LOST banner) rather than mistaking a dropped operator for a present one. Either seat can abandon a runaway session ([k]): nothing merges, the agent is stopped, and the audit chain keeps every resolved gate.

Connectivity

Kontur does not run a relay or do NAT hole-punching — the operator connects directly to the host, so the two machines must be able to reach each other on the network. The [l] toggle swaps the invite between a LAN address and a public one, but a public IP still needs a port-forward or DMZ on the host's router. For pairing across networks, put both machines on a mesh VPN (Tailscale or WireGuard) and use the LAN-style address — it's the supported WAN path and avoids exposing the host to the open internet. (A hosted relay is deliberately out of scope: code stays on machines the team already trusts.)

Platform support

Developed and tested on macOS and Linux. Windows is not currently tested — path handling and the in-viewer $EDITOR hand-edit ([e], which launches $EDITOR or vi) haven't been validated there; treat a Windows host as unsupported for now. The MCP bridge is built in (kontur mcp-bridge), so there is no nc or other external-tool dependency on any platform.

The design lives in

  • docs/PRD-coop-supervisor.md — problem, requirements, architecture, and the two-signatory four-eyes mechanism.
  • docs/UX-kontur.md — console anatomy, screen states, and the interaction model.

Built on

MCP as the action/enforcement plane (consequential actions routed through hosted MCP servers and gated for approval), with Claude Code as the first agent backend. The two-signatory sign-off is layered over MCP's single-approver gate.

License

MIT OR Apache-2.0.

↑↓ navigate openesc close