Skip to main content

Baton 🏃‍♂️→🏃

Cross-agent memory handoff via MCP. Claude Code, Codex, and Antigravity hand off project context to each other, so a fresh agent starts warm instead of burning quota re-exploring the codebase.

The problem

You hit Claude Code's usage limit mid-task. You open Codex to continue — and watch it re-list directories, re-read files, and re-derive decisions you already made. That re-exploration costs 5–10% of the new agent's quota before any real work happens. Multiply by every handoff, every teammate, every morning you re-open a project.

How it works

┌─────────────┐   ┌──────────┐   ┌─────────────┐
│ Claude Code │   │  Codex   │   │ Antigravity │
│ (hooks +    │   │ (hooks + │   │ (rules +    │
│  CLAUDE.md) │   │AGENTS.md)│   │  MCP config)│
└──────┬──────┘   └────┬─────┘   └──────┬──────┘
       │    MCP (stdio, pull-based)     │
       └───────────────┼────────────────┘
                ┌──────┴──────┐
                │ Baton MCP   │  FastMCP, Python
                │ server      │  4 tools, no LLM calls
                └──────┬──────┘
                ┌──────┴──────────────┐
                │ .agent-memory/      │  ← lives IN the repo,
                │   digest.md         │    committed to git
                │   events.jsonl      │
                └─────────────────────┘

Three principles:

  1. The server is dumb. No LLM calls, no API keys, no embeddings. The agent already has the session in context — it writes the digest and passes it as a tool argument. The server stores strings.
  2. Automation lives client-side. MCP is pull-based; hooks and standing instructions make agents actually use the tools (see Reliability below).
  3. Memory travels with the repo. .agent-memory/ is committed to git. Clone the repo, get the memory — teammates and CI included. No cloud, no accounts, no sync.

Quickstart

Baton is on PyPI as baton-mcp; all you need is uv:

# in any project you work on:
cd ~/my-project
uvx --from baton-mcp baton init
Running from a source checkout instead
git clone <this repo> && cd baton && uv sync

cd ~/my-project
uv run --project /path/to/baton baton init

baton init detects how it was launched and writes matching configs: the uvx install emits uvx --from baton-mcp baton-server entries, the source checkout emits uv run --project /path/to/baton baton-server entries.

baton init is idempotent and does everything for Claude Code: creates .agent-memory/, registers the MCP server (.mcp.json), installs hooks and pre-allowed permissions (.claude/settings.json), and appends workflow instructions to CLAUDE.md/AGENTS.md. It prints the config blocks for Codex (~/.codex/config.toml) and Antigravity (~/.gemini/antigravity/mcp_config.json) rather than silently editing global files.

Watch memory move between agents live:

uvx --from baton-mcp baton watch

The four tools

Tool What it does
memory_load Returns the trusted digest + recent events. Called at session start, before exploring.
memory_checkpoint(digest) Overwrites the digest (≤2000 tokens, enforced). Called after each task.
memory_log(type, text) Appends one event: decision, blocker, or todo.
memory_handoff(to_agent, note) Writes a handoff block into the digest and logs the event.

Agent identity comes from BATON_AGENT in each client's MCP config — no per-call parameters.

Reliability: making agents actually use it

Instructions alone don't guarantee tool calls. Baton makes both directions deterministic in Claude Code:

  • Loading — a SessionStart hook injects the digest into context before the first prompt. Zero tool calls, can't be skipped.
  • Saving — a PostToolUse hook marks .agent-memory/.dirty on any file edit; memory_checkpoint clears it; a Stop hook blocks the agent from finishing while the flag exists, telling it to checkpoint first (with a loop guard via stop_hook_active). Q&A turns pass through untouched.
  • Permissions — baton init pre-allows mcp__baton__* and pre-approves the project server, so there are zero prompts.

Codex gets the same SessionStart digest injection via ~/.codex/hooks.json (same schema), plus default_tools_approval_mode = "approve" so tool calls run unprompted. Antigravity relies on the AGENTS.md instructions.

Storage

digest.md — one overwritten markdown file, hard-capped at ~2000 tokens: current task, handoff note, architecture summary, annotated file map, decisions & constraints, tried-and-failed (saves the next agent from repeating dead ends), next steps. Its header tells the reading agent to trust it rather than re-verify — that's where the token savings come from.

events.jsonl — append-only log: checkpoint | decision | blocker | todo | handoff | load. Loading appends a load event, so the viewer shows a handoff being received.

Cold start vs. warm start

Measured on a real repo (Codex 0.142 / gpt-5.5, identical prompt: "You are taking over this project from another agent. State the current task and the concrete next steps."):

Cold (no Baton) Warm (Baton)
Exploration commands 12 file reads/listings 0 (one memory_load call)
Total tokens 128,830 54,270 (−58%)
Orientation cost¹ ~77k tokens ~2k tokens

¹ Tokens beyond Codex's fixed per-session system overhead (~52k), i.e. what getting oriented actually cost.

The key ingredient: memory_load prepends a server-side trust preamble ("do NOT re-explore what this states"). Without it, agents load the digest and then re-explore anyway — we measured that too (210k tokens).

Honest claim: the digest reduces exploration, it doesn't eliminate it. An agent will still verify what it's about to change — it just stops re-deriving what's already known.

Limitations

  • Deterministic save enforcement (Stop hook) is Claude Code-only today; Codex and Antigravity rely on instructions plus explicit prompts.
  • Pre-allowed permissions take effect after the repo is trusted once.
  • events.jsonl can merge-conflict across git branches (append-only helps; see roadmap).

Roadmap (deliberately not built)

  • Vector search / semantic retrieval — the digest fits in one read today
  • Server-side summarization — would add API keys; the agent summarizes
  • Cloud sync / multi-machine — git already does this
  • Web dashboard — baton watch does this without ports
  • Merge-friendly event log (per-branch segments)
  • Multi-project global memory

Metadata

Release files for baton-mcp 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for baton-mcp 0.1.0
File Size Uploaded
baton_mcp-0.1.0.tar.gz 17.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for baton-mcp 0.1.0
File Interpreter ABI Platform
baton_mcp-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 35.6 kB

Release files / baton_mcp-0.1.0.tar.gz

Download URL baton_mcp-0.1.0.tar.gz
Size 17.8 kB
Tags Source
SHA-256 checksum
How to use checksums
27a1a18a83881f230227f37f5ea317eb04579074a2e98e80d2eb8127e9ed2be2
BLAKE2b-256 checksum
How to use checksums
9173927926d4d1a60b4b9575206815dce1f2bfba2343a021dffff3ef31aded0c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 16, 2026.

Transparency log

Release files / baton_mcp-0.1.0-py3-none-any.whl

Download URL baton_mcp-0.1.0-py3-none-any.whl
Size 17.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
afea9e0837c4b70ead7c78682c4a6059c744e039f63cec3eee71aa995170300c
BLAKE2b-256 checksum
How to use checksums
b26f4c68940c24253647d4bdefb897ef377ffd13a443341dfb440fff800c6ca8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 16, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page