An MCP server that lets AI agents act like a human at a real terminal, local or over SSH.
Runs on your machine from its package; the steps are below.
At most: moves money, runs code or commands, deletes data, or sends messages for you.
Odel charges nothing per call. The publisher may charge for its own service.
Runs locally over stdio
This server isn't hosted — your MCP client launches it from a package registry. Use one of the commands below, or drop the config into your client (e.g. Claude Desktop).
Run
docker run -i --rm ghcr.io/open-mcp-ai/termcp:0.2.7
MCP client config
{
"mcpServers": {
"termcp": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/open-mcp-ai/termcp:0.2.7"
]
}
}
}
English | 中文
Lightweight AI-native secure terminal: visual multi-surface, MCP + SKILLS + API
| Agent | Command |
|---|---|
| Claude Code | claude mcp add termcp -- npx -y @open-mcp-ai/termcp daemon stdio |
| Codex | codex mcp add termcp -- npx -y @open-mcp-ai/termcp daemon stdio |
| Gemini CLI | gemini mcp add termcp npx -- -y @open-mcp-ai/termcp daemon stdio |
| Crush | add to ~/.config/crush/crushrc: mcp add termcp --command npx --args -y --args @open-mcp-ai/termcp --args daemon --args stdio |
{
"mcpServers": {
"termcp": {
"command": "npx",
"args": ["-y", "@open-mcp-ai/termcp", "daemon", "stdio"]
}
}
}
That command is the whole server: it starts the background instance on first use, relays MCP over stdin/stdout, and the instance exits on its own once idle. Ready to go as-is.
| Command | |
|---|---|
| npm | npm i -g @open-mcp-ai/termcp — installs a termcp command; with it, drop npx -y @open-mcp-ai/termcp from every snippet above and use termcp. Wrapper: open-mcp-ai/Termcp-npm. |
| Go | go install github.com/open-mcp-ai/termcp@latest — GOPROXY=https://goproxy.cn,direct in mainland China; also usable as a module (go get github.com/open-mcp-ai/termcp). |
| Docker | docker run -d --name termcp -p 18765:18765 -v termcp-data:/home/termcp -e TERMCP_AUTH_TOKEN=change-me-to-a-long-random-secret ghcr.io/open-mcp-ai/termcp:latest termcp --no-internal --host 0.0.0.0 --port 18765 |
| Binary | Prebuilt releases — linux / darwin / windows on amd64 / arm64, one static file each. |
The npm wrapper downloads the matching prebuilt binary (override with TERMCP_VERSION, TERMCP_MIRROR,
TERMCP_BIN, TERMCP_SKIP_DOWNLOAD). Flags: docs/cli.md. Docker recipes, Compose and a
token-free loopback setup: docs/deploy.md.
HTTP transport, when an instance is already answering somewhere (npx -y @open-mcp-ai/termcp):
{
"mcpServers": {
"termcp": {
"type": "http",
"url": "http://localhost:18765/stream"
}
}
}
Reachable from a client in Docker as http://host.docker.internal:18765/stream (macOS/Windows) or the host's
LAN IP; from another container on the same network as http://termcp:18765/stream. Legacy SSE uses
http://localhost:18765/sse — only /sse, JSON-RPC goes to /message by itself. With
--auth-token, add a bearer header: "headers": {"Authorization": "Bearer <token>"}.
Open http://127.0.0.1:18765 — every agent session appears here.
A shell's timeline marks each line by its source — green shell output, yellow your input, pink the agent's.
At sudo, a password, MFA or [Y/n], the agent calls notify_user to hand the prompt back to you; you type
the secret in the browser, where it stays out of the model's context.
| Sessions | Many long-lived SSH connections at once — to this host (ssh_config="internal", zero config) or to any remote host; each session holds several shells, forwards and SFTP. |
| Terminals | Full pty (ConPTY on Windows) and line-oriented pipe channels on one connection; arbitrary rows/cols; input, named keys, resize. |
| Output | Byte-cursor reads (tail / offset / live reader), paged from disk and replayable after a restart; per-line timeline of who wrote what. |
| Files | SFTP browse, read, write, rename, delete, mkdir, permissions, links — plus HTTP URLs with Range resume. |
| Forwarding | -L local, -R remote, -D SOCKS5, over ProxyJump bastion chains. |
| Notifications | shell_notify wakes the agent on exit / silence / new output; notify_user toasts the human with the instance URL. |
| SSH profiles | A central TOML store with batch import/export, in-memory temporary hosts, connection testing, and edit/copy/rename. |
| Review mode | Per-session approval gate: every agent write waits for a human decision. |
| Discovery | shell_detect finds the target's interactive shell instead of guessing from the local PATH. |
| Agent Skill | Instances serve /skills.md, so an agent drives everything with plain curl. |
ssh_config are stored on the host only and never read back; the MCP read interface returns profile names. Profile write tools stay off unless --mcp-manage-ssh-configs is set, and --no-internal narrows agents to remote hosts.--auth-token, or a salted --auth-hash so the server holds no plaintext — Web UI, REST, both MCP transports and the WebSocket. A non-loopback bind requires it.session_not_running; output reading keeps working, and the session's port forwards close with it.docs/cli.md | Every flag and subcommand, capability gates, authentication. |
docs/clients.md | All entrances end to end: MCP transports, the stdio bridge, Skill install, REST examples. |
docs/deploy.md | Docker, multi-stage builds, Compose, pure-API build. |
docs/mcp-tools.md | All 31 MCP tools: parameters, return shapes, error codes. |
docs/api.md | REST endpoints, WebSocket frames, locator resolution. |
docs/architecture.md | Session kernel, entrances, storage. |
docs/design/ | Design records: Web UI, resource model, session storage, font stack, mobile terminal. |
CHANGELOG.md | Release notes. |
Released under the MIT License. You are free to use, modify, and distribute it, provided the copyright notice and permission notice are retained. Thanks to the linux.do community for the discussions and support.