Skip to main content
Glama

Agents Handoff

CI npm npm License: MIT

Git tells you what code changed. Nothing tells the next developer what that change means for them.

Agents Handoff is an open format and a small, local-first toolkit for closing that gap. Your coding agent writes a short, structured HANDOFF.md about a change you just finished. Your teammate's agent reads it in their repository and knows exactly what to change — and what not to build.

finish a change  →  "write a handoff for mobile"  →  validate  →  export <id>.md  →  their agent reads it
  • The tool collects the facts, the agent does the reasoning. Git history, changed routes, auth guards, types, migrations and environment variables are gathered deterministically. What they mean to another team is written by the agent that built the change with you.

  • Markdown files. Create, validate, export and read the complete handoff locally. The exported file is the artifact another developer or agent consumes.

  • Works where you already are. Plugins for Claude Code and Codex, an MCP server for any other agent, and a CLI for humans and scripts.


Quick start

Requires Node.js 20.10 or later, and git.

Claude Code

/plugin marketplace add Ryujin-Labs/agents-handoff
/plugin install agents-handoff@agents-handoff

The plugin brings both the /agents-handoff:handoff and /agents-handoff:handoff-receive skills and the handoff MCP tools. In a repository where you just finished a change, ask:

write a handoff for the mobile team

Codex

codex plugin marketplace add Ryujin-Labs/agents-handoff
codex plugin add agents-handoff@agents-handoff

The same two skills and the same MCP tools, packaged for Codex. Ask it the same way: "write a handoff for the mobile team".

Any MCP client

Claude Code, without the plugin:

claude mcp add agents-handoff -- npx -y ryujin-handoff-mcp

Claude Desktop (claude_desktop_config.json), Cursor (.cursor/mcp.json) and other clients that use the same shape:

{ "mcpServers": { "agents-handoff": { "command": "npx", "args": ["-y", "ryujin-handoff-mcp"] } } }

Codex without the plugin (~/.codex/config.toml):

[mcp_servers.agents-handoff]
command = "npx"
args = ["-y", "ryujin-handoff-mcp"]

Nothing is installed globally: the client fetches the server on first use.

The CLI

npm i -g ryujin-handoff
handoff            # an interactive menu
handoff init       # set up this repository

handoff install claude-code copies the skills into .claude/skills/ so a whole team gets them by cloning, and handoff install mcp adds the server to Claude Desktop.


Related MCP server: Home Lab Context MCP

The loop

1. You finish a change. Backend work is done: GET /messages/:threadId now returns 403 to non-members, and the list fields were renamed.

2. Your agent writes the handoff. It calls handoff_context for the deterministic brief, reads the code that matters with handoff_source, adds what it knows from building the change with you, and stores a finished document with handoff_write:

.handoff/2026-09-14-message-list-requires-thread-membership/HANDOFF.md

If the intent is unclear — two unrelated changes in the working tree, a target it had to guess, a breaking call the code does not settle — it asks once, with its proposal already in the question.

3. Export the Markdown. The agent calls handoff_export, or you run handoff export <id>. It writes the complete document to .handoff/exports/<id>.md and reports the local file path. Open or download that file from your agent’s file view. You choose how to give the file to the other developer.

4. Their agent reads it. In the mobile repository:

receive this handoff: ~/Downloads/2026-09-14-message-list-requires-thread-membership.md

handoff_receive narrows Required Actions to their target, and their agent searches its own codebase for the code that consumes the change, reports what actually differs, and — when asked — implements it.

What a handoff looks like

---
handoff_version: 1
id: 2026-08-28-auth-refresh-v2
created_at: 2026-08-28T18:20:00Z
status: ready
breaking: true
source:
  project: backend
  branch: feature/auth-refresh
  commit: 71ac931
targets: [mobile, web]
change_type: [api, authentication]
---

# Refresh tokens are now single-use

## Summary

`POST /auth/refresh` now returns a new `refreshToken` and invalidates the one you sent.

## Why This Matters

Clients that keep their original token get logged out mid-session the first time they
refresh after this ships.

## Required Actions

### mobile

1. Read `refreshToken` from the refresh response and persist it in the keychain.
2. Replace the stored token atomically, in the same write as the access token.

## Instructions for Receiving Agent

Find the existing refresh path before writing anything. Modify it. Do not add a second
token store, a new HTTP client, or a global retry interceptor.

The frontmatter is the machine contract; the sections are for people and agents. The two that matter most are Required Actions — what the receiver must do — and Instructions for Receiving Agent — what it must not build. Three complete examples live in examples/, and the format is specified in SPEC.md.

What your agent gets

Tool

handoff_context

The deterministic brief: revision, changed files, and signals about routes, auth, contracts, migrations, environment and dependencies

handoff_source

Read the files and diffs behind the brief

handoff_write

Store a finished, validated handoff — prose in, facts from git

handoff_export

Export the full, validated Markdown and report its local path

handoff_receive

Read a handoff someone sent, narrowed to this repository

handoff_list · handoff_read · handoff_validate · handoff_setup

Plus two prompts, handoff and handoff-receive, carrying the same method as the skills.

handoff_write takes prose only. The schema version, id, timestamp, branch, commit and revision range come from git, and the section headings are generated — so they cannot be misremembered, and they cannot drift from what the validator and the receiving side match on. The document is validated and scanned for credentials before it is stored; if it fails, nothing is written and the agent gets the reasons back. It never replaces an existing handoff unless you chose to update it: a taken id comes back as a question for you.

The core never calls a model. The brief is fast, offline and the same for every agent, and it says what it cannot know: its last section is titled "What this brief does not contain".

