How to Implement Cross-Agent Handoffs Between Claude Code and Codex in ai-memory

ai-memory enables seamless cross-agent handoffs by providing Model Context Protocol (MCP) tools that let one agent create a structured handoff (memory_handoff_begin) and another agent consume it (memory_handoff_accept), preserving full context across Claude Code and Codex sessions.

The akitaonrails/ai-memory repository implements a server-side handoff mechanism that eliminates context loss when switching between AI agents. By using dedicated MCP tools, you can transfer session state—including file changes, open questions, and next steps—from Claude Code to Codex without manual copy-pasting or context window management.

Understanding the Handoff Architecture

The Two-Phase Protocol

The handoff system operates through a strict two-phase commit pattern. First, the ending agent creates a handoff record in the handoffs table. Second, the starting agent consumes that record. This design ensures that no context is lost even if hours or days pass between sessions.

In crates/ai-memory-mcp/src/server.rs, the implementation exposes two primary tools: memory_handoff_begin (lines 37–46) for creation and memory_handoff_accept (lines 48–57) for consumption. The server handles all persistence logic, meaning agents only need to invoke these tools without managing state directly.

Data Structure and State Management

The core data structure is defined in crates/ai-memory-core/src/handoff.rs. The NewHandoff struct (lines 58–88) captures:

  • summary: A high-level description of completed work
  • open_questions: Pending uncertainties for the next agent
  • next_steps: Recommended actions
  • files_touched: List of modified files
  • cwd: Current working directory for context
  • shared: Optional flag for project-wide visibility

The HandoffState enum (lines 20–28) tracks lifecycle states, ensuring each handoff can only be consumed once. Once accepted, the state transitions from Open to Accepted, preventing duplicate work.

Creating a Handoff from Claude Code

The memory_handoff_begin MCP Tool

When Claude Code finishes a session, it calls the memory_handoff_begin tool. This tool records a NewHandoff row via the writer actor and returns a unique handoff ID. The implementation in crates/ai-memory-mcp/src/server.rs (lines 37–46) validates the request context and persists the payload atomically.

The tool automatically captures the operator identity from the request's actor context, setting the owner_user field unless the shared flag is explicitly enabled.

Structuring Handoff Content

Effective handoffs require structured content. The NewHandoff struct enforces this by separating concerns into distinct fields. Rather than dumping raw conversation history, you provide curated context that the next agent can immediately act upon.


# Claude Code creates a handoff before exiting

ai-memory handoff begin \
    --workspace default \
    --project my-app \
    --summary "Implemented JWT authentication flow; all integration tests passing" \
    --open-questions "Should we implement refresh token rotation?" \
    --next-steps "Add OAuth2 provider support" \
    --files-touched src/auth.rs src/middleware.rs tests/auth_test.rs

This command returns a handoff ID (e.g., a1b2c3...) and stores the context in the ai-memory database, ready for the next agent.

Consuming the Handoff in Codex

Automatic SessionStart Hook

When Codex initializes a new session via ai-memory session start, the built-in SessionStart hook automatically invokes memory_handoff_accept. This tool queries for the most recent open handoff using the latest_open_handoff function in crates/ai-memory-store/src/reader.rs (lines 3996–4004).

If a valid handoff exists, the tool marks it as Accepted and prepends its payload to Codex's initial context window. You see this as a formatted block in the agent's console:


📥 ai-memory: pending handoff from previous session
Summary: Implemented JWT authentication flow; all integration tests passing
Open questions:
• Should we implement refresh token rotation?
Next steps:
• Add OAuth2 provider support
Files touched:
• src/auth.rs
• src/middleware.rs
• tests/auth_test.rs

Manual Acceptance for Scripts

For automation or scripting scenarios, you can manually trigger acceptance using the CLI:


# Fetch handoff manually in Codex or scripts

ai-memory handoff accept \
    --workspace default \
    --project my-app

# Returns JSON payload with full context

Controlling Handoff Visibility with Ownership

User-Scoped vs Shared Handoffs

By default, handoffs are private to the creator. The owner_user field in the NewHandoff struct binds the record to the authenticated operator (extracted from OIDC or bearer tokens). This prevents accidental context leakage in multi-user environments.

To enable team handoffs, set the shared flag to true during creation. This sets owner_user = None in the database, making the handoff visible to any operator with project access. This is ideal for shift handovers or collaborative debugging sessions.

Identity Filtering in Action

The acceptance logic in crates/ai-memory-mcp/src/server.rs builds an owner_filter from the caller's identity. If the handoff has an owner, only that specific operator can claim it. If shared, the first caller wins. This security model is tested in crates/ai-memory-mcp/tests/handoff_admission.rs, which validates proxy-operator isolation and ownership enforcement.

Complete Cross-Agent Workflow Example

The following workflow demonstrates a complete handoff from Claude Code to Codex, including ownership considerations:

Step 1: Claude Code finalizes work


# Claude Code session ending

ai-memory handoff begin \
    --workspace production \
    --project api-service \
    --summary "Refactored database connection pooling; resolved timeout issues" \
    --open-questions "Consider adjusting pool size for high-traffic periods?" \
    --next-steps "Implement circuit breaker pattern" \
    --files-touched src/db/pool.rs src/db/connection.rs \
    --shared true  # Make available to team

Step 2: Codex starts fresh


# Later, Codex picks up the context

ai-memory session start \
    --workspace production \
    --project api-service \
    --agent codex

# Codex automatically receives the formatted handoff context

Step 3: Verification

If you need to verify the handoff was consumed (preventing duplicate processing):


# Check for remaining open handoffs

ai-memory handoff accept \
    --workspace production \
    --project api-service

# Returns: {"handoff": null} if already consumed

Summary

  • Server-side persistence: ai-memory stores handoffs in a database, not agent memory, enabling durable cross-agent context transfer.
  • Two-tool API: Use memory_handoff_begin (lines 37–46 in server.rs) to create handoffs and memory_handoff_accept (lines 48–57) to consume them.
  • Single-use guarantee: The HandoffState machine ensures each handoff is consumed exactly once, preventing duplicate work.
  • Ownership controls: Handoffs default to private (owner_user set) but support project-wide sharing via the shared flag.
  • Structured context: The NewHandoff struct enforces clean separation of summaries, questions, next steps, and file references for efficient context windows.

Frequently Asked Questions

How does ai-memory prevent the same handoff from being consumed by multiple agents?

The handoff system uses a state machine defined in crates/ai-memory-core/src/handoff.rs (lines 20–28) with two states: Open and Accepted. When memory_handoff_accept successfully processes a handoff, it atomically updates the database row to Accepted status. Subsequent queries for open handoffs filter out accepted records, ensuring only the first caller receives the context.

Can I transfer a handoff between different users or machines?

Yes, but only if the handoff is created with the shared: true flag. By default, handoffs include an owner_user field derived from the creator's authentication context (OIDC or bearer token). Private handoffs can only be accepted by the same identity. Setting shared to true sets owner_user = None, making the handoff claimable by any authenticated user with project access.

What happens if Codex starts without an existing handoff?

If no open handoff exists for the project (or if all handoffs are already accepted), the memory_handoff_accept tool returns handoff: null. Codex then starts with a fresh context window. This behavior is handled gracefully in the SessionStart hook, allowing agents to function normally even without pending handoffs.

Which source files should I examine to understand the handoff implementation?

Key implementation files include:

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →