shellphone
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@shellphonewhat's the current state of the bitlattice project?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
shellphone ๐ฆ๐
A context bridge between Claude Code and Claude Chat. Two surfaces that already talk to you individually now talk to each other, so you stop being the modem.
See SPEC.md for the design rationale. This README is how to run it.
What it actually does
At the end of every Claude Code session, a stop-hook makes Claude write a terse
digest of what just happened into .shellphone/state.md โ plain markdown, in
your repo, git-trackable. A small MCP server exposes those digests to Claude
Chat, and lets Chat queue instructions back.
you, in chat: "where's bitlattice at?"
chat: get_state("bitlattice")
โ needs-input, 2h ago, blocked on fixed vs adaptive
temperature schedule; open question about PRNG streams
you, in chat: "adaptive, seed from the repo state hash"
chat: send_instruction("bitlattice", "...")
you, later: $ claude # in bitlattice
๐ฆ๐ shellphone: 1 instruction waiting from Claude Chat โฆNo code leaves the machine. shellphone moves state about code, never the code.
Related MCP server: Herald
Install
npm install -g shellphone # or: npm link, from a cloneThen, once per repo you want on the wire:
cd ~/src/bitlattice
shellphone init
shellphone install-hooks --global # safe: hooks no-op outside shellphone reposinstall-hooks merges three hooks into ~/.claude/settings.json (or
.claude/settings.json with no --global). It never overwrites hooks you
already have, and re-running it is a no-op.
Hook | What it does |
| Asks for a digest, but only once the ledger has gone stale (see below) |
| Hands over any instruction still pending from chat |
| Catches instructions that land mid-session |
It also installs a /digest slash command.
Install as a Claude Desktop extension
Download shellphone-<version>.mcpb from the
releases page and double-click
it, or drag it into Claude Desktop. No Node install needed โ Claude Desktop
ships its own runtime.
The extension is the read side: it lets a chat session see your repos. To get digests written in the first place you also need the CLI and hooks:
npm install -g shellphone
cd ~/src/your-repo
shellphone init
shellphone install-hooks --globalThen run /survey once in a Claude Code session there, and /digest whenever
you want the chat side brought up to date.
Example prompts
Once a repo has been surveyed and has at least one digest:
"What am I working on?" โ lists every registered repo with its status, one-liner, and anything waiting (
list_repos)"Where is lattice-relax at, and what is it?" โ the project manifest plus the latest digests (
get_state)"Tell lattice-relax to use the adaptive schedule, seeded from the repo state hash." โ queues an instruction for the next Claude Code session there (
send_instruction)"Did Code pick up what I sent?" โ whether the instruction was shown to Code and whether it acted on it (
get_queue_status)
Trying it without a real project
There is no account to hand out, so there is a seed script instead. It builds a small populated repo using only the CLI, so every tool can be exercised before you have run a single Claude Code session:
bash scripts/demo-seed.sh # creates ./shellphone-demo
shellphone forget lattice-relax # undo, then delete the directoryTwo documents, two clocks
A digest answers what just changed. It cannot answer what is this, and a reader who has never seen the repo needs the second question answered first.
So there are two files, deliberately not one:
|
| |
answers | what just changed | what this project is |
written by |
|
|
lifecycle | append-only, one entry per drift | overwritten in place |
changes | every session | when the project reshapes |
/survey # in Claude Code โ reads the repo, writes the manifest
shellphone manifest # read it back
shellphone manifest --json # ...as JSONThe manifest records identity, stack, layout, entry points, settled decisions with their reasoning, constraints, gotchas, and open deliberations. The decisions field is the one that earns its place: a decision without its why doesn't stop anyone re-litigating it, which is the only reason to record it.
get_state leads with the manifest and follows with the digest, under separate
headings, so a standing fact is never mistaken for something that happened last
Tuesday. list_repos shows each repo's one-liner, which is what makes a list of
repo names mean anything.
Staleness here is reported, not thresholded โ you get "surveyed 12d ago, 40 commits since" and make your own call. Two hundred commits of bugfixes may not change what a project is, while one commit adding a subsystem does; a hard threshold would only cry wolf.
Drift, or: when does a digest get written
Digests work like context compaction. There's a verb you invoke whenever you want one, a passive signal that builds up, and an automatic trigger at the far end that you'll rarely hit.
Context window | shellphone |
|
|
"context left until auto-compact" | drift, shown in |
auto-compact at the threshold |
|
Drift is measured against the ledger, not against your session. The question is whether what Chat would read is still true, and that doesn't depend on who is asking or how long they've been asking for. Concretely, drift is commits plus changed files since the last digest โ so a session where you only talked never drifts, and one that landed three commits drifts immediately.
Three levels:
fresh โ nothing has moved. No warning anywhere, no interruption.
drifting โ something moved, but not much. A quiet note in
statusand in what Chat reads. Never interrupts.stale โ past a threshold. Chat is told, in the first line it reads, that the digest no longer describes the repo. The
Stophook asks for a fresh one.
Age alone never makes a digest stale. A month-old digest for a repo nobody has touched is still perfectly accurate, and nagging about it would train you to ignore the warning that matters.
shellphone config --staleFiles 5 --staleCommits 2 --staleMinutes 45 # defaults
shellphone config --autoDigest false # never interrupt; /digest onlyThis design came out of dogfooding. v0.1.0 wrote one digest per session, at the first stop โ so it described the least-finished state a session ever had and then went quiet for hours. The ledger didn't just go stale, it went stale while reading as current, which is worse than having no ledger at all.
Connecting Claude Code (stdio)
claude mcp add shellphone -- shellphone mcpWorth doing even though Code is the writing side: it gives Claude the
record_digest tool, which is more reliable than the CLI fallback, and lets a
Code session read the state of your other repos.
Connecting Claude Chat (HTTP)
claude.ai can't reach your laptop directly, so the HTTP transport is meant to sit behind a tunnel.
shellphone serve # binds 127.0.0.1:7373
cloudflared tunnel --url http://localhost:7373 # or ngrok / tailscale funnelAdd the resulting https://โฆ.../mcp URL as a custom connector in claude.ai, with
an Authorization: Bearer <token> header. Get the token with:
shellphone config --show-tokenThe token is generated on first run and lives in ~/.shellphone/config.json
(mode 0600). /health is unauthenticated so tunnels can probe it; it reports
nothing about your repos. Everything under /mcp requires the bearer token.
The tunnel is the real trust boundary here. Anyone with the URL and the token can read your digests and queue instructions into your repos. Treat the token like an SSH key, and take the tunnel down when you're not using it.
MCP tools
Tool | Direction | Notes |
| read | name, branch, triage status, age, pending count |
| read | latest digest + rolling history |
| read | announced vs consumed, per instruction |
| write | queues to |
| write (Code-side) | what |
| write (Code-side) | what |
Read tools are cheap and safe. send_instruction is an instruction injection into
a coding agent, and is described to Chat as something to confirm with you first.
CLI
shellphone status one line per repo: status, age, summary
shellphone attach [repo] [--watch] full latest digest + pending instructions
shellphone manifest [repo] [--json] what this project is
shellphone survey [repo] --stdin write a manifest from JSON (CLI fallback for /survey)
shellphone inbox [repo] [--all] instructions sent from chat
shellphone ack [repo] <id> mark an instruction acted on
shellphone send <repo> <text...> queue an instruction locally (test the write path)
shellphone prompt statusline fragment, silent when idle
shellphone config show or set config (see Drift, above)
shellphone forget <repo> unregister (leaves files on disk)Inside Claude Code, /digest writes one immediately โ that's the ergonomic path,
and the one to reach for before switching over to Chat.
shellphone prompt prints ๐ฆ๐2 when a repo has unread instructions and nothing
at all otherwise, so it drops straight into a statusline:
{ "statusLine": { "type": "command", "command": "shellphone prompt" } }The two trust levels
Per SPEC ยง2, read and write are gated differently, and per SPEC ยง5 the write path starts human-confirmed:
Default (
autonomous: false) โ an arriving instruction is shown to Claude along with a protocol: show it to the user verbatim, wait for a go-ahead, thenshellphone ack. Chat can put words in front of you; it can't put them in front of your compiler.shellphone config --autonomous trueโ Claude may act directly, but still has to say which instruction it's following before it starts.
Graduate to autonomous once you trust the digests. That's the whole point of running in confirmation mode first.
On-disk layout
<repo>/.shellphone/
manifest.md what the project is โ overwritten by /survey
state.md the ledger โ append-only markdown + fenced YAML
queue/inbox.md instructions from chat, pending/consumed in the heading
queue/cursor.json which ids Code has been shown (machine-only)
~/.shellphone/
registry.json known repos on this machine
config.json bearer token, host/port, autonomous flagBoth markdown files are the source of truth. Read them, hand-edit them, delete
entries from them, commit them โ shellphone re-reads and agrees with you. If
shellphone vanishes, less .shellphone/state.md still tells you what was going
on, which is the point.
Answers to SPEC ยง7
Digest granularity โ neither per-stop nor per-session: per drift. Both of the original options are wrong, and dogfooding showed why. Per-stop spams the ledger, since
Stopfires at the end of every turn. Per-session sounds right but collapses to the first stop, describing the least-finished state the session ever had. Writing when the repo has actually moved is the only version where the cost is proportional to the value. See Drift, above.Multi-machine repos โ every digest carries a
machinetag (hostname). The registry is per-machine, so two boxes with the same repo produce two ledgers that reconcile through git like any other file.Structured
next_decisionโ split in two.statusis an enum (wip/blocked/needs-input/exploratory/shipped) so chat can triage a dozen repos at a glance;next_decisionstays free text for the actual content of the choice.
Development
npm install
npm run build
npm testTests cover the two parsers, which are the load-bearing correctness surface โ model-written prose full of colons, quotes, and code fences has to survive a YAML round trip, and the queue has to deliver each instruction exactly once without losing one whose session died mid-flight.
Privacy Policy
shellphone runs entirely on your machine. It has no backend, no accounts, and no
telemetry, and the author receives nothing โ there is no server for data to be
sent to. It reads and writes plain-text files under .shellphone/ in your repos
and ~/.shellphone/, and reads repository metadata via git. It does not read,
transmit, or store your source code.
The one case where data leaves your machine is opt-in and takes two deliberate
steps: running shellphone serve and then exposing that port through a tunnel
you operate, so claude.ai can reach it. That path is off by default.
Full policy, including retention and deletion: PRIVACY.md (https://github.com/gtaghon1/shellphone/blob/master/PRIVACY.md).
License
MIT โ see LICENSE.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseBqualityDmaintenanceMCP server for managing Claude Code conversation sessionsLast updated12182MIT
- Alicense-qualityBmaintenanceThe self-hosted MCP bridge between Claude Chat and Claude Code.Last updated46AGPL 3.0
- AlicenseAqualityDmaintenanceWraps Claude Code as tools for MCP clients, enabling autonomous coding tasks via a 4-tool lifecycle with session management, async polling, and permission controls.Last updated415617MIT
- Alicense-qualityCmaintenanceEnables MCP clients to spawn and control Codex CLI and Claude Code sessions on the host machine, with session management and filesystem access.Last updated4MIT
Related MCP Connectors
Real-time chat hub for AI agents โ Claude Code, Cursor, Cline, Codex over MCP or REST.
Real-time chat hub for AI agents โ Claude Code, Cursor, Cline, Codex over MCP or REST.
Persistent memory and cross-session learning for AI coding assistants (hosted remote MCP).
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/gtaghon1/shellphone'
If you have feedback or need assistance with the MCP directory API, please join our Discord server