Content
# lifeline
A tiny watchdog MCP server for Claude Code on Windows.
When the MCP server Claude Code is working through crashes or hangs, its tools
stop responding and there is no tool left to call to fix it, so the session
stalls until someone steps in. lifeline is a second MCP server that removes that
dead end. It runs separately, on system Python, with zero dependencies, so it
stays up when the other one goes down. Claude can call its `reboot` tool to kill
the stuck server and drive Claude Code's `/mcp` reconnect, then pick the task
back up on its own, with a fallback shell and file reader to use in the meantime.
It is deliberately small and self-contained: one stdlib-only file, raw JSON-RPC
over stdio, no MCP SDK. There is almost nothing in it that can break.
## Requirements
- **Windows.** It uses Win32 (via ctypes) to enumerate processes and to inject
keystrokes into the Claude Code terminal. It will not run on macOS or Linux
as-is.
- **Claude Code.** The reboot flow drives Claude Code's `/mcp` menu.
- **Python 3.8+** on PATH. No pip packages.
## Tools
- `reboot` - kill the target MCP server and trigger a Claude Code `/mcp`
reconnect, which relaunches it. Use when the target's tools are failing.
- `status` - report whether the target server and Claude Code are running, with
PIDs and the process ancestry lifeline is using.
- `shell` - run a shell command. A fallback terminal for when the target is down.
- `read_file` - read a file. A fallback for when the target's file tools are down.
## How reboot works
1. Find the Claude Code process by walking up lifeline's own process tree.
2. Find the target server process by matching `TARGET_MATCH` against process
command lines, limited to the current Claude Code session's process tree so it
never touches another session's server.
3. Kill it (unless you pass `kill_first=false`).
4. Inject keystrokes into the Claude Code terminal: `/mcp` then Enter to open the
server menu, Enter to select the server, Down to the Reconnect action, Enter
to fire it. Claude Code reconnects, which relaunches the server.
Step 4 is the fragile part. See Adapting below.
## Install
lifeline is one file. Point Claude Code at it and run it with your **system**
Python, not the target server's virtualenv. That is the whole point: it should
survive if the target's environment is what broke. `example_config.json` shows
the shape:
```json
{
"mcpServers": {
"lifeline": {
"command": "python",
"args": ["C:/path/to/lifeline/server.py"],
"env": {
"LIFELINE_TARGET_MATCH": "my-mcp/server.py",
"LIFELINE_TARGET_LABEL": "my-mcp"
}
}
}
}
```
## Adapting it to your setup
Everything you need to change is the CONFIG block at the top of `server.py`, or
the matching `LIFELINE_*` environment variables:
- `TARGET_MATCH` - a substring that uniquely identifies your server's launch
command. `server.py` works if it is your only Python MCP server; if you run
several, narrow it (for example `my-mcp/server.py`, or a distinctive folder
name). Matching is already limited to your Claude Code session's process tree.
- `TARGET_LABEL` - cosmetic name used in status and log messages.
- `SHELL_CWD` - working directory for the `shell` tool.
**The `/mcp` menu choreography is the part most likely to need tweaking.** The
injection in `run_injection()` assumes the target is the FIRST server listed in
Claude Code's `/mcp` menu and that Reconnect is one Down from the top (Enter,
Down, Enter). If you have several MCP servers, a different menu order, or a
Claude Code build whose menu differs, adjust that stage sequence, and the
`DELAY_*` timing constants if injection is racing the UI. lifeline writes an
`inject.log` next to `server.py` recording each stage, which makes tuning quick.
## Safety
This is a recovery tool, so it is intentionally powerful and unsandboxed: `shell`
runs arbitrary commands, `read_file` reads any path, and `reboot` kills processes
and types into your terminal. Only ever run it locally, as your own MCP server.
Do not expose it over a network.
## License
MIT. See LICENSE.