everett
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
Everett
Route requests, messages, and shared memory across your coding-agent sessions—from a CLI or MCP client.
Works with: Claude Code · Codex · OMP · Pi · Hermes Agent · Grok CLI · Devin CLI. T3 Code threads are recognized through their underlying harness sessions. OpenAI dots and Grok Bot connect through registered external MCP inboxes. Hark and Muse compatibility is unverified.
Everett Local packages the installed runtime for local plugin clients. ChatGPT custom MCP connections use the gateway over HTTPS or Secure MCP Tunnel. See ChatGPT setup, supported modes, and verification.
Wake support: Claude Code has native local wake and an optional relay receiver policy. Dots and Grok Bot can use owner-configured webhook nudges. Other harnesses use headless resume or inbox pickup. See agent support and wake.
The maintainer waived the v2.2.0 live proof bar; live same-org, cross-org, and external-binding evidence is not recorded. See the proof-bar status. See also Grok Bot 0.77 reachability.
Quickstart
Everett is one native binary for macOS and Linux. Have at least one harness CLI on your PATH.
Local sessions, routing, inboxes, hooks, MCP, and SSH peers work without an Everett account.
The hosted relay is https://relay.raitox.tech. Account identity stays
https://everett.raitox.tech. Hosted enrollment follows the deployed service's
account policy. The repository's public deployment profile enables separate
GitHub account namespaces; self-hosted deployments can restrict enrollment to one owner.
To install and configure local agents without browser sign-in:
curl -fsSL https://raw.githubusercontent.com/raitoxlol/everett/main/install.sh | sh # ~/.local/bin
export PATH="$HOME/.local/bin:$PATH"
everett onboard --yes --no-backfill
everett doctorOr via Homebrew or Cargo:
brew tap raitoxlol/tap && brew install everett
cargo install --git https://github.com/raitoxlol/everett everett # from sourceonboard --yes --no-backfill backs up and applies the default hook and MCP registrations
for detected agents without an interactive review. It skips older session cards and does
not sign in, require a routing key, or schedule nightly merges. To inspect registration
examples without changing files, run everett install-hooks and everett install-mcp.
Those commands can include agents that onboarding has not detected; they are not an
exact preview of its selected changes.
Onboarding detects installed CLIs even before their first session. It backs up and registers
hooks and MCP for detected Claude Code, Codex, OMP, and Grok installations. Restart those clients,
then run everett ls. Doctor checks the registered launchers and lists your exact next steps.
For Pi and Devin run everett install-hooks --pi --apply / everett install-hooks --devin --apply
so their MCP calls bind to the right session; Hermes needs one config entry (everett install-mcp --hermes).
See MCP caller identity.
No router key or model call is needed for this setup. Codex may ask you to enable/trust its hooks.
install.sh verifies the release checksum; EVERETT_VERSION=vX.Y.Z pins a release and
EVERETT_INSTALL_DIR changes the target directory. Rerun it to update.
From source (needs a Rust toolchain): cargo install --git https://github.com/raitoxlol/everett everett,
or cargo install --path everett-rs from a checkout.
Upgrading from the retired Python package (pipx). Install the binary, then run
everett install-hooks --apply and everett install-mcp --apply. They back up each file and replace
the Python hook commands, -m everett mcp launchers (and their PYTHONPATH), and the OMP extension with
the native binary. Then pipx uninstall everett-sessions.
Setup options
Run everett in a terminal to start onboarding on first use. Successful setup records that the
wizard was applied, not that an agent has loaded its tools. Cancellation or an apply error leaves
first-run setup pending. Later bare runs show help. Run everett onboard to repeat setup. Explicit
commands and noninteractive bare runs do not prompt.
The terminal flow is welcome, choose local setup or account sign-in, choose agents, per-agent setup guides,
review/apply, then a copyable instruction prompt. With a configured hosted Cloudflare issuer, the
CLI opens the approval page locally, prints a URL and code usable on another device, waits for
approval, saves its private credential, and verifies its identity with the server before continuing.
SSH sessions keep the URL/code path. Fresh interactive setup defaults to
https://relay.raitox.tech for the network endpoint, with account identity
https://everett.raitox.tech. That service accepts GitHub accounts into separate relay namespaces.
Explicit account configuration is preserved. After a failed or cancelled sign-in, press
l in the terminal wizard to continue locally. To skip browser sign-in entirely, use the
account-free quickstart above. See account setup.
Local choices use detected sessions and installed CLIs. Cloud and VM tabs include Dots, Grok Bot, Hark, Muse and another computer. Each selected local agent gets a guide for its actual settings, restart and tool verification. Cloud/VM choices remain pending until their own connection is completed. Everett account approval, local hooks/MCP and external-client OAuth are separate. Muse and Hark compatibility is unverified.
Space selects a local agent's supported integrations together. Press d for individual controls and
file paths. At review, d shows exact changes and v opens Advanced. Routing keys, nightly merges,
and older session cards live there. Cards and nightly merges start off in the interactive wizard.
--schedule-merge explicitly enables the schedule. Plain prompts and --yes retain their defaults.
The result distinguishes apply errors from settings saved. Loading and using Everett tools in the
chosen agent still needs verification. The final prompt asks each agent to read its appropriate
instruction Markdown and show a scoped addition before applying it. The wizard never edits those
instruction files. The prompt is printed after leaving the full-screen UI so it can be selected and
copied. Results, guides and the prompt scroll with j and k.
q, Escape or Ctrl-C cancels before apply; completed account approval is retained. d on welcome
opens the optional explanation, with Overview, Local, Cloud and VM tabs on keys 1-4; the chooser
uses 1-3. A usable terminal starts at 54 columns and 14 rows. Smaller terminals ask you to resize.
Without a usable terminal, Everett uses plain prompts. While entering a key, Escape or Ctrl-C cancels.
The welcome has an animated balloon and multiple colors. Set EVERETT_NO_ANIM=1 to disable motion
or NO_COLOR=1 to disable color. Input stays available during animation. To review with synthetic
sessions in a disposable home, build the debug binary and run sh scripts/demo-onboarding.sh.
Captured terminal journey uses actual PTY cells from synthetic sessions, rendered with Menlo on a dark canvas. It is not a Termius screenshot.
--yes explicitly applies defaults without prompting:
everett onboard --yes # apply every default, non-interactively
everett onboard --yes --span-days 7 # backfill cards for the last 7 days (default 3, 1-30)
everett onboard --yes --no-backfill # skip card backfill
everett onboard --yes --no-mcp # skip MCP registration
everett onboard --yes --jev-key-env MY_KEY # save a Jev key from an env var (validated first)
everett onboard --yes --schedule-merge # macOS/Linux: also schedule nightly `everett trunk merge`Smarter routing (optional). Jev (typesafe.ai) picks the right session
when many are running; without it, routing uses local BM25 matching without network calls.
Harness resumes and LLM memory merges use their model providers. The onboarding step offers
"paste a key" or "skip" -- if a key is already found
(TYPESAFE_API_KEY, ~/.everett/config.toml, or ~/.hermes/.env), it shows "Jev key found ✓
(source)" and defaults to skip. A pasted key is validated with one test route call (5 s timeout);
on failure you can keep it anyway or skip. The key is masked while typing and never echoed or
logged, and is saved as typesafe_api_key in ~/.everett/config.toml (created chmod 600,
preserving every other key). The same step has a "merge shared memory nightly" toggle -- see
Nightly auto-merge below.
Everett reads the session stores the harnesses already write: ~/.claude/projects,
~/.codex/sessions, ~/.omp/agent/sessions, ~/.pi/agent/sessions, ~/.grok/sessions,
Hermes' state.db files, the Devin CLI's sessions.db (plus transcripts/*.json),
and T3 Code's ~/.t3/userdata/statev2.sqlite (legacy state.sqlite fallback). Every database is opened read-only.
Cloud agents use explicit local registrations and the native restricted MCP gateway, not fabricated
provider transcripts or API-model substitutes. See OpenAI dots setup,
Grok Bot registration, polling, and webhook wake, and gateway permissions.
Owner-side connector setup is required; queued messages do not prove pickup. A matching owner
webhook is the supported Grok Bot wake path: Wake a Grok Bot.
Manage local bindings with everett external add, list, and remove.
Keep an OpenAI tunnel client forwarding with everett tunnel watch; a ready
health check does not show a stuck control-plane poll. See the dots doc.
Related MCP server: handoffs
Demo
Local dashboard (Rust binary)
cargo install --path everett-rs
everett dashboard
everett --hours 168 dashboard --port 7347 --no-openThe Mac-first dashboard opens automatically on macOS and prints its loopback URL
on other platforms. It reads the same provider stores and Everett cards as
everett ls, showing up to 80 recent non-automated sessions. Search by project,
card, or session ID; filter by harness or state; expand a row for the full card
body, provider/source details, and copyable inbox-send, local-route, and events
commands. Refresh rescans local data. CLI listings retain their compact card
summaries.
It is read-only: copying a command does not execute it, deliver a message, or
wake an agent. “Active” is Everett's existing process/recency heuristic, not a
verified agent heartbeat. The server binds only to 127.0.0.1, rejects foreign
Host headers and write methods, and sends no session data to a hosted service.
Stop it with Ctrl-C.
Future direction: a hosted dashboard could expose cross-device local activity. Optional account auth and inbox-only SSH/Cloudflare peer transports exist, but dashboard hosting/session synchronization (including a custom-domain frontend on Vercel) do not. A Rust local-data service would still be required; a static website cannot read another device's session stores.
This is example output (paths and ids are shortened):
$ everett ls
● claude 2m ~/src/api API: adding retry/backoff to upload client; next: integration test
○ codex 40m ~/src/web Web: dark-mode toggle in settings; state: styles done, wiring store
○ omp 3h ~/src/infra Infra: Terraform module for the staging bucket
$ everett route "the upload retries should cap at 5"
SESSION (choice=s0, confidence=0.84, router=local)
→ [claude] ~/src/api — API: adding retry/backoff to upload client
cd ~/src/api && claude --resume 3f1c… 'the upload retries should cap at 5'
$ everett send "the upload retries should cap at 5"
SENT [claude] ~/src/api — API: adding retry/backoff to upload client
Done. MAX_RETRIES is now 5 and the backoff test covers the cap.● means running (its id is in a live process, or its file changed in the last 10 minutes).
Commands
Command | What it does |
| Recent sessions from every harness, one line each. |
| Sessions on one paired SSH device, with |
| List active Cloudflare device bundles. |
| Pair at an explicit SSH address; require both confirmed fingerprints. |
| Restricted sshd endpoint; no hosted address publication. |
| SSH polls/imports replies; relay queries queued/delivered/claimed/replied/expired state from signed observations (not task completion). |
| Receive encrypted messages through Cloudflare push notifications and authenticated HTTPS inbox reads. Claude session wake and external webhook posts follow the local owner policy. |
| Register this agent's keys and display name, list active key bundles (maximum 256), or verify account/agent authorization. |
| Hosted Cloudflare enrollment labels beside device IDs and fingerprints. Advisory only; the default JSON bundle list is unchanged. |
| Opt in to sharing this exact local session's card, or withdraw it. The backend derives its authenticated author and agent. |
| List exposed authenticated author/session cards across the account, without device pairing. |
| Update this Cloudflare device's hosted label. Device ID, keys, and pins stay the same. |
| Revoke this or an admin-selected agent, remove org membership (admin), or rotate this agent's relay keys using its old signing key. |
| Pin a device on the selected relay after out-of-band bundle confirmation; fingerprint is raw 64-character lowercase hex, not the SSH |
| Inspect device keys/peers; remove a remote authorization or revoke a local tagged client key. |
| Native Rust binary only: read-only local browser dashboard with session cards, filters, activity state, and copyable CLI actions. |
| Picks the session a request continues: |
| Routes and pings immediately. Idle local sessions run headless; verified local Claude background sessions receive a native inbox nudge. Unsupported transports fail without queue fallback. |
| Default |
| Queues the request, then explicitly wakes an existing local Claude Code background session through a PTY and waits for a reply linked to that inbox message. Requires an interactive local terminal and Claude Code 2.1.285 or newer. The sender cannot request this native wake through |
| Answers an Everett message; the reply goes to the sender's inbox. |
| Checks one local ping path with a random nonce canary and a correlated inbox reply. Default timeout is 120 seconds. Dry-run resolves the target and transport without sending. See wake proofs. |
| Shows the messages waiting for this session (or the human inbox when run outside a session) and marks them delivered; |
| Records what this session is doing (see Events). |
| Recent events across sessions. |
| Delivers another session's (or a project's) events to your inbox. |
| Skips routing and delivers to one session. The target is an exact id, a unique id prefix, an exact title (case-insensitive), the card's name ( |
| When routing says |
| Card coverage per harness: agent-written, automatic, missing. |
| Human setup TUI (welcome, account approval, agents, guides, review/apply and instruction prompt; optional settings under Advanced); |
| Prints the hook registrations. |
| Runs the stdio MCP server (harnesses start it; see below). |
| Prints or registers the MCP server for each harness. |
| Installed CLIs, stores, hooks, live stdio/MCP registration checks, cards, router, and account diagnostics; SSH revocation remains explicit. |
| Pushes a fact to the shared core inbox. Secrets are rejected. |
| Distills the inbox into the shared core. |
| Shows the core a new session in this folder receives, the file to edit, or past merges. |
| Writes the session list as a Markdown note into your notes vault (optional). |
| Prints (default) or, with |
| Native Rust binary only: signs this device in to an Everett account with Cloudflare native device approval (see Accounts). |
| Verifies the saved Cloudflare credential online. |
| Deletes the local Cloudflare credential; optionally confirms hosted device revocation first. |
| Permanently revokes self or a same-owner device as admin, and removes matching local peer configuration and pins. SSH authorizations must be revoked separately. |
Global option: --hours N sets the look-back window (default 72).
How delivery works
Harness | Resume (send) | New session (--spawn) |
Claude Code |
|
|
Codex |
|
|
OMP |
|
|
Pi |
|
|
Hermes Agent |
|
|
Grok CLI |
|
|
Devin CLI |
|
|
T3 Code | Inbox; hooks where supported, otherwise explicit MCP polling; no CLI resume | not supported |
OpenAI dots / Grok Bot | Registered external inbox via owner-authorized MCP; no provider resume. Optional owner webhook nudge: Wake a Grok Bot. | not supported |
The harness appends the request and the reply to that session's history. Hermes sessions that belong to a chat platform (Telegram, Discord, and so on) are listed and routable, but send refuses them, because a CLI resume would not reach that chat. Scripted Hermes runs (cron, oneshot, webhook) are hidden like other automated runs. Grok sessions are read from ~/.grok/sessions/<url-encoded cwd>/<id>/ (summary.json for id, folder, and title; prompt_history.jsonl for the typed requests). A Grok session counts as running while ~/.grok/active_sessions.json names it with a live process id. Headless grok -p runs are hidden like other scripted runs. Devin CLI sessions are read from sessions.db under $DEVIN_HOME, else the platform data dir (~/Library/Application Support/devin/cli on macOS, ~/.local/share/devin/cli on Linux): the sessions table gives id, folder, title, and activity; message_nodes gives the user asks when the CLI build has it, otherwise transcripts/<id>.json carries the listing. Hidden sessions are skipped. Devin has session-binding hooks but no inbox-injection hooks. Idle sessions use headless devin --resume <id>; open sessions require explicit MCP inbox polling.
T3 Code is a desktop GUI that runs Codex, Claude Code, and Grok underneath. Everett marks the
matching session with source t3code ([t3code] in ls) and uses the thread title when needed.
Active projections with a real provider ID also supply sessions when the local provider
transcript is absent. Current v2 and legacy stores are supported; see the
T3 discovery and polling guide.
T3 sends require explicit --mode inbox (MCP mode: "inbox"). Automatic sends fail without queueing.
Hooks can inject a queued message only if T3's provider runtime
actually loads and runs them; queuing alone does not prove pickup. Otherwise the receiving
thread must have EVERETT_SESSION_ID=<underlying-provider-session-id> in that thread's MCP
launch environment, then calls everett_inbox() and answers with
everett_send(reply_to="<message-id>", text="…"). A model-supplied session_id cannot create
that binding.
Verify the Everett tools are available inside that T3 thread, and use everett_core for shared
memory. CLI resume is refused because it would fork T3's own resume point.
Sessions that Everett spawns are recorded in ~/.everett/spawned.jsonl, so they show in ls even though they ran headless.
Safety rails for agents that call send:
Hop guard. Each delivery sets
EVERETT_HOPSin the harness environment. Asendfrom inside a session that is already 3 hops deep is refused (exit 7), which stops ping-pong loops between agents.No self-send. When the caller's session id is known (
EVERETT_SESSION_ID, or the harness's own session variable), Everett refuses to send to that session.Spawning is explicit.
NEWstarts a session only with--spawn.
Exit codes: 2 bad input, 3 no Jev key with --router jev, 4 session stayed busy or automatic delivery has no safe ping/wake path, 5 harness did not start or timed out, 6 harness failed, 7 hop limit reached.
Wake a Grok Bot
Everett queues a registered Grok Bot inbox. It does not resume the bot. Explicit
--mode inbox writes the text. A matching receiver-webhook.json rule then POSTs
a nudge that omits the inbox text. HTTP 200 means the routine accepted a run.
wake stays false. Copy-paste commands, the policy file, and cross-device relay
are in Grok Bot webhook wake.
The same file can name openai-dot.
On the computer that holds the inbox:
Sign in and register the inbox with
everett external add --id ext-grok-acceptance --harness grok-bot --title 'Grok Bot inbox'.Create a Grok Bot webhook routine and store its URL and Sender key in separate private files with mode
0600.Run
everett relay webhook ext-grok-acceptance --harness grok-bot --url-file /absolute/webhook.url --bearer-file /absolute/webhook.key. Everett derives the owner and binds the rule to this device's inbox.Bind the routine's MCP to that inbox through a reachable Remote HTTPS
everett gateway. Tell it to calleverett_inbox, theneverett_sendwithreply_to.Send
everett send 'check inbox' --to ext-grok-acceptance --mode inbox --json. Expect"wake":falseand webhook"state":"accepted"with HTTP 200, then verify the routine callseverett_inbox.
Cloudflare native relay
With [auth] provider = "cloudflare", native account approval and encrypted relay use
the same separately approved device identity. Register both computers and run
everett relay on both. Devices on the same owner account trust active signed bundles
automatically. Use everett relay devices --names, then send to a unique name such as
--to 'Max NUC/codex/SESSION_ID'. No fingerprint exchange or peer add-relay is required
for same-owner Cloudflare messaging.
Those remote sends now require explicit --mode inbox; there is no synchronous remote
ping receipt. The listener uses an outbound hibernating WebSocket for fixed notifications, then reads
the encrypted inbox over authenticated HTTPS. Healthy quiet connections make no scheduled billable
inbox requests. The listener stages ciphertext durably, reauthorizes before inbox
publication, and retries temporary failures. Deploy the matching Worker before updating receivers.
An older Worker fails explicitly; EVERETT_RELAY_TRANSPORT=poll enables compatibility polling
with a recurring request cost. See request costs. Receiver-side Claude wake is disabled by
default. An owner can opt in through the provider-local receiver-wake.json policy described
in the native relay guide. A registered Grok Bot or OpenAI dot
on that computer uses receiver-webhook.json in the same directory; see
Wake a Grok Bot. Read, reply and revocation need their
own verification.
The actual native CLI passed local production-Worker acceptance and a physical Mac/NUC
send/read/reply/reconnect/revoke journey, with synthetic GitHub and private SSH forwarding
to the local Worker. The 2.0.0 release notes record successful hosted
first-run GitHub approval. Real public Mac/NUC delivery, idle Claude wake/reply and second-account isolation/revocation passed for 2.1.0.
Choosing sign-in during fresh interactive onboarding opens https://relay.raitox.tech for account approval.
Identity keys remain https://everett.raitox.tech.
That service supports public enrollment; messaging stays within each account. Existing account configuration
is preserved. Cloudflare's device protocol is custom, not RFC8628.
Cross-owner grants are unavailable on Cloudflare. SSH pairing uses an explicit address; cloud-agent OAuth is separate.
Local harnesses that launch Everett with the same HOME and EVERETT_HOME use that
home's account configuration and device credential. They do not each need a separate
GitHub sign-in. everett doctor reports the selected provider's stored account without
verifying it online. With Cloudflare selected, everett whoami --json checks the account
with the provider.
Human-readable relay device names
On the hosted Cloudflare provider, everett relay devices --names prints enrollment
labels beside device IDs and verified fingerprints. everett relay devices and
everett relay devices --json keep the signed JSON bundle array.
Labels come from the hosted account metadata already written during browser
approval. They are not covered by the relay bundle signature and do not
establish ownership. Duplicate names remain separate rows with separate IDs;
same-owner Cloudflare sends resolve a unique name to an active device ID and verify
its signed bundle. Duplicate or incomplete name directories fail closed. Use
id:DEVICE_ID/HARNESS/SESSION to select an exact device without name metadata.
Revocation and explicit pairing continue to use IDs. Different owners still require
explicit bilateral grants and fingerprint confirmation. No label lookup writes a pin.
everett relay rename 'Office NUC' updates this device's hosted label. Device
IDs, peer aliases, keys, pins, and signed bundles stay as they are. When the
backend has no label metadata, --names prints (unnamed) and says names are
unavailable.
Cross-device peers (SSH or Cloudflare)
Cloudflare is the only hosted relay. Sign in on each device, run everett relay,
then send to an exact authenticated target. Same-account device bundles are pinned
on first use and key changes fail closed. Messages use X25519 + HKDF-SHA256 +
ChaCha20Poly1305 encryption and Ed25519 signatures; opted-in session cards are
available through everett relay authors. See Cloudflare setup
and the metadata and crypto limits.
For SSH, pair once using the receiving machine's host/device fingerprints and absolute Everett path. Existing noninteractive SSH login access is required for setup. The dedicated peer key can only run Everett RPC: no shell, PTY, or forwarding. Host-key changes fail closed.
everett ls --peer linux-box --json
everett send --to linux-box/claude/<full-session-id> --idempotency-key task-42 --json 'Check the failing test'
everett peer status linux-box <returned-message-id>SSH delivery is inbox-only; it never resumes/spawns a harness or silently queues on your
device. The receiving agent replies normally, but Everett retains that reply on the receiver
until the sender polls peer status. No reverse SSH pairing is needed for replies.
queued means inbox write, delivered means inbox pickup (.done), and replied means a
correlated reply exists. A timeout can leave remote delivery uncertain: retry the same explicit
idempotency key. Requests have a 64 KiB cap, 20-second deadline, and three-hop end-to-end limit.
SSH needs no registry, account sign-in, hosted relay, or Everett listener. See cross-device setup, protocol, revocation, and real-machine checks.
Live delivery
Default sends use ping: an immediate headless run for an idle local session or a
verified same-session native Claude background nudge. Unsupported immediate transports
fail explicitly rather than silently queueing. A native nudge uses a durable inbox item;
if attachment fails afterward, the error identifies that retained item. Dispatch is not
inbox consumption or task completion.
See agent support and wake and the
delivery policy and explicit queue exceptions.
Which path.
send --mode pingis the default in CLI and MCP. Native Claude dispatch requires a full UUID, supported version, and verified background state. Attached OMP 18.12.2 sessions accept localping/autothrough the running Everett extension when a fresh per-session capability proves support. The receipt reportstransport: "omp-extension"andextension_pending; pickup and reply remain unconfirmed. T3, external agents, attached sessions without a supported wake transport, and remote transports require explicit legacy--mode inbox.autoandresumeare compatibility options, not defaults. Remote provenance never permits a local provider wake or resume. See the OMP behavior and trust boundary.Explicit Claude wake.
send --to <full-session-UUID> --wakeis a separate local CLI opt-in. Everett verifies the Claude version and exact background-session state, queues the original request, then attaches to that same session in a PTY with a fixed nudge to read and answer the queued inbox item. It reports the native prompt receipt separately from a real Everett reply.--wakerejects prefixes, routed destinations, remote sessions, T3 Code, relay-derived callers, and non-Claude sessions. The request remains recorded if the attach or reply wait fails, but Claude may already have read it. A timeout does not mean the request is still pending. MCP, gateway, and ordinaryautosends cannot request wake.Inbox.
~/.everett/inbox/<session-id>.jsonl, one message per line:id,from(the sender's session id, orhumanfrom a terminal),from_harness,from_card,text,ts,reply_to,hops,kind(message,reply, orevent). Delivered ids go to<session-id>.done. Undelivered messages expire after 7 days.Injection. The hook adds at most 5 messages (2,000 characters each, 6,000 in total) as context, marked as coming from Everett with the sender's session and card, and marks exactly those delivered. The rest arrive at the next hook. The hook reads local files only, takes about 40 ms, and prints nothing on any error.
Replies. The receiving agent answers with
everett_send(reply_to="<id>", text=…)oreverett reply <id> "<text>". The reply lands in the sender's inbox and is injected there the same way. A sender can instead block on it:everett send --wait 120 …oreverett_send(wait=120).everett inbox/everett_inboxread an inbox directly.Safety. A thread can go back and forth at most 3 hops (exit 7), the calling session is never a target, and headless
everett sendruns (EVERETT_SEND=1) never consume inbox messages.
Harness | Next turn | Mid-task | How |
Claude Code |
|
|
|
Codex (0.155+) |
|
| the same contract (checked against the hook schemas embedded in the 0.155.1 binary) |
Grok CLI | no |
| Grok discards an allowing |
OMP |
|
| the Everett extension; idle nudges use fixed ID-only text and |
Pi, Hermes, Devin | MCP polling | MCP polling | messages wait in the inbox; the agent reads them with |
Grok also runs the hooks in ~/.claude/settings.json. Everett's Claude delivery hook recognizes Grok's camelCase input and leaves a Grok session's messages alone on UserPromptSubmit, so nothing is marked delivered that Grok would drop.
Claude Code has its own cross-session messages (<cross-session-message> over sockets in /tmp/cc-socks/). Everett does not use that private sender protocol. Native Claude ping uses a verified same-session PTY attachment and a fixed inbox nudge instead.
Events
Everett knows what each session is doing, not just what it was about.
Kinds.
done,blocked,needs-input,info. An agent reports one witheverett_event(kind, message), or anyone witheverett event blocked "waiting on staging key". Events are appended to~/.everett/events.jsonland set the session's state in~/.everett/state/<session-id>.json, withsince(when that state began). Messages are capped at 300 characters and secret-filtered.Automatic. The Stop hooks (Claude Code, Codex, Grok) read the turn's last assistant message (from the hook input, else the transcript) and classify it deterministically, with no LLM:
blocked: a closing line states "blocked", "stuck", "waiting on" / "waiting for", "can't proceed" / "cannot continue", or "unable to proceed". Negated ("not blocked", "no longer blocked", "unblocked") and questioned ("is it blocked?") mentions do not count.needs-input: a closing line ends with a question mark, or asks the user to act ("need you to", "please confirm", "should I", "do you want", "would you like", "let me know if" …).done: anything else, a clean finish. Only the last four prose lines count; code blocks, quotes, and tables are ignored. An automatic event that repeats the session's current state within 10 minutes, or with the same text, is dropped, so a chatty session does not spam.
Seeing them.
everett lsprefixes sessions that are blocked or need input (⚠ blocked 32h: waiting on staging key · <card>).everett_lsreturnsstateandstate_kindfor every session.everett events --since 24hlists them.Subscriptions.
everett subscribe <session|project>(oreverett_subscribe) puts another session's or a whole project's events into your inbox, so they are injected at your next turn. Stored in~/.everett/subscriptions.json. A session never receives its own events.The human.
blockedandneeds-inputalso go to you. By default that is a macOS notification (osascript). Setnotify_commandto run your own command as well, for example one that pushes a message to your phone. It runs undersh -cwith the one-line summary as$1andEVERETT_EVENT_KIND,EVERETT_EVENT_TEXT,EVERETT_EVENT_SESSION,EVERETT_EVENT_PROJECT,EVERETT_EVENT_REASON, andEVERETT_EVENT_JSONin its environment. Notifiers run detached, so hooks never wait on them.Escalation. A session still
blockedorneeds-inputafterescalate_minutes(default 30) triggers one more notification ("blocked for 45 min: …"). The check runs at most once a minute from any session's hooks, and on demand witheverett events --check(for example from cron).
Routing
Everett has two routers with the same output:
local (default without a key): BM25 lexical scoring of the request against each session's card, title, first and last request, and project folder name, weighted by recency. It needs no network. A clear lead gives
SESSION, a tie givesASK, and no overlap givesNEW.jev (default when a key is set): the Jev System One model makes a typed choice among the sessions. A confidence below 0.6 gives
ASK.
The Jev key is read from, in order: TYPESAFE_API_KEY, typesafe_api_key in ~/.everett/config.toml, then TYPESAFE_API_KEY in ~/.hermes/.env. Force a router with --router local|jev, or set router = "local" in the config.
Session cards
A card is a note of 50 words or fewer, kept at ~/.everett/cards/<session-id>.md, that says what a session is about, its state, and the next step. Routing and ls prefer a card over the raw transcript text. A card is ignored if it is more than 24 hours older than the session's last activity.
Agent cards: the SessionStart hook tells each new session where its card lives and asks the agent to write it in its first working reply.
Automatic cards: when the agent has not written one, the Stop hook writes a deterministic fallback from the transcript (no LLM, no network). Automatic cards start with
<!-- everett:auto -->, and hooks never overwrite an agent-written card.
Hooks stay silent for everett send resumes (EVERETT_SEND=1) and for scripted Claude runs.
Installing the hooks
everett install-hooks # print the snippets for all harnesses
everett install-hooks --apply # back up, then merge into the real config filesClaude Code: adds
SessionStart,Stop,UserPromptSubmit, andPostToolUseentries to~/.claude/settings.json. The last two deliver live messages;Stopalso records events.Codex (0.155+): adds the same four entries to
~/.codex/hooks.json. Codex needshooks = truein~/.codex/config.tomland asks you to trust new hooks the first time they run.Grok CLI: writes
~/.grok/hooks/everett.jsonwith aStophook for automatic cards and events, and aPostToolUsehook for live delivery. Grok ignoresSessionStartoutput, so Grok sessions get no card instruction or shared core at start. Grok also runs the hooks in~/.claude/settings.json; Everett's Claude hooks do nothing there: they needsession_idandtranscript_path, and Grok's documented hook input uses camelCasesessionIdwith no transcript path.--grokis included by default when~/.grokexists.OMP: writes
~/.omp/agent/extensions/everett.ts, which re-exports Everett's extension. OMP loads that folder at startup. You can also pass it per launch:omp --hook=<path printed by install-hooks>.
--apply writes a backup (<file>.everett-bak-<timestamp>) before any change. It never removes other hooks and never adds a second Everett entry. The hooks run everett hook <name> through the binary you ran it from. Hooks registered by the retired Python package are replaced in place.
Shared core: one mind, many sessions
Parallel sessions each build their own context and drift apart. The shared core is the part they all have in common. Their context and actions differ, but the core is the same.
Push. Any session (or you) runs
everett learn "Atlas deploys from main; staging is auto". The fact is checked by a secret filter (key and token patterns plus an entropy check), capped at 500 characters, and appended to~/.everett/core/inbox.jsonlwith the time, session id, harness, folder, and project.Merge (slow path).
everett trunk mergedistills the inbox into~/.everett/core/core.md(global) and~/.everett/core/projects/<project>.md, at most 300 words each. With--llm claudeor--llm codex, a headless harness run is prompted to deduplicate and resolve contradictions; invalid or secret-bearing output changes nothing.--llm noneappends and removes normalized duplicates with no LLM. Previous core files and the processed inbox are archived under~/.everett/core/history/<time>/. Facts learned during a merge stay pending for the next one; a second simultaneous merge is refused. A configured vault gets a generatedCore.mdmirror.Pull. The SessionStart hooks (Claude Code, Codex, OMP) add the global core plus the current project's core (at most 350 words in total) to each new session's context, with one line telling the agent to run
everett learnwhen it finds something other sessions should know. The hooks read local files only, take about 40 ms, and stay silent on any error.
During an active session, call everett_core again to pull the latest merged facts. Every call reads the local files. Pending learnings still need a merge.
For facts beyond the compact core, call everett_core(action="search", query="compiler cache", project="atlas"). Local BM25 search ranks original learnings in ~/.everett/core/facts.sqlite3. The store keeps accepted facts beyond the 300-word injection cap, with a durable ID, timestamp, scope, project, and source session/harness/folder. Search defaults to global plus current/named project. Use scope="global" or scope="project" to narrow it. Queries accept up to 500 characters and use at most 32 literal words. Results default to five, with limit from 1 to 20. Search does not execute FTS operators supplied in the query.
The searchable store starts with new learnings accepted by this version. It never imports history backups. Existing core files remain readable through the default action. New learnings become searchable immediately, while compact-core injection still needs a merge. Relearning the same normalized fact in the same scope keeps its ID and updates its source metadata.
For temporary memory, call everett_learn(fact="Preview uses port 4200", ttl_seconds=3600). The lifetime is a whole number of seconds from 1 to 31536000 (365 days). Its receipt returns stored=true, pending=false, and an absolute expires_at in Unix seconds. Temporary facts are searchable before expiry and never enter the pending inbox, distillation, or injected core. After expiry, search excludes them; their stored rows remain until forgotten. This does not erase history backups or independently written paraphrases.
Relearning a temporary fact with a TTL refreshes its expiry and keeps its ID. Learning it without a TTL explicitly makes it permanent and queues it for merging. An existing permanent exact fact in the same scope must be forgotten before a temporary copy can be learned. Corrections preserve temporary expiry, including an elapsed deadline, and stay out of the compact core. A correction that would change an existing replacement fact's lifetime is rejected before memory changes.
Local MCP sessions can update memory immediately with everett_core(action="forget", fact="Atlas deploys on Fridays") or everett_core(action="correct", fact="Atlas deploys on Fridays", replacement="Atlas deploys on Mondays"). Copy the whole fact without its bullet marker, including existing merged bullets longer than 500 characters. Matching ignores case, punctuation, and repeated whitespace. Both actions remove matching active bullets and pending learnings so a later merge cannot restore those pending copies. Replacement facts use the same 500-character limit and secret filter as everett_learn, and stay within the 300-word core cap. changed=false means no match was found.
Changes default to global scope. Pass project="atlas" for project scope, or scope="project" for the current project. Forget/correct also update exact matches in the searchable store, including facts dropped from the compact core. They do not match semantic paraphrases. A running merge makes either action fail with a retry message. File and search-store writes are separate: a storage error can leave a partial change; retry the same action after resolving the error to finish it. Generated vault mirrors update after a successful change. History backups stay intact and are never merge inputs. Gateway connections remain read-only for compact shared core and reject local search or mutation arguments.
The project is the enclosing git repository's folder name, else the folder name. Your home folder is not a project. Default merge engine: merge_llm in the config, else claude.
For storage boundaries, mid-session reads, and the relationship to Power Proxy and Basic Memory, see Shared memory and other memory tools.
Nightly auto-merge
everett trunk schedule previews a native nightly schedule. Apply it explicitly to run the shared-core merge each day (default 04:00 in the host's local time, --llm claude):
everett trunk schedule # print the files and activation commands; change nothing
everett trunk schedule --apply # write and activate this user's schedule
everett trunk schedule --at 02:30 --llm codex --apply
everett trunk schedule --remove --apply # disable and remove only Everett's schedulePlatform | Files and activation | Inspect runs |
macOS |
|
|
Linux |
|
|
The job uses the current Everett executable, selected EVERETT_HOME, and absolute entries from PATH. It runs everett trunk merge --llm <x> and skips cleanly when the inbox is empty. --llm none needs no harness CLI. Linux units contain only HOME, EVERETT_HOME, and PATH from the installation environment; they do not copy API keys. A configured harness can still read its own account files or environment supplied by the user manager.
Linux requires systemd and a reachable user manager. If activation fails, Everett exits nonzero with the failed command and leaves the unit files for inspection/retry. The timer uses Persistent=true to catch a missed run when the user manager starts again. Running while logged out depends on the host's existing user-manager/linger configuration; Everett does not change it.
everett doctor checks that the Linux timer is enabled and active; this confirms scheduling, not a completed merge. Check the journal for the actual run result. On macOS it checks the plist and saved executable path. everett onboard offers the same "merge shared memory nightly" toggle, or use --schedule-merge for an unattended opt-in. Preview and removal do not alter the core or its pending facts.
For agents: MCP
Everett is mostly used by agents. everett mcp is a stdio MCP server (JSON-RPC 2.0, protocol versions 2025-06-18, 2025-03-26, and 2024-11-05) written with the standard library only, so every MCP-capable harness gets Everett as native tools:
Jev first. Call everett_send with just text; do not call everett_ls and hand-pick a target session. Without to, Everett routes the request itself (Jev when a key is configured, else the local matcher) before delivering it, and the response reports the decision -- router, chosen session, confidence -- so you can tell the user e.g. "jev picked [claude] ~/src/api". Pass to only when the user named a specific session or you are replying to one; it skips routing. On an ambiguous ASK decision nothing is sent -- the response carries candidates (close sessions) to disambiguate, then send again with to. everett_ls is for a quick overview of what sessions are doing, not for picking a send target.
Tool | Arguments | Returns |
|
| Sessions with their cards (and |
|
|
|
|
| Routes then pings by default. Dispatch is separate from inbox pickup. Unsupported immediate paths fail explicitly; |
|
| Stores a secret-filtered fact. Durable facts queue for shared core; temporary facts stay in local search until expiry. |
|
| Reads the latest core by default. Local |
|
| Writes the calling session's card. |
| none | The caller's session id, harness, hop count, and how they were detected. |
|
| The Everett messages (requests, replies, events) waiting for you; marks them delivered. |
|
| Records done / blocked / needs-input / info for your session. |
|
| Follows a session's or project's events in your inbox. |
|
| Owner-local control. |
|
| Verified identity, registration, directory/pins and scoped revocation controls. |
|
| Device-side encrypted send to an explicit named agent. No sender-requested wake or implicit routing; receiver policies are separate. |
|
| Sender-only status from signed delivery/pickup/reply observations. |
See agent-facing relay MCP, cross-device deployment and relay threat model. Cloudflare binds account/agent identity; cross-owner delivery is unavailable. External inbox text is labeled untrusted. Existing Jev routing, SSH, OMP, and Pi integration is unchanged.
Listing, routing and sending default to a 72-hour window. Pass the same larger hours value
to these MCP tools when continuing an older session. Resume/spawn children have closed stdin;
the MCP connection remains available for the client's protocol messages.
Register it:
everett install-mcp # print the registration for Claude Code, Codex, OMP, and Grok
everett install-mcp --apply # back up, then register (idempotent)Claude Code:
claude mcp add --scope user everett -- <everett> mcp, or--applyaddsmcpServers.everettto~/.claude.json.Codex: an
[mcp_servers.everett]block in~/.codex/config.toml.OMP:
mcpServers.everettin~/.omp/agent/mcp.json. OMP also imports Claude Code's servers.Grok CLI:
grok mcp add everett <everett> -- mcp, or--applyappends an[mcp_servers.everett]block to~/.grok/config.toml. Grok also imports Claude Code's servers by default. Included by default when~/.grokexists.Devin CLI (v3000.3+):
everett install-mcp --devin --applymergesmcpServers.everett(launched aseverett mcp --harness devin) into~/.config/devin/mcp_config.json(Windows:%APPDATA%/devin/mcp_config.json). This is separate from the session store configured byDEVIN_HOME. Existing servers and unrelated environment values are preserved; use--repair --applyto back up and refresh a stale registration.everett install-hooks --devin --applyaddsSessionStart/UserPromptSubmithooks to~/.config/devin/config.jsonthat record which session the Devin process holds, so MCP calls bind to it.
The registration launches the executable you ran it from with ["mcp"]. A launcher left by the
retired Python package (["-m", "everett", "mcp"]) is reported stale and replaced by --apply.
For another MCP client, copy the launcher printed by a dry run. Restart clients after changing their registration.
Caller identity. Claude Code supplies CLAUDE_CODE_SESSION_ID when it starts a stdio MCP server; Grok CLI 1.0.4+ supplies GROK_SESSION_ID; Codex supplies the current thread on every call as _meta.threadId (unreleased; on main after 1.6.0); and everett gateway supplies an immutable EVERETT_SESSION_ID. Pi, OMP, Devin, and Hermes bind through their host process (unreleased): install-mcp launches them as everett mcp --harness <name>, and Everett's Pi extension, OMP extension, and Devin hooks record which session each harness process holds. Pi's extension registers the server per session with EVERETT_SESSION_ID set. Hermes binds only when exactly one interactive Hermes session was created in the server's directory since the process started. When the binding is ambiguous or missing, identity-requiring tools return a readable tool error (isError: true) that says how to fix it; Everett never guesses. T3 Code threads still need EVERETT_SESSION_ID in their MCP launch environment. A model-supplied session_id cannot establish or replace a binding; the argument is deprecated, no longer advertised in tool schemas, and a conflicting value is a tool error. Details per harness: docs/mcp-identity.md.
Safety.
The server refuses self-send. If
everett_whoamicannot identify you, have the owner bind the MCP launch environment before sending. Do not guess another session's identity from its folder or recency.EVERETT_HOPStravels through every delivery, and a request that has already been forwarded 3 times is refused, so two agents cannot ping-pong. A live session also inherits the hop count of messages delivered to it within the last 15 minutes (older deliveries no longer count against it).A new session starts only with
spawn: true.everett_learnruns the secret filter.Calls are logged to
~/.everett/mcp.logwith tool name, argument names, caller id, result status and duration. Argument values and replies are not logged. Existing log entries from older versions are preserved.
Tool failures come back as isError: true with a message written for the agent. Malformed requests get standard JSON-RPC error codes.
Configuration
Everything is optional. ~/.everett/config.toml:
vault = "~/Notes" # enables `everett trunk`
vault_dir = "Everett" # folder inside the vault (default "Everett")
default_harness = "claude" # NEW suggestions: claude | codex | omp | pi | hermes | grok
router = "local" # local | jev
typesafe_api_key = "…" # Jev key ([jev] api_key also works)
merge_llm = "claude" # trunk merge engine: claude | codex | none
notify = "osascript" # blocked/needs-input: osascript | command | both | none
notify_command = "…" # e.g. a push-notification command; gets the summary as $1 (sets notify default to both)
escalate_minutes = 30 # re-notify once when a session stays blocked this long (0 = never)
[auth]
provider = "cloudflare" # EVERETT_AUTH_PROVIDER; only supported provider
issuer = "https://everett.raitox.tech" # EVERETT_AUTH_ISSUER; identity, not the connect URL
base_url = "https://relay.raitox.tech" # EVERETT_AUTH_BASE_URL; optional relay URL
# relay_aliases = "https://everett.raitox.tech,https://relay.raitox.tech" # EVERETT_AUTH_RELAY_ALIASES; default shown
Environment overrides: EVERETT_VAULT, EVERETT_VAULT_DIR, EVERETT_HARNESS, EVERETT_ROUTER, TYPESAFE_API_KEY, EVERETT_NOTIFY, EVERETT_NOTIFY_COMMAND, EVERETT_ESCALATE_MINUTES, EVERETT_AUTH_ISSUER, EVERETT_AUTH_BASE_URL, EVERETT_AUTH_RELAY_ALIASES, and EVERETT_HOME (the root used in place of ~). Existing configs that set only issuer keep using that origin as the connect URL. GitHub sign-in stays on the issuer. Pins treat every origin in relay_aliases as the same relay; an explicit list replaces the public pair above.
Accounts
Sign-in is optional for local/SSH use. everett login uses Cloudflare's native
device approval protocol (not RFC 8628). Approve the named device at the printed
browser link. Credentials live in ~/.everett/cloudflare-auth.json (0600), and
whoami verifies them online. logout removes the local credential;
logout --revoke-device additionally requests server revocation first.
No incoming CLI port or browser callback is needed. Relay keys and pins stay under
~/.everett/relay-cloudflare/; retired state is not migrated or reused.
See account setup and revocation. Sessions and shared core stay local.
Privacy
Session indexing and state are local. Everett reads harness stores and writes its own state under
~/.everett/, plus configured vault notes and explicitly applied harness registrations. Headless
resumes let the harness append its own history. Local routing needs no network; optional Jev
sends routing context to its API. send, --spawn, and LLM merges call your installed harness,
which may contact its provider. trunk merge --llm none is local. Desktop notifications use macOS
osascript; a custom notify_command can send events wherever you configure it.
Transcript adapters generally inspect bounded slices; Grok prompt-history scans and automatic
card backfills may read more. SQLite stores are opened read-only. No harness session data is copied
to a cloud service for plain ls, local routing, or inbox delivery.
Explicit Cloudflare sends share encrypted bodies and visible org/device/grant IDs, public bundles/fingerprints, parent/hop lineage, message/idempotency IDs, timing/size, signatures and observation state. Account identity and connection metadata are also visible to the service; replay/revocation records remain after ciphertext deletion. E2EE is not anonymity, secure backup erasure, endpoint protection or forward secrecy against later recipient static-key compromise. Full inventory and limitations: relay threat model.
Troubleshooting
For delivery diagnosis, compatibility checks, migration, and a correlated reply check, see troubleshoot message delivery.
Symptom | Next step |
| Add the install directory (default |
| A registration still points at the retired Python package. Run |
MCP client shows zero tools | Run |
OMP or Devin has an old | Run |
Hermes points to a missing Everett binary | Run |
Session not found / no live reply | Start a harness session or run |
Codex reports | Delivery is unconfirmed. Check the target session before retrying; for an open session with Everett hooks, use |
Shared fact missing / scheduling unavailable | Run |
Development
The code lives in everett-rs/.
cd everett-rs
cargo build --release # binary at target/release/everett
cargo test # isolated suite: temp HOME, never touches real storestests/release_journey.rs drives the CLI and every MCP tool through routing, messages, replies,
status subscriptions and global/project memory. Point it at a packaged binary with
EVERETT_VERIFY_BINARY=/path/to/everett cargo test --test release_journey.
See the verification skill.
GitHub Actions runs cargo test and the release journey against a release build on macOS and Linux.
Release tags publish prebuilt binaries for macOS (arm64, x86_64) and Linux (static musl,
x86_64, aarch64), each with a .sha256, plus a rendered Homebrew formula (everett.rb).
The gateway uses the official Rust MCP SDK for private stdio and authenticated loopback HTTP. See the owner-bound gateway setup.
License
MIT. See LICENSE.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Durable agent-to-agent handoffs and shared scratchpad for multi-agent workflows.
The team layer for AI coding agents: shared contracts, collision alerts, E2EE sessions.
Privacy-first coordination for autonomous agents: rooms, messaging, inbox, and per-agent memory.
Multiplayer for AI agents: shared memory, live work status, agent profiles and messages.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables multiple Claude Code sessions to communicate, share state, and coordinate tasks through session management, message passing, and task scheduling, supporting a three-role collaboration workflow.2MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI coding agents to send exact, durable handoffs to each other's existing sessions, with one turn per delivery, no duplicates, and no interruption of busy agents.1Apache 2.0
- AlicenseAqualityBmaintenanceEnables AI coding agents to coordinate through a local, pull-only message board by registering sessions, posting updates, proposing and accepting tasks, holding leases, and reading or acknowledging updates under scoped human authorization.8MIT
- AlicenseNot gradedqualityBmaintenanceEnables one AI coding agent to discover, read, message, and wait on other agent sessions across Codex threads and Claude Code or Claude Desktop sessions, while logging every send as a local receipt that can be audited later.1 npmMIT