Export

The output is one complete Markdown file: frontmatter, summary, required actions, contracts, verification, and every other section the author wrote.

handoff validate <id> --strict
handoff export <id>
handoff export ./HANDOFF.md --out ./exports/backend-auth.md

Without --out, the file is written to .handoff/exports/<id>.md. Export checks the handoff and copies its original bytes, so the result is the full document rather than a message preview or a shortened summary. It reports the exported path; --json also returns the source path and complete Markdown for automation.

With MCP, ask the agent to call handoff_export and show you the exported file. Open or download it from the client’s file view, then give that Markdown to the receiving agent. The receiver can use handoff receive <path> --as mobile to read the required actions for its repository.

Handoffs and exports are local files. Use handoff config --gitignore to keep .handoff/ out of git, or keep them in a private repository when your team wants them versioned. A file committed to a public repository is public. Review the document before sharing it.

Security

A handoff you receive was written by another team. The tooling treats it as data:

  • Paths are confined. The MCP server reads and writes only inside the project it is given (and only under --root, when pinned), with symlinks resolved before the check — including exported Markdown files. A handoff’s id never chooses an arbitrary file path; exports require a safe id for the filename.

  • Credentials are refused. Documents are scanned for credential-shaped strings before they are stored by handoff_write or handoff create --stdin, and every handoff is scanned again before it is exported. Validation — CLI or MCP — reports what it finds and fails. A handoff you receive that carries one is read but not stored, so it is never committed here. Files that exist to hold secrets — .env, keys, .npmrc, cloud credentials — are never read.

  • Incoming instructions are not commands. The receiving brief tells the agent to weigh the document's claims against its own repository, not to obey it.

See SECURITY.md to report a vulnerability.

Configuration

handoff.config.json, written by handoff init and optional everywhere:

{
  "version": 1,
  "project": "backend",
  "targets": ["mobile", "web", "devops"],
  "identity": null,
  "language": null,
  "ask": "when-unclear",
  "gitignore": false
}

Key

project

Logical name written into source.project

targets

Consumers this project hands off to, offered in prompts

defaultTarget

Target assumed by handoff create when none is given

identity

Which consumer this repository is — narrows handoffs you receive. Separate from defaultTarget, which is who the handoff addresses

language

Prose language; null means English. ## headings stay English, since they are the machine contract

ask

When the agent checks in: when-unclear (default), always, never

gitignore

true keeps .handoff/ out of git

CLI

Command

handoff init

Set up the repository (--claude-code installs the skills too)

handoff context

Print the deterministic brief for the current change

handoff create

Scaffold a draft with real git facts and <!-- TODO --> where judgment is owed, or store a finished document with --stdin

handoff list · show

List handoffs (--inbox for received ones), print one

handoff validate <id|path>

Check against the v1 schema (--strict fails on warnings)

handoff receive <path>

Read an incoming handoff (--as mobile to narrow it)

handoff export <file|id>

Export the complete Markdown (--out chooses the local path; --json returns paths)

handoff config

Show or change settings, and report configuration problems

handoff install claude-code|mcp

Install the skills, or add the MCP server to Claude Desktop

Run any command with nothing to go on and it asks; give it flags and it never prompts. Prompting turns on only when both stdin and stdout are a terminal, so an agent shelling out or a CI job gets the non-interactive behaviour automatically. Full reference in docs/cli.md.

A scaffold from handoff create still needs the agent’s prose. Export refuses unfilled TODO markers, and a document marked ready that still carries a TODO fails validation.

Limitations

This is 0.1. What it does not do yet, plainly:

  • Signals are pattern-based. Route, contract and migration detection is strongest for TypeScript/JavaScript and Python backends. Go, Rails and OpenAPI are partly covered; Django, Spring, Ktor, Swift and Kotlin types are not detected yet. The agent reads the code either way — the brief is a starting point, never the verdict.

  • Downloads depend on your client. The tool returns a local Markdown file path. Clients with a file view can open or download it; other clients show the path.

  • No acknowledgement tracking. A handoff does not know whether it was read.

  • Claude Code and Codex are the tested clients, each with a plugin. Any other MCP client works through the server alone.

Architecture

packages/
  core/                        schema, Markdown, git context, collectors, validation,
                               storage, Markdown export, and the shared method. No model calls.
  mcp/                         the MCP server: tools and prompts over stdio
  cli/                         the `handoff` binary
  integrations/claude-code/    the Claude Code plugin and its generated skills
  integrations/codex/          the Codex plugin and its generated skills

The method an agent follows — collect, recall, read, check in, compose, cut, report — is written once in packages/core/src/guidance/ and rendered into the MCP prompts, the server's instructions, and both plugins' skills, so the surfaces cannot drift apart. More in docs/architecture.md and docs/mcp.md.

Development

npm install
npm test                 # build, then the full suite
npm run release:check    # what CI runs before a release

The tests run the collectors, the CLI and the MCP server end to end against real temporary git repositories. See CONTRIBUTING.md.

License

MIT. Agents Handoff is built and maintained by Ryujin Labs.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI coding agents and hosts to enforce deterministic repository boundaries via MCP, providing structured reads, supervised edits, snapshots, audits, and recovery with machine-readable evidence.
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Coordination protocol for parallel coding agents, built above Git. The MCP server exposes the full 17-tool lifecycle over stdio: register agents, publish intents with semantic scopes and declared operations, claim work, check for conflicts before code is written, publish ChangeSets, run trusted named verification checks, and record accepted work. Deterministic rules raise findings when two agents'
    18
    541
    Apache 2.0