Metadata-Version: 2.4
Name: baton-mcp
Version: 0.1.0
Summary: Cross-agent memory handoff via MCP — agents pass the baton instead of re-exploring the repo
Project-URL: Homepage, https://github.com/p-aveen06/baton
Project-URL: Repository, https://github.com/p-aveen06/baton
Project-URL: Issues, https://github.com/p-aveen06/baton/issues
Author-email: Paveen <paveenpradeep2@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: agent-memory,agents,claude-code,codex,handoff,mcp,model-context-protocol
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development
Requires-Python: >=3.10
Requires-Dist: mcp>=1.2.0
Requires-Dist: rich>=13.0
Description-Content-Type: text/markdown

# 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`](https://pypi.org/project/baton-mcp/); all
you need is [uv](https://docs.astral.sh/uv/):

```bash
# in any project you work on:
cd ~/my-project
uvx --from baton-mcp baton init
```

<details>
<summary>Running from a source checkout instead</summary>

```bash
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.
</details>

`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:

```bash
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
