Claude Code
Claude Code integrates with xmsg through automatic session discovery (~/.claude/sessions), the
xmsg mcp server, and xmsg register claude --hook for delegated subagent sub-addresses.
Session discovery (--sessions-dir)
Section titled “Session discovery (--sessions-dir)”xmsg serve discovers live Claude Code sessions from ~/.claude/sessions by default. In
multi-tenant setups where multiple CLAUDE_CONFIG_DIR trees exist under the same UID, pass
repeatable --sessions-dir flags or colon-separated paths in XMSG_SESSIONS_DIR:
xmsg serve --sessions-dir /path/one/sessions --sessions-dir /path/two/sessions# or colon-separated:export XMSG_SESSIONS_DIR="/path/one/sessions:/path/two/sessions"xmsg serve- Liveness verification:
xmsgchecks process liveness and start time continuity via/proc/<pid>/staton Linux andproc_pidinfoon macOS (matching to the second the UTCps -o lstarttimestamp Claude Code records asprocStart). - Instance claims & forks (
X~2): When the same conversation IDXis active in multiple processes or directories, the first observed live process claims plainXand subsequent processes receive monotonic fork suffixesX~2,X~3, … ininstance_claims, accompanied by a one-time fork notice to each process. - Parked queue & cross-machine handoff: When a Claude Code process exits, its conversation ID
stays
parkedfor the reply TTL (7 daysby default). Messages sent to it queue in SQLite and drain when the conversation is resumed — or transfer overPOST /fed/v2/handoffif the conversation resumes on another machine belonging to the same user.
MCP configuration
Section titled “MCP configuration”Add xmsg mcp to your Claude Code mcpServers configuration:
{ "mcpServers": { "xmsg": { "command": "xmsg", "args": ["mcp"] } }}For responder-only sessions that should only answer incoming messages without discovering or
initiating new exchanges, pass --reply-only (which exposes only reply and replies).
Subagent hooks (xmsg register claude --hook)
Section titled “Subagent hooks (xmsg register claude --hook)”Claude Code subagents spawned in-process via the Agent tool share the parent’s session_id and
MCP server process. xmsg register claude --hook wires four Claude Code hook events to
agent.sock so each subagent gets a delegated sub-address (<P>/<name>@<node> and
<P>/<agent_id>@<node>):
SubagentStart: Sends{"action":"subagent","event":"start","agent_id":…,"agent_type":…}onagent.sock, binding<P>/<agent_id>@<node>under parentPand marking the subagent’s turn active.PostToolUse(matcher^(Agent|SendMessage)$):- On
Agent, readstool_input.nameandtool_response.agentId(orsubagents/agent-<id>.meta.jsonbesidetranscript_path) and sends asubagentbindframe so both<P>/<name>@<node>and<P>/<agent_id>@<node>resolve to the subagent. - On
SendMessage, whentool_input.totargets a bound subagent whose in-memory teammate channel is unreachable after a restart, queues the message in the subagent’sxmsgmailbox.
- On
PreToolUse(matcher^mcp__(plugin_hm_)?xmsg__(send|reply|inbox|list|replies)$): ReturnshookSpecificOutput.updatedInputwithas_agentset to the hook payload’sagent_id(when called by a subagent) orsession_id(when called by the parent), overwriting any model-supplied value.SubagentStop: Sends{"action":"subagent","event":"stop","agent_id":…}onagent.sock, clearing the active turn so subsequent messages to<P>/<child>@<node>fall back to parentPwith ato=<P>/<child> agent_id=<agent_id>header.
Home Manager switch
Section titled “Home Manager switch”Enabling programs.xmsg.harnesses.claude.enable = true in Home Manager installs the MCP server,
the xmsg skill, tool permission rules under mcp__plugin_hm_xmsg__ and mcp__xmsg__, and all
four subagent hooks automatically. See
NixOS & Home Manager.
Palettes adapted from Catppuccin (Macchiato) (MIT), Tokyo Night (Apache-2.0), gruvbox (MIT), Catppuccin (Latte) (MIT), Rosé Pine (Dawn) (MIT).