Reliable, transparent terminal runtime between AI agents and the shell (local + SSH).
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
π‘ Paste into ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows)
Persistent, policy-controlled missions for AI agents operating real environments.
Termada is a single-binary, local-first runtime that sits between an AI agent and
the terminal, locally or over SSH. The agent talks to it over the
Model Context Protocol and gets a sturdy
toolset instead of a raw shell: bounded exec_run waits, persistent sessions
that keep cwd/env, async jobs with streamed output, PTY input for interactive
prompts, and structured results β while you watch and control active jobs from a
live dashboard with a job kill-switch and an approval queue. Mission Control
adds a durable goal, GPT/Codex-authored plan, runtime-verified steps, interruption
recovery, and an exportable evidence report around that execution.
The live dashboard: every session is a real terminal you can watch and take over β block or pause the agent, type in yourself β beside the agent panel, policy management, a tamper-evident History, and a Stop-All active-job kill-switch.
Handing an AI agent a raw shell is fragile and opaque: a command blocks on a
prompt and the agent hangs; cd and exported env vanish between calls; long
builds flood the context window; and you can't see β let alone stop β what's
running. Termada replaces the raw shell with a runtime that is reliable for
the agent and transparent for you:
exec_run calls use bounded wait budgets
and return structured output; sessions persist cwd/env; long jobs run async
and stream incrementally instead of dumping; interactive prompts are answerable.confirm wait for your approval; one
button installs a short-lived action admission barrier, requests cancellation
of active gateway executions, signals active engine jobs and closes forwards;
remote/provider effects still require terminal verification or reconciliation.For a concrete operational outcome, Codex or another MCP agent starts with
mission_create(goal, plan). Termada allocates a dedicated persistent session;
normal exec_* calls keep using the same policy, approval, PTY/SSH and audit
paths. The agent attaches each successful job_id with mission_update, then
exports mission_report.
The report separates runtime-observed evidence from agent notes, includes exact
audit sequence/hash anchors, and returns a SHA-256 recorded in the audit. If the
daemon restarts, a non-terminal mission becomes interrupted; mission_resume
creates a fresh session attempt instead of pretending PTY state survived.
Run the isolated real-execution demo:
It starts a broken loopback HTTP service and a separate demo daemon. The
protected repair genuinely changes service state and waits for a human approval;
the final probe must observe HTTP 200. See
demo/mission-control and the
2:40 demo script.
Execution engine
cwd, env, and venv between commands.exec_start β job_id; poll incrementally by a stable cursor, with sequential bounded pages, a full status state machine and structured errors.exec_write, with secret redaction). Local PTY
jobs support process-group signals/kill; remote SSH interrupt/kill requests
are best-effort Ctrl-C, not a guaranteed force-kill.Live control & observability
serve --stdio is a thin shim that proxies MCP to it β so multiple agents share one daemon and one dashboard.termada top) and a full inspection CLI.termada audit verify verifies the continuous chain across rotated segments.Mission Control
job_id from a mission session,
status=exited, exit_code=0) and refusal to succeed while jobs remain active.Security
confirm parks in the durable operator queue, times out to deny, and can execute only when the caller retries the exact approved action id.outcome_unknown reconciliation state.security.identity_mode: strict in production: every configured agent must
have an existing assigned policy and authenticate with either a unique strong
static token or an explicitly enabled, offline-verified short-lived
agent_identity JWT. Tokenless, unknown and policyless callers fail closed.
A strict policy without structured rules also denies every command that lacks
an explicit legacy allow match; deny/confirm gates take precedence.
development retains self-asserted ids for trusted local clients and is the
compatibility default for older configs that omit the field.security.run_as drops local shell processes to a dedicated uid and
disables daemon-privileged local file tools and daemon-environment inheritance;
use commands inside that dropped session for local file access. Remote SFTP
remains available./api/* request and /metrics requires either the dashboard token
or an enabled, pinned-JWKS-verified human JWT. Operator-only Unix-socket routes
similarly require either a verified human JWT or the separate cli.token used
by the local CLI.Remote & fleet
orphaned, and its uncontrolled
remote process may still continue. Verify remote state before retrying it.fleet_run across servers by name or tag with best-effort-redacted,
structured per-server results. Commands must be non-empty argv arrays and run
under a shared daemon-wide ceiling of five concurrent fleet targets; a call
may request less. One call matches at most 256 targets and returns at most
2 MiB of aggregate result text. SSH uses vault creds, ssh-agent, or on-disk keys, with
serialized, fsynced TOFU host-key pinning that fails closed on a malformed
known_hosts file.Operations
orphaned), bounded local-FS snapshots/undo, desktop notifications and outbound-only Telegram notifications.prepare β execute β verify β compensate/reconcile phases, provider
idempotency keys, secret-free receipts and restart recovery. Generic shell and
plugin effects remain opaque unless a concrete provider adapter defines and
proves its semantic invariants.<plugin>.<tool>. Plugins are
trusted executables, not a security sandbox; calls are policy-gated and do not
start unless their start audit record is durable.termada update β bounded self-update from GitHub releases on Unix (mandatory SHA-256 verification, optional Ed25519-signed checksums, exact-member extraction, atomic replace). Windows reports an explicit manual-install path because a running .exe cannot be replaced atomically.Not yet: a native Windows ConPTY runtime (cross-compiles today, but PTY and signals are stubs) and code-signing / notarization.
One line, no Go needed β downloads a prebuilt macOS or Linux amd64/arm64
binary (SHA-256 verified) to ~/.local/bin:
Pin a version with TERMADA_VERSION=vX.Y.Z, or change the location with
TERMADA_BIN_DIR=~/bin. If ~/.local/bin isn't on your PATH, the installer
prints the one line to add.
The Docker command starts the daemon directly; open the tokenized URL printed in its logs. The native CLI commands below apply when the binary is installed on the host.
Releases also ship .deb, .rpm, and manual Windows archives on the
releases page. The Windows
binary cross-compiles, but native PTY execution still awaits a ConPTY backend.
The dashboard bootstrap stores the token in browser session storage and removes
it from the address bar. Static assets are public on loopback, but every TCP
/api/* request and /metrics requires the token. The legacy
dashboard.local_trust setting is deprecated and does not bypass API auth.
Connect it to your agent β this is a one-time, user-wide step. You do it once per user account and every project gets Termada automatically; there's nothing to copy into each repo.
For Claude Code, one command does it:
Using a different agent (or prefer a file)? Add this once to your global MCP
config β see .mcp.json.example:
That's it. From now on, just ask the agent to do terminal work β it flows through Termada while you watch and control it live. The one shared daemon serves every project and every agent session, all on the same dashboard.
Configuration is strict: unknown/unsupported fields fail startup. Values written
as ${NAME} are expanded from the environment, and an unset referenced variable
is an error rather than an empty credential. Leave optional credential fields out
until their variables are available.
For the agent to operate a remote box through Termada (observable, reconnecting,
policy-gated) instead of shelling out to raw ssh, register the server once β then
it's reachable by name, no IP and no raw ssh client.
Add it to config.yaml (see config.example.yaml) and
restart the daemon:
β¦or add it live from the dashboard (Servers β Add). Confirm it's registered:
Now the agent reaches it by name:
session_create(target="prod"), then run exec_run / exec_start in that session (state persists while connected; after a link drop Termada reconnects a fresh shell, but an orphaned remote process may still be running);fleet_run(command=[...], servers=["prod"]) (or by tag).port_forward(server="prod", remote_host="127.0.0.1", remote_port=5432), then close its returned id with port_forward_close when done.Agents like Claude Code and Cursor ship with a built-in shell and will reach for it
(and for raw ssh) by default. Two things steer them to Termada:
Install the usage skill β the plugin below, or skills/termada. It teaches the agent how to drive the tools (and to route remote work through registered servers instead of ssh).
Add a project rule so the agent prefers Termada. Put this in CLAUDE.md
(Claude Code), .cursor/rules (Cursor), or your agent's system prompt:
Use the Termada MCP tools for all shell and remote work β
exec_run/exec_startfor commands,session_create(target="<server>")andfleet_runfor remote servers. Do not use the built-in shell or a rawsshclient: everything must go through Termada so it is observable, reconnecting, and policy-gated. If a server isn't inserver_list(), ask me to register it rather than falling back tossh. For a concrete operational outcome, start withmission_create, use its session for every command, attach real successful job ids to plan steps, and finish withmission_report.
This repo is also a Claude Code plugin marketplace β it bundles the MCP server
config and the usage skill (you still need the termada binary on PATH):
Commands are passed as an argv array (["echo", "hi"]), never a shell string,
so metacharacters are literal unless you explicitly invoke a shell such as
["bash", "-lc", "..."]. Explicit shell payloads still pass through policy;
ambiguous compound payloads fail closed when deny/confirm rules are present.
| Group | Tools |
|---|---|
| Missions | mission_create Β· mission_list Β· mission_get Β· mission_update Β· mission_resume Β· mission_report |
| Run | exec_run Β· exec_start Β· exec_poll Β· exec_write Β· exec_signal Β· exec_kill Β· exec_list |
| Sessions | session_create Β· session_list Β· session_close |
| Files & logs | file_read Β· file_write Β· logs_tail |
| Recipes | recipe_list Β· recipe_run |
| Remote | server_list Β· fleet_run Β· port_forward Β· port_forward_list Β· port_forward_close |
| Plugins | <plugin>.<tool> names discovered at daemon startup |
| Meta | capabilities |
A single daemon owns runtime state; agents connect through a stdio shim, and runtime inspection and controlled actions in the dashboard, TUI, and CLI use the same daemon control plane. Host-owner maintenance commands such as vault-file creation/reset, installation, service registration, self-update, audit-file verification, and configuration editing run outside that API and remain part of the trusted OS/deployment boundary.
Engine tests exercise a real PTY and bash; fleet logic is unit-tested with a
mock runner; the daemon stack and SSH are integration-tested end-to-end.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/termada)<a href="https://allmcps.com/mcp/termada"><img src="https://allmcps.com/api/badge/termada?style=directory" alt="Termada on AllMCPs" /></a>