termius-mcp
by yapp
README.md
# termius-mcp
<p align="center">
<img src="assets/logo.png" alt="termius-mcp logo" width="256">
</p>
MCP server that drives visible terminals in a running Termius app.
> **Local only.** This server connects to a locally running Termius desktop app via the Chrome DevTools Protocol on `localhost:9229`.
## Prerequisites
Termius must be running with remote debugging enabled. On macOS:
/Applications/Termius.app/Contents/MacOS/Termius --remote-debugging-port=9229
At least one Termius window must be open. The server connects to the primary renderer (the main Termius UI), injects a bridge that exposes the Termius mediator API, and registers MCP tools that call into that bridge.
## Quick Start (with an MCP client)
Install once globally, or use `npx` to always run the latest version without install:
npx -y termius-mcp
Then wire it into your MCP client. Pick your client below.
### Claude Desktop / Claude Code
`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows:
```json
{
"mcpServers": {
"termius-mcp": {
"command": "npx",
"args": ["-y", "termius-mcp"]
}
}
}
```
On Windows, Claude Desktop needs the `cmd /c` wrapper:
```json
{
"mcpServers": {
"termius-mcp": {
"command": "cmd",
"args": ["/c", "npx", "-y", "termius-mcp"]
}
}
}
```
### Cursor
`~/.cursor/mcp.json` (or `.cursor/mcp.json` in the repo for project-scoped):
```json
{
"mcpServers": {
"termius-mcp": {
"command": "npx",
"args": ["-y", "termius-mcp"]
}
}
}
```
### opencode
Add to your `opencode.json` / `opencode.jsonc`:
```json
{
"mcp": {
"termius-mcp": {
"type": "local",
"command": ["npx", "-y", "termius-mcp"]
}
}
}
```
### Cline (VS Code)
`cline_mcp_settings.json`:
```json
{
"mcpServers": {
"termius-mcp": {
"command": "npx",
"args": ["-y", "termius-mcp"]
}
}
}
```
### From source (for development)
git clone https://github.com/yapp/termius-mcp.git
cd termius-mcp
npm install
npm start
A repo-root `.mcp.json` is provided so Cursor / Claude Code / VS Code MCP builds can auto-discover the server without writing the config by hand.
## Usage
Once connected, ask the client to:
1. Open a local terminal in Termius (`terminal_create`).
2. Send a command to it (`terminal_send`).
3. Read the output (`terminal_read`).
The initial CDP connection is non-fatal. If Termius is not running when the server starts, the next tool call retries the connection.
## Tools
### Local terminals
| Tool | Description |
|---|---|
| `terminal_create` | Open a new Local Terminal in the Termius UI. Optional `command`, `cols`, `rows`. Returns the terminal id (UUID). |
| `terminal_send` | Write a raw string to terminal stdin via `mediator.shell.sendData`. |
| `terminal_read` | Drain buffered output. `wait=true` blocks up to `timeoutMs`; `snapshot=true` also returns visible xterm buffer lines. |
| `terminal_resize` | Resize both the xterm renderer and the pty (`shell.sendSize`). |
| `terminal_kill` | Close the terminal via `mediator.shell.close`. |
| `terminal_list` | List terminals managed by the bridge, including terminals opened in the UI before the server connected. |
| `terminal_send_keys` | Send a named special key (`Ctrl+C`, `Enter`, `Tab`, arrow keys, etc.) as the right escape sequence. |
### Existing SSH saved-host sessions
These tools operate on terminals that already exist in the running Termius app, typically SSH saved-host sessions opened from the UI. They auto-sync the bridge with the Redux state, so SSH terminals whose `.terminal` DOM element is not mounted (hidden tabs) remain addressable by `terminalId`. No credentials are needed: the bridge piggybacks on Termius's already-authenticated session.
| Tool | Description |
|---|---|
| `ssh_list_sessions` | List live terminal sessions from the Redux store with metadata: `connectionProtocol`, `address`, `hostLabel`, `isActive`, `osName`, `managed`. Optional `protocol` / `active` filters. |
| `ssh_send` | Write a raw string to an existing SSH session stdin. |
| `ssh_read` | Drain buffered output from an existing SSH session. Same options as `terminal_read`. |
| `ssh_wait_for` | Wait for a substring to appear in the output buffer. Useful for waiting for a prompt or a marker. Optional `drainOnMatch`. |
| `ssh_send_keys` | Send a named special key to an existing SSH session. |
| `ssh_sync` | Manually sync the bridge with the live Termius state. Called automatically by the other SSH tools. |
## Configuration
| Variable | Default | Description |
|---|---|---|
| `TERMIUS_CDP_HOST` | `localhost` | CDP endpoint host. |
| `TERMIUS_CDP_PORT` | `9229` | CDP endpoint port. Must match the `--remote-debugging-port` flag passed to Termius. |
## Testing
Smoke test against a running Termius instance (exercises `list`, `create`, `send`, `read`, `resize`, `sendKeys`):
npm run smoke
End-to-end test that creates terminals, sends commands, and reads output:
npm test
Both require Termius running with `--remote-debugging-port=9229`.
## Requirements
- Node.js with ESM support
- Termius desktop app (developed against v10.0.6)
- Network access to `localhost:9229`
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues