# How ai-memory's Cross-Agent Handoff Mechanism Works Between AI Coding Agents

> Discover how ai-memory's cross-agent handoff seamlessly transfers context between AI coding agents using MCP tools and session snapshots for efficient collaboration.

- Repository: [Fabio Akita/ai-memory](https://github.com/akitaonrails/ai-memory)
- Tags: deep-dive
- Published: 2026-08-20

---

**ai-memory enables seamless context transfer between AI coding agents through a server-side handoff system that uses MCP tools to create single-use snapshots containing session state, open questions, and next steps, which are automatically injected into the next agent's context via SessionStart hooks.**

The `akitaonrails/ai-memory` project provides a robust infrastructure for maintaining continuity across AI-assisted coding sessions. Its **cross-agent handoff mechanism** allows one agent—such as Claude Code—to pass a structured snapshot of its work to another agent like Codex or OpenCode. This system ensures that context, open questions, and next steps survive agent transitions without manual copy-pasting.

## The Handoff Lifecycle

The handoff implementation in [`crates/ai-memory-mcp/src/server.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-mcp/src/server.rs) follows a strict server-side lifecycle designed to preserve context integrity while enforcing security boundaries.

### Initiating a Handoff with memory_handoff_begin

An agent creates a handoff by invoking the MCP tool `memory_handoff_begin`. According to the source code, this tool gathers the current session's **open questions**, **next steps**, and **touched files** using the helper `cap_handoff_list`. 

The system then writes a `NewHandoff` record to the SQLite store via the writer actor. By default, the handoff belongs to the creating operator; however, setting `shared: true` makes it visible to any subsequent agent in the same project. The call returns a `handoff_id`, and the server prepends a marker like `📥 ai-memory: pending handoff` to the session's context.

### Automatic Consumption via SessionStart Hooks

When the next agent initializes, its `SessionStart` hook automatically executes. This hook, implemented in [`crates/ai-memory-hooks/src/router.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-hooks/src/router.rs), scans the incoming context for the pending-handoff marker. Upon detection, it **fetches the stored handoff** and **injects its content** as a synthetic observation (`hook_result`).

The handoff operates under single-use semantics. As documented in the `memory_handoff_fetch` tool implementation (lines 3422-3436 of [`server.rs`](https://github.com/akitaonrails/ai-memory/blob/main/server.rs)), the handoff is **deleted immediately after retrieval**, ensuring that session state does not persist indefinitely or leak to unintended consumers.

### Explicit Control with Accept and Cancel Operations

Agents retain explicit control over pending handoffs through two dedicated MCP tools. The `memory_handoff_accept` tool allows an agent to formally take ownership of a handoff, while `memory_handoff_cancel` discards it entirely. Both tools reference the `handoff_id` returned by the initial begin call and enforce strict ownership checks—the `hand_off.owner` field must match the caller unless the handoff is marked as shared.

### Security Boundaries and Visibility Rules

The visibility system implements tiered access controls. Handoffs without an owner are **public** and can be listed by any agent, as verified by the `api_handoff_listing_serves_body_when_auth_is_off` test. Conversely, owned handoffs restrict access to the owner or root users (`api_handoff_listing_serves_body_to_named_caller`).

The API endpoints under `/workspaces/{workspace}/projects/{project}/handoffs`, defined in [`crates/ai-memory-web/src/routes/api.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-web/src/routes/api.rs), expose metadata such as summaries and next steps but **never expose the raw body** to unauthorized callers. Additionally, [`crates/ai-memory-wiki/src/admission.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-wiki/src/admission.rs) marks hand-off operations as distinct lifecycle events, ensuring they bypass standard wiki write constraints.

## Cross-Workspace Agent Coordination

The mechanism supports sophisticated multi-workspace workflows through explicit `workspace` and `project` arguments in the handoff tools. This design allows a handoff created in one directory or workspace to target a different workspace entirely, enabling agents operating in isolated environments to transfer context seamlessly. The SQLite-backed writer actor guarantees atomicity during these cross-boundary transactions.

## Implementation Architecture

The handoff system relies on several coordinated components:

- **[`crates/ai-memory-mcp/src/server.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-mcp/src/server.rs)** – Implements the core MCP tools including `memory_handoff_begin`, `memory_handoff_fetch`, `memory_handoff_accept`, and `memory_handoff_cancel`.

- **`crates/ai-memory-store/src/`** – Manages the SQLite persistence layer and writer actor responsible for atomic handoff storage and deletion.

- **[`crates/ai-memory-hooks/src/router.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-hooks/src/router.rs)** – Handles the `SessionStart` hook that detects pending handoff markers and manages synthetic observation injection.

- **[`crates/ai-memory-web/src/routes/api.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-web/src/routes/api.rs)** – Exposes HTTP endpoints for listing, creating, and retrieving handoff metadata while enforcing authorization boundaries.

- **[`crates/ai-memory-wiki/src/admission.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-wiki/src/admission.rs)** – Ensures handoff operations are processed as distinct admission events separate from standard wiki edits.

## Practical Implementation Examples

The following patterns demonstrate how agents interact with the handoff system in practice:

```rust
// Agent A: Create a handoff at the end of a session
let resp = client
    .memory_handoff_begin(
        workspace = "default",
        project = "scratch",
        summary = "Refactor user-profile module".into(),
        open_questions = vec!["How to handle edge cases?".into()],
        next_steps = vec!["Write tests".into()],
        shared = false,
    )
    .await?;

// Store the returned ID for reference
let handoff_id = resp["handoff_id"].as_str().unwrap();

```

```rust
// Agent B: The SessionStart hook automatically injects the handoff.
// Manual fetch (e.g., after a restart) retrieves and deletes the handoff:
let handoff = client.memory_handoff_fetch(
    workspace = "default",
    project = "scratch",
).await?;

// Returns null after first fetch due to single-use semantics

```

```rust
// Optional: Explicitly accept a pending handoff
client.memory_handoff_accept(
    workspace = "default",
    project = "scratch",
    handoff_id = handoff_id,
).await?;

```

## Summary

- ai-memory's **cross-agent handoff mechanism** uses MCP tools to create portable session snapshots that transfer context between agents like Claude Code and Codex.
- The **single-use semantics** ensure handoffs are automatically deleted after consumption, preventing data leakage.
- **Ownership controls** and visibility rules restrict access to authorized agents unless explicitly shared.
- The **SessionStart hook** in [`crates/ai-memory-hooks/src/router.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-hooks/src/router.rs) automates handoff injection without requiring manual intervention.
- Cross-workspace support enables agents in different directories to coordinate through explicit workspace and project targeting.

## Frequently Asked Questions

### How does ai-memory ensure that handoffs are only consumed by the intended agent?

The system enforces ownership checks through the `hand_off.owner` field in the database record. When an agent调用s `memory_handoff_fetch` or `memory_handoff_accept`, the server verifies that the caller matches the stored owner unless the handoff was created with `shared: true`. Additionally, the API layer in [`crates/ai-memory-web/src/routes/api.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-web/src/routes/api.rs) prevents unauthorized access to raw handoff bodies, only exposing metadata to unauthenticated list requests.

### What happens if two agents try to fetch the same handoff simultaneously?

The SQLite writer actor provides atomicity guarantees for all handoff operations. Since the `memory_handoff_fetch` implementation deletes the record immediately upon retrieval (single-use semantics), concurrent fetch attempts will result in only one successful retrieval. The second request will receive a null response, ensuring that session context is never duplicated or split between agents.

### Can a handoff persist across different project directories or workspaces?

Yes. The `memory_handoff_begin` tool accepts explicit `workspace` and `project` parameters that allow agents to target handoffs to specific locations. This enables an agent operating in one workspace to create a handoff that another agent can consume in a completely different workspace, facilitating cross-directory collaboration while maintaining the project's context isolation boundaries.

### Why does ai-memory use synthetic observations for handoff injection instead of modifying the context directly?

The SessionStart hook in [`crates/ai-memory-hooks/src/router.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-hooks/src/router.rs) injects handoffs as synthetic observations (`hook_result`) to maintain compatibility with the Model Context Protocol (MCP) and existing agent architectures. This approach treats the incoming handoff as a natural part of the conversation flow rather than an invasive system state modification, allowing agents to process the transferred context using their standard observation handling logic.