@lobsterline/mcp
v0.1.1
Published
LobsterLine MCP server — exposes terminal tools (run, send keys, interrupt, read) over the Model Context Protocol. Loopback-trusted; auth happens upstream at the relay.
Maintainers
Readme
@lobsterline/mcp
MCP server exposing terminal tools over the Model Context Protocol. A long-lived bash session backs the tools, so cd, exported vars, and shell state persist across calls.
Tools
| Tool | What it does |
|---|---|
| terminal_run | Execute a shell command. Safe/moderate runs immediately; destructive is HELD and returns a confirmation_id. |
| terminal_confirm | Run a previously-held destructive command. Only after explicit user authorization. |
| terminal_cancel | Drop a previously-held destructive command without running it. |
| terminal_send_keys | Send raw bytes to the shell (interactive prompts, TUI nav). Fire-and-forget. |
| terminal_interrupt | SIGINT (Ctrl-C) the shell. |
| terminal_read_scrollback | Tail of recent shell output (default 60 lines, max 500). |
Server-side tier classification via denylist.js:
- safe — runs immediately
- moderate — runs immediately (V1; future: short soft-hold for cancel)
- destructive (rm -rf, sudo, dd, fs reformat, ...) — HELD.
terminal_runreturns aconfirmation_idand a preview; the AI client must surface the command to the user, get explicit authorization, then callterminal_confirm({ id }). Holds expire 5 minutes after issuance. This is a multi-step hold matching the SPEC §6 destructive-confirm flow — never a flat refusal.
The agent's claimed tier argument is informational only; the server re-classifies and the held-vs-immediate decision is server-side.
Run standalone (Claude Desktop)
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"lobsterline": {
"command": "node",
"args": ["/Users/<USER>/source/LobsterLineBackend/packages/mcp/server.js"]
}
}
}Restart Claude Desktop. The four tools appear under "lobsterline" in the tools list. Spawn one shell per Claude conversation; state persists for that conversation's lifetime.
Test
npm test --workspace=@lobsterline/mcpSpawns the server, walks the MCP handshake, calls each tool, asserts behavior. ~500ms total.
Implementation notes
- Not a PTY. stdin/stdout pipes to
/bin/bash --norc -s. No terminal echo, no readline noise, no rc-file pollution. The cost: TUI commands (vim, top, less paging) won't work via this surface — they'll need the iOS WS byte-stream surface to ship. - Sentinel-based command completion. Each
terminal_runwraps the user command withprintf '##LL-DONE-<id>##:%d##\n' $?. The server reads stdout until the marker line appears, slices everything before it as captured output. - Stderr merged into stdout at the wrapper layer (
{ cmd; } 2>&1). The AI sees errors alongside normal output, single content block. - Loopback trust. No auth in this process; transport is stdio (Claude Desktop spawns it locally) or upstream-authenticated (shim, when hosted). Any caller who can reach the process gets a shell.
Hosted deployment
Not in this package. The hosted backend (Cloudflare Tunnel + Supabase JWT auth + per-user PAT support) lives in ../shim + ../web (Session 2). When deployed, the shim verifies the bearer token then forwards to this MCP server on 127.0.0.1.
