coterm
CoTerm provides an MCP-native terminal runtime with shared PTY-backed sessions, enabling AI agents to create, manage, and interact with local, SSH, WSL, or Docker sessions through 23 terminal and workspace tools.
README
CoTerm — AI Native Terminal Runtime
<div align="center">
English | 中文
</div>
The runtime layer between AI and the terminal.
CoTerm isn't another terminal emulator. It's a programmable shared terminal session runtime for Humans, AI Agents, and MCP tools.
<div align="center">
| Shared Terminal Session | Human + AI Collaboration | SSH / PowerShell / WSL / Docker |
|---|---|---|
| MCP Native | Session API | Prompt Detection |
| Screen Buffer | Multi-Agent | Session Replay |
</div>
CoTerm is a headless runtime that manages PTY-backed shell sessions and exposes them to humans and AI through a unified Session API and MCP (Model Context Protocol) server. Any terminal, AI agent, or IDE plugs into the same shared session.
Human (Tabby / WezTerm / VS Code)
│
▼
┌─────────────────────────────────────┐
│ CoTerm Runtime │
│ Session ─ PTY ─ Prompt ─ Screen │
│ Intelligence ─ Recording ─ Workspace│
│ Input Arbitration (Human > AI) │
└──────────┬──────────────┬───────────┘
│ │
Session API MCP (stdio)
(in-process) (AI agents)
What CoTerm IS
| Shared Session | One terminal session, safely shared by a Human, multiple AI agents, and MCP tools — not a new terminal per consumer |
| Terminal Runtime | Owns the PTY, screen buffer, prompt detection, and session lifecycle |
| AI Native | Agents operate a structured Session API / MCP, not raw keystrokes |
| MCP Native | 23 terminal + workspace tools over the standard Model Context Protocol |
What CoTerm is NOT
| ❌ A terminal emulator | Rendering is delegated to Tabby / WezTerm / VS Code / Windows Terminal |
| ❌ An SSH client | SSH is just one connector — same as PowerShell, WSL, Docker |
| ❌ A shell | The shell runs inside CoTerm-managed sessions |
| ❌ An AI coding agent | CoTerm is the runtime agents plug into |
Why CoTerm?
Every AI coding tool (Claude Code, OpenHands, Cline, Roo Code…) re-implements the same plumbing:
- PTY lifecycle management
- Output parsing and prompt detection
- Session state and Ctrl+C handling
- Timeouts and error handling
CoTerm solves this once. Any MCP-compatible agent connects and gets a shared, long-lived terminal session — it never re-logins, never re-initializes the environment, and never pollutes the human's terminal.
- Windows ConPTY built in — the platform most terminal-sharing tools ignore.
- Enterprise SSH flows (VPN → bastion → OTP → SSH) stay alive inside the session; AI attaches, it doesn't authenticate.
- Human always wins — priority-based input arbitration means the human can interrupt any AI command instantly.
Features
Session Management
- Full lifecycle:
created → starting → running → active → paused → closed - Create / attach / detach / close, ownership model (Human owns, AI collaborates)
Connectors
| Connector | Target | Command |
|---|---|---|
local |
Local shell (PowerShell / CMD / bash) | powershell.exe, cmd.exe, /bin/bash |
ssh |
Remote host via SSH | ssh -p <port> [-i <key>] <user>@<host> |
wsl |
WSL distribution | wsl -d <distro> --cd <dir> |
docker |
Running container | docker exec -it <container> <shell> |
Input Arbitration
- Human input always has priority; AI input is queued
- Human can interrupt any AI command with Ctrl+C (
session:interrupted) - Real-time lock/unlock state with events
Session Intelligence (L3)
- Current directory tracking (error-aware, via
cdparsing — nopwdprobe) - Toolchain detection (node / python / git / docker…) via PATH scan — no subprocess
- Full-screen app detection (
vim,top,less) via ANSI alternate-screen sequences - Command graph — every command with requester, duration, error heuristic, and output preview
AI Runtime (L4)
- Multi-AI attach — several agents share one session with distinct identities
- Session recording — JSONL event log (output, prompts, commands, interrupts)
- Snapshot / restore — capture config + screen + history, recreate a session with continuity
Workspace (L5)
- Group sessions into named workspaces (e.g. a deploy workspace of Linux / Redis / MySQL / K8s)
- Run commands across all members in parallel
Integration
- MCP server over stdio — 23 terminal + workspace tools
- Session API — programmatic TypeScript interface for terminal renderers
- CLI — full session lifecycle and inspection commands
- Windows standalone — a single
coterm.exe, no Node.js or bun required
Tech Stack
| Layer | Choice |
|---|---|
| Language | TypeScript (strict) |
| Dev runtime | bun (bundler, test runner) |
| Production runtime | Node.js (via tsx dev / pkg exe) |
| PTY | node-pty (ConPTY on Windows, forkpty on POSIX) |
| AI protocol | @modelcontextprotocol/sdk |
| CLI | commander |
| Validation | zod |
| Logging | pino (to stderr, keeps MCP stdio clean) |
Note: On Windows,
node-ptyConPTY writes are unreliable under the bun runtime. CoTerm runs the PTY layer under Node (dev viatsx, distribution viapkg). The CLI warns when launched via bun.
Quick Start
Requirements: bun (dev), Node.js 18+.
bun install
# Type-check and run tests
bun run typecheck
bun test
Activate the environment (conda-activate style)
coterm # starts the daemon (if not running) and activates the shared environment
coterm activate # same, explicit
# Now every command acts on the shared environment's default session
coterm run --command "kubectl get pods" # runs in the native shell session (no session id needed)
coterm status # cwd, toolchains, command graph
coterm list # all sessions
coterm env # environment status
coterm stop # deactivate (stops the daemon)
Commands pick the first running session when you omit a session id. To target a specific session, pass it: coterm status <sessionId>.
Configuration (~/.config/coterm.json)
The daemon reads its MCP port/host and shell defaults from a config file. CLI flags always override it.
coterm config # show config path + effective MCP endpoint
coterm config-set mcp_server_port 9000 # change the MCP port
coterm config-set defaultShell cmd.exe
{
"mcp_server_port": 8377,
"defaultShell": "powershell.exe",
"defaultCwd": "C:\\work"
}
Create sessions with connectors
coterm create --connector ssh --host jump.company.com --user admin --port 22
coterm create --connector wsl --distro Ubuntu
coterm create --connector docker --container web
Connecting an AI Agent (MCP)
Multiple agents sharing one daemon (recommended)
Run a single daemon, then any number of agents connect over HTTP and share the same sessions:
{
"mcpServers": {
"coterm": {
"type": "http",
"url": "http://127.0.0.1:8377/mcp"
}
}
}
Agent A creates a session; Agent B sees and attaches to it — one process, one shared session registry.
Single agent over stdio (ad-hoc)
{
"mcpServers": {
"coterm": {
"command": "coterm",
"args": ["mcp"]
}
}
}
Terminal tools
| Tool | Description |
|---|---|
terminal_create |
Create a session (local / ssh / wsl / docker) |
terminal_list |
List active sessions |
terminal_attach |
Attach an AI (with an optional agent id) |
terminal_detach |
Detach an AI |
terminal_read |
Read last N lines of output |
terminal_write |
Write raw input (arbitrated) |
terminal_run |
Run a command and wait for the next prompt |
terminal_wait_prompt |
Wait for command completion |
terminal_resize |
Resize the PTY |
terminal_interrupt |
Send Ctrl+C |
terminal_close |
Close a session |
terminal_status |
Structured session intelligence + presence |
terminal_history |
Recorded command graph |
terminal_recording |
Start / stop session recording |
terminal_replay |
Replay recorded events (JSONL) |
terminal_snapshot |
Capture a session snapshot |
terminal_restore |
Restore a session from a snapshot |
Workspace tools
| Tool | Description |
|---|---|
workspace_create |
Create a named session group |
workspace_add |
Add a session to a workspace |
workspace_remove |
Remove a session from a workspace |
workspace_list |
List workspaces |
workspace_run |
Run a command across all members |
workspace_status |
Show member state / presence / cwd |
Session API (for terminal renderers)
CoTerm exposes an in-process TypeScript API so terminal frontends (Tabby, WezTerm, VS Code) can embed the runtime:
import { SessionAPI } from './src/api/session-api.js';
const api = new SessionAPI();
const sessionId = await api.createSession({ shell: 'powershell.exe' });
await api.runCommand(sessionId, 'git pull', 'ai');
await api.waitForPrompt(sessionId);
console.log(api.readText(sessionId));
const unsub = api.onPromptDetected(sessionId, (prompt) => {
console.log('command finished at', prompt);
});
await api.close(sessionId);
Standalone Executables (Windows / Linux / macOS)
Package self-contained binaries — no Node.js or bun needed on the target machine:
bun run package:windows # -> coterm.exe
bun run package:linux # -> coterm
bun run package:macos # -> coterm
Pushing a v* tag runs the release workflow on all three platforms (windows-latest / ubuntu-latest / macos-latest) and publishes one GitHub Release with coterm-windows-x64.exe, coterm-linux-x64, and coterm-macos-x64. Each binary embeds the Node.js runtime, all code, and node-pty's native binaries (ConPTY on Windows, forkpty on POSIX).
Shell integration (prompt prefix + shorthand commands)
After coterm activate, the shell prompt shows a (coterm) prefix and shorthand commands
(list, status, run, stop, ...) work without the coterm prefix. It is auto-installed
on first activation — or manually:
| Platform | Command | Effect |
|---|---|---|
| PowerShell (Windows) | coterm install-powershell |
writes ~/.config/coterm/powershell.ps1, sources it from $PROFILE |
| bash / zsh (Linux/macOS) | coterm install-shell |
writes ~/.config/coterm/coterm.sh, sources it from ~/.bashrc / ~/.zshrc |
# any platform
coterm # auto-starts daemon (hidden) + activates; prompt gains "(coterm) "
list # shorthand — no "coterm" prefix needed
run --command "echo hi"
status
stop # deactivates; prompt reverts
readandhistoryshorthands are omitted on bash/zsh to avoid clashing with shell builtins (usecoterm read/coterm history).
Distribution
Ship only the single binary — it is fully self-contained. On each target machine just run it:
coterm activates (and auto-installs the shell integration on first use). Restart the shell
(or source ~/.bashrc / . $PROFILE) to see the (coterm) prompt.
Optional per-user config lives at ~/.config/coterm/config.json (mcp_server_port, defaultShell). Everything else is auto-generated at runtime.
Claude skill
A ready-to-use Claude skill lives at skills/coterm/SKILL.md —
it drives CoTerm as a pure HTTP client (calls the daemon's /cli endpoint via curl;
no MCP client config needed). Install by copying it into your agent's skills directory:
mkdir -p ~/.claude/skills && cp -r skills/coterm ~/.claude/skills/
The skill only calls the running daemon — start it first with
coterm.
Project Structure
src/
├── index.ts # CLI entry
├── main.ts # Runtime bootstrap
├── api/session-api.ts # Programmatic Session API
├── core/ # types, event-bus, session, session-manager
├── pty/ # PTY adapters (Windows / POSIX) + factory
├── connectors/ # local / ssh / wsl / docker
├── buffer/ # screen buffer, prompt detector
├── queue/ # command queue, input scheduler (arbitration)
├── intelligence/ # cwd, toolchains, screen mode, command graph
├── ai/ # multi-AI, recorder, snapshot/restore
├── workspace/ # session groups
├── mcp/ # MCP server + tools
└── cli/ # CLI commands
Roadmap
- [x] L1 Session / PTY / Prompt detection / Connectors
- [x] L2 Input arbitration + Presence
- [x] L3 Session Intelligence (cwd, toolchains, command graph, full-screen detection)
- [x] L4 AI Runtime (multi-AI, recording, snapshot)
- [x] L5 Workspace (session groups, batch commands)
- [ ] Plugin ecosystem (recorder, metrics, notification)
- [ ] CI/CD cross-platform builds
- [ ] Desktop UI (Tauri + React) as a renderer frontend
License
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.