Skip to content

feat(mcp): let LLMs drive alacritree via an MCP server#52

Merged
mathix420 merged 1 commit into
masterfrom
mcp
Jul 13, 2026
Merged

feat(mcp): let LLMs drive alacritree via an MCP server#52
mathix420 merged 1 commit into
masterfrom
mcp

Conversation

@mathix420

Copy link
Copy Markdown
Owner

What

Adds alacritree mcp — a stdio Model Context Protocol server that bridges tool calls to the running app, so LLM agents can browse projects/worktrees, open shells in them, type into terminals, read their output, and inspect git state.

claude mcp add alacritree -- alacritree mcp

How

Two pieces, mirroring upstream alacritty's IPC design (polling/ipc.rs):

  • ipc.rs — the app listens on a unix socket at $XDG_RUNTIME_DIR/alacritree/alacritree-<pid>.sock, advertised to child PTYs via ALACRITREE_SOCKET (same trick as ALACRITTY_SOCKET), so an agent running inside an alacritree session automatically targets the instance hosting it. One newline-delimited JSON request per connection with an {"ok"}/{"error"} reply. Requests touching app state hop to the UI thread over an mpsc channel drained once per frame (woken by request_repaint, per the EventProxy contract); slow operations (git-status walks, worktree creation with its git fetch) run on the connection thread so they never stall a frame.
  • mcp.rs — hand-rolled newline-delimited JSON-RPC (tools only), no SDK/tokio so the crate stays fully synchronous. Tool names + arguments map 1:1 onto IpcRequest serde tags. Socket discovery: env var → runtime-dir scan, --socket <path> to override.

Tools

Tool What it does
list_projects Sidebar projects with worktrees, branches, default branch
list_sessions Sessions: id, title, workspace, kind, size, active tab, attention flag
select_workspace Focus a workspace, like clicking it in the sidebar
create_session / close_session Open/close a shell session in a workspace
send_text Type into a terminal (control chars pass through; \r submits)
read_screen Screen text + cursor position + optional scrollback
git_status Staged/unstaged files and per-file +/- vs the default branch
create_worktree Same flow as the sidebar's + button (fetch, branch, LLM-config copy)
refresh_project Re-scan a project's worktrees

Worktree deletion is deliberately not exposed — destructive, and the UI gates it behind a confirm dialog for good reason.

Config / platform

  • [general] ipc_socket = false disables the socket — same option name and location as alacritty's.
  • IPC is unix-only, matching upstream; on Windows alacritree mcp fails fast with a clear message and the app simply doesn't bind a socket.

Testing

Verified end-to-end against the live app on sway: registered the bridge, listed real projects/sessions, spawned a session, sent echo hello-from-mcp $((6*7))\r, read hello-from-mcp 42 back via read_screen, pulled git_status (correctly reported this branch's own then-uncommitted files), exercised the unknown-worktree error path, and closed the session. Protocol edge cases (unknown tool → -32602, unknown method → -32601, notifications unanswered, ping) covered against a mock socket. cargo fmt + cargo check clean.

🤖 Generated with Claude Code

Add `alacritree mcp`, a stdio Model Context Protocol server that bridges
tool calls to the running app over a new IPC socket, so agents can browse
projects/worktrees, open shells, type into terminals, read screens, and
inspect git state.

The socket mirrors alacritty's polling/ipc.rs design: unix-only, one
newline-delimited JSON request per connection, bound at
$XDG_RUNTIME_DIR/alacritree/alacritree-<pid>.sock and advertised to child
PTYs via ALACRITREE_SOCKET — an agent running inside a session targets
the instance hosting it. Requests touching app state hop to the UI thread
through an mpsc channel drained once per frame (woken by request_repaint);
git-status walks and worktree creation run on the connection thread so
they never stall a frame.

Tools: list_projects, list_sessions, select_workspace, create_session,
close_session, send_text, read_screen, git_status, create_worktree,
refresh_project. Worktree deletion is deliberately not exposed.

The MCP side is hand-rolled newline-delimited JSON-RPC (tools only) to
keep the crate synchronous instead of pulling in an SDK plus tokio.
`[general] ipc_socket = false` disables the socket, matching alacritty's
option of the same name.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mathix420 mathix420 merged commit 17a7d47 into master Jul 13, 2026
2 checks passed
@mathix420 mathix420 deleted the mcp branch July 13, 2026 09:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant