Handoff について
Handoffは、Claude向けのローカルなプロジェクト横断型メモリーMCPサーバーです。決定の変更を追跡し、優先度に基づいてトークン予算内の簡潔なブリーフを生成します。
主な機能
- 01目標・決定・次の手順の記録
- 02撤回された決定のブリーフ除外
- 03優先度付きトークン制限ブリーフ
- 04プロジェクト横断キーワード検索
- 05Markdown保管庫と派生SQLite索引
活用シーン
- 01新しいセッションで作業を再開
- 02別プロジェクトの決定を検索
- 03計画変更に応じてブリーフを更新
MCP 対応
作業の記録、メモリー検索、ブリーフ取得、セッションのチェックポイント用ツールを提供します。セッションブリーフのリソースとresumeプロンプトも公開します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
7掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| type | enum | はい | 次のいずれか:'goal'(このセッションで達成すること)、'decision'(下した選択。理由も含める)、'deadend'(試して失敗したこと。再試行を避けるため)、'file'(変更した、または関連するファイル)、'question'(未解決の質問)、'next_step'(具体的な次のアクション)。goal | decision | deadend | file | question | next_step |
| content | string | はい | 1~2文で単一の項目を記述します(決定とその理由、単一の失敗した試み、または1つの次のステップ)。複数段落のセッション要約にはしないでください。永続的なノートを本文中で [[Entity]] として参照し、グラフにリンクします。 |
| project | any | いいえ | プロジェクトの名前空間です。デフォルトは現在のセッションのプロジェクトです。 |
| importance | integer | いいえ | 優先度は 1~5(5 = 重大)です。優先度の高い項目は、簡易ブリーフの容量が限られている場合も残ります。 |
| supersedes | any | いいえ | このイベントによって無効になる過去のイベント ID(例:覆された決定)です。無効になったイベントは今後のブリーフから除外されます。 |
| supersedes_query | any | いいえ | ID がわからない過去のイベントを無効にするには、キーワード検索でこのプロジェクト内の同じ種類の有効なイベントから最も一致するものを見つけ、無効化します。過去の決定を変更したものの、その ID がわからない場合に使用します。無効化されたイベントの ID は返され、記録されるため、監査可能です。 |
詳細
handoff-mcp
セッション間でエージェントの記憶を保持します。 Model Context Protocol を介して、Claude のためにプロジェクトをまたいで引き継ぎを永続化します。目標、決定事項、行き詰まった点、次にすべきことを記憶するため、次のセッションをゼロから始める必要はありません。
Claude はセッション間ですべてを忘れてしまいます。handoff-mcp は、コンテキストウィンドウを超えて存続する記憶を提供します。目標、決定事項とその理由、行き詰まった点、未解決の質問、次のステップといった作業の進捗を追跡し、セッションの終わりに、優先順位付けされ、トークン予算に合わせたブリーフを作成します。そのため、次のセッションでは前回の続きからすぐに再開できます。
これはコンテキストのダンプではありません。類似性ベースのメモリストア(mem0 / OpenMemory スタイル)とは、次の 2 つの点で異なります。
- 時間軸に基づく置き換え。 新しい決定事項は古い決定事項を撤回し、撤回された決定事項は以降のブリーフに表示されません。メモリには矛盾する事実が平坦に積み重なるのではなく、世界の現在の状態が反映されます。
- 決定論的なブリーフ。 ブリーフは LLM ではなく、説明可能なランキング処理(新しさ+重要度+置き換え)によって組み立てられるため、再現可能であり、トークン予算内に収まります(イベント内容に対するソフト上限です。制限事項を参照してください)。
- 自分のストアを複数デバイスで利用。 ボールトはホスティングサービスではなく、自分だけのプライベートな git リポジトリです。そのため、ベンダーロックインなしで、マシン間でメモリを引き継げます(起動時にプル、チェックポイント時にプッシュ、競合しないエンティティのマージ)。複数デバイス間の同期を参照してください。
ステータス:v0.4、初期段階です。 コア機能(ボールト、ブリーフ、置き換え、キーワード検索、プロジェクト横断の想起)はテスト済みで安定しています。セマンティック機能、統合、インポーター、複数デバイス間の同期レイヤーはオプションで、より新しい機能です。適切なタイミングでエージェントがツールを呼び出すことを前提としています。率直な制約については制限事項を参照してください。
また、プロジェクト横断で利用できます。1 つのボールトをプロジェクトごとに名前空間で分けて使います。ブリーフの対象はプロジェクト単位(このプロジェクトでどこまで進めたか)ですが、search_memory はすべてのプロジェクトを横断して想起できます。そのため、「自分のプロジェクトの 1 つで X を行った」と伝えると、Claude は別のプロジェクトからその決定事項を見つけて取り出せます。
目次
- デモ:2 つのセッション
- ベンチマーク
- 仕組み
- MCP ツール
- コストと API キー
- セマンティック想起(オプション)
- メモリの統合(オプション)
- 既存の履歴をインポート
- クイックスタート
- MCP クライアントを接続 — Claude、Cursor、Codex、Kilo Code、…
- メモリの保存場所
- 複数デバイス間の同期(オプション)
- エージェントとの統合
- 制限事項
- 開発
- ライセンス
デモ:2 つのセッション
python examples/two_sessions_demo.py — セッション 1 が作業して終了し、セッション 2 はブリーフだけを使って再開する新しいプロセスです。
セッション 1 は進捗を記録し、一度考えを変えます:
log_event("goal", "Ship the finance agent: income/expense tracking…")
d = log_event("decision", "Store transactions in a flat JSON file.")
log_event("decision", "Use SQLite instead of JSON — need queries.", supersedes=[d]) # retracts ↑
note_entity("Architecture", "SQLite-backed; LLM summary calls run in a worker.") # durable
log_event("deadend", "Provider streaming API times out on long months; needs chunking.")
log_event("question", "Recurring transactions: templates or materialised rows?")
log_event("next_step","Write the SQLite schema, then the ingest function.")
checkpoint("Chose SQLite; finance schema is next.")
セッション 2 は get_brief() を呼び出し、現在の状態だけを取得します。撤回された JSON の決定は含まれません:
# Hand-off brief — agent-hub
## Goal
- Ship the finance agent: income/expense tracking with scheduled summaries.
## Next step
- Write the SQLite schema for transactions and categories, then the ingest function.
## Decisions
- Use SQLite for transactions instead of JSON — need queries for summaries. See [[Architecture]].
## Dead ends (tried & failed)
- Tried the provider's streaming API for the summary job — times out on long months. Don't retry without chunking.
## Open questions
- Should recurring transactions be modelled as templates or materialised rows?
## Related knowledge
- [[Architecture]] — SQLite-backed; LLM summary calls run in a worker.
撤回された「フラットな JSON ファイル」という決定は一度も表示されません。グラフで関連付けられた
[[Architecture]]ノートは自動的に取り込まれます。ブリーフは約 170 トークンです。
また、プロジェクトをまたいだ想起では、search_memory("timeout chunking", scope="all") によって、別のプロジェクトの決定が取得されます:
- [hermes] In the Hermes project we solved long-job timeouts by chunking requests.
- [agent-hub] Tried the provider's streaming API for the summary job — times out on long months…
ベンチマーク
オフラインで実行できる、決定論的なベンチマークが 2 つあります。LLM もネットワークも不要なため、どこでも同じ結果を再生成でき、tests/test_benchmark.py で固定されています。詳しい数値、手法、再現方法については、benchmarks/RESULTS.md をご覧ください。
1. 単独での上書き処理(benchmarks/supersession_benchmark.py)。あるプロジェクトの決定が、4 つのトピックについて 8 件の発言を通じて変化します。それぞれのトピックには、後の発言で撤回される決定が 1 つあります(JSON→SQLite、Cookie→JWT など)。決定ごとに取得する(つまり、古い情報にもすべてアクセスできる)場合の、フラットなログと有効なビューの比較です:
| モード | 古い情報の漏出 | 現在の決定の保持 |
|---|---|---|
| 上書き処理 OFF(フラットなログ) | 4 / 4 | 4 / 4 |
| 上書き処理 ON(有効なビュー) | 0 / 4 | 4 / 4 |
上書き処理によって、撤回された決定だけを除去し、現在の決定はすべて保持されます。さらに、現在の決定の保持も評価するため、空の回答を成功として扱うことはできません。ある情報が別の情報を退役させるという概念のない類似度ストアでは、OFF の行と同じように動作します。
2. ブリーフと単純なダンプの比較(benchmarks/brief_reconstruction.py)。再開時のセッションが実際に読み取る内容、つまり予算管理と上書き処理に対応したブリーフと、ログ全体を貼り戻す方法を比較します。履歴が増えるにつれて、ダンプは膨らみ、撤回された情報をすべて保持し続けます。一方、ブリーフは上限(ソフト上限)内に収まり、すべての重要項目を保持しながら矛盾を含みません(例:228 件のイベントで 3063→217 トークン、14 倍、矛盾は 3 件から 0 件)。
これらは、別のストアとの比較を演出するのではなく、仕組みを正直に評価するものです。システム間で公正に比較するには、同一の取得条件と、CI で再現できない LLM エンドポイントが必要です(ADR-0008 を参照)。
この README の「トークン」は、ここでもほかの箇所でも、実際のトークナイザーで数えたものではなく、
len(text) / 4による推定値です(モデルに依存しません)。
仕組み
Markdown ボルトが信頼できる情報源です。人間が読みやすく、Obsidian で開くことができ、データは自分のディスク上にあります。SQLite + FTS5 インデックスはボルトから派生し、いつでも再構築できます。ランキング、トークン予算、プロジェクトをまたいだ全文検索に使用されます。
設計の根拠については、docs/architecture.md と ADR をご覧ください。
MCP ツール
| ツール | Claude が呼び出すタイミング |
|---|---|
get_brief(project?, token_budget?) | セッション開始時 — 前回のセッションの続きから作業できるよう、状態を読み込みます。 |
log_event(type, content, importance?, supersedes?, supersedes_query?, project?) | 作業中 — 目標、決定事項、行き詰まった点、ファイル、質問、次の手順を記録します。supersedes は ID を指定して以前のイベントを終了扱いにし、supersedes_query は ID が分からない場合に、同じタイプで最も一致するアクティブなイベントを終了扱いにします(ADR-0007)。 |
search_memory(query, scope=current|all, limit?) | ユーザーが過去の作業や別プロジェクトの作業に言及したときに使用します。limit は結果数の上限です(デフォルトは 10)。各検索結果にはイベント ID が含まれ、log_event の supersedes にそのまま渡せます。 |
note_entity(name, content, project?) | プロジェクトに関する永続的な知識(アーキテクチャ、規約、コンポーネント)を記録します。 |
checkpoint(summary?, project?) | セッション終了時 — セッションを確定し、ブリーフを出力します。記録時と同じ project を渡してください(デフォルトはセッションのプロジェクトです)。 |
consolidate(project?, older_than_days?) | 古いセッションを圧縮し、永続的なメモにまとめます(オプトイン、LLM が必要です)。 |
sync(remote_url?) | デバイス間でメモリを同期するため、ボールトのプライベートな Git リモートから取得、コミット、プッシュします(オプトイン)。リポジトリ URL を指定した初回呼び出しで設定し、その後は引数なしで同期します。マルチデバイス同期を参照してください。 |
また、MCP リソース session://brief と、セッションの最初にブリーフを
自動読み込みするためのプロンプト resume も公開しています。
log_event のタイプ:goal、decision、deadend、file、question、next_step。
コストと API キー
サブスクリプション不要。必須の API キーもありません。コア機能は無料で完全にローカルで動作します — メモリはディスク上のプレーンなファイルであり、handoff-mcp が外部に通信することはありません(ホスト型サービスもテレメトリーもありません)。
| 機能 | モデル/キーが必要ですか? |
|---|---|
| メモリ、ブリーフ、置き換え、キーワード検索、プロジェクト横断、インポーター | いいえ — ローカル、オフライン、無料 |
| セマンティック検索 (オプション) | デフォルトでは不要(hashing またはローカルの sentence-transformers)。openai バックエンドを選ぶ場合に限り、OpenAI 互換のキーを用意してください |
| 統合 (オプション、時折使用) | モデル — 自分のキー(数セント程度、頻繁には実行しません。ホットパスではありません)またはローカルモデル |
そのため、価値の大半は無料で、キーも必要ありません。オプション機能はローカルで動作するか、ご自身のプロバイダーを使用するため、当社のサービスに縛られることはありません。
セマンティック検索(オプション)
キーワード検索(FTS5/bm25)はデフォルトで有効になっており、追加の設定は不要です。キーワードの類似度と埋め込みの類似度を Reciprocal Rank Fusion で統合するセマンティックレイヤーを有効にできます。
HANDOFF_SEMANTIC=1 handoff-mcp # turn the layer on (default: hashing backend)
選択するバックエンドによって、言い換えを実際に理解できるかどうかが決まります。
デフォルトの hashing バックエンドは字句的なベースラインです。トークンをハッシュすることで、あいまいな字句マッチングを追加し(ハイブリッドパイプラインのデモにもなります)、単語が異なる場合は意味に基づいて検索することはありません。言い換えに対応した検索を実現するには、学習済みの埋め込みを使用する local または openai を選択してください。
HANDOFF_EMBEDDER で選択するプラグ可能な埋め込みバックエンド。サーバーは1つで、フォークは不要です。
| バックエンド | インストール | 言い換えに対応? | メモ |
|---|---|---|---|
hashing(デフォルト) | — | いいえ — 字句ベース | 決定論的で、オフラインで動作し、依存関係のないおもちゃのベースライン(feature-hashing)です。デモやテストには適していますが、実際の意味理解には対応していません。 |
local(推奨) | pip install -e ".[semantic-local]" | はい | オフラインの sentence-transformers を使用します。キーは不要ですが、torch がインストールされます。デフォルトモデルは Qwen/Qwen3-Embedding-0.6B(ロシア語を含む多言語対応、1024次元、Apache-2.0)です。 |
openai | pip install -e ".[semantic-openai]" | はい | OpenAI 互換のエンドポイントを使用できます(OpenAI、Together、セルフホストのプロキシなど)。HANDOFF_EMBED_BASE_URL / OPENAI_BASE_URL と HANDOFF_EMBED_API_KEY / OPENAI_API_KEY を設定してください。 |
# Example: semantic recall via any OpenAI-compatible endpoint
pip install -e ".[semantic-openai,semantic]"
export HANDOFF_SEMANTIC=1 HANDOFF_EMBEDDER=openai
export HANDOFF_EMBED_BASE_URL=https://your-openai-compatible-endpoint/v1 HANDOFF_EMBED_API_KEY=sk-…
export HANDOFF_EMBED_MODEL=text-embedding-3-small
設計については ADR-0004 を参照してください。
Embedderプロトコルの背後にあるプラグ可能な埋め込み器 — デフォルトのhashingは決定論的で依存関係がなく、openai/localはほかの設定を変更せずに実際のセマンティック品質を提供します。- sqlite-vec は高速化手段であり、必須ではありません(
.[semantic])— ベクトルは BLOB として永続化され、正確なコサイン類似度スキャンで検索できます。sqlite-vecがインストールされ、読み込み可能な場合は、vec0テーブルによって同じ上位検索結果を高速な KNN で取得できます。 - 決定論的な brief は埋め込みを参照しません — セマンティック検索が影響するのは
search_memoryのみです。 - 再ランキング — 検索結果は、関連性・新しさ(時間減衰)・重要度を決定論的に組み合わせて、どのモードでも並べ替えられます。これにより、新しく優先度の高いメモリが先に表示されます。LLM は使用しません。生の関連性順にするには
rerank=Falseを指定してください。 - 増分埋め込み — イベントは不変のため、起動時に埋め込まれるのは新しいイベントのみです(キャッシュ済みのベクトルは再利用されます)。埋め込みモデルの次元が変わると、キャッシュは自動的に無効化されます。これにより、より高負荷なローカルモデルも実用的に使用できます。
より軽量で高速なローカルモデルを使うには、HANDOFF_EMBED_MODEL を設定してください(例:Alibaba-NLP/gte-multilingual-base、305M/768次元。このモデルには HANDOFF_EMBED_TRUST_REMOTE_CODE=1 も必要です)。
メモリの統合(オプション)
長期にわたるプロジェクトでは、エピソードログは際限なく増えていきます。これはインデックスだけでなく、容量の問題です。統合(「スリープ」)によってログを整理できます。
HANDOFF_LLM_MODEL=gpt-4o-mini handoff-mcp # enables the consolidate tool
consolidate(project?, older_than_days?) は、完了済みの古いセッションに含まれるアクティブな決定事項を、長期保存されるエンティティノート(Architecture、Decisions、Dead-ends など)に要約し、元のデータを <project>/archive/ にアーカイブして、アクティブなインデックスから削除します。これにより、ブリーフですでに提示される永続的な知識は維持したまま、保管庫を縮小できます。
- LLM を呼び出すのはこのステップのみです。また、
HANDOFF_LLM_MODELが設定されていない限り無効です(OpenAI 互換。エンベッダーのエンドポイント設定を再利用します)。ブリーフ、検索、置き換えは引き続き決定論的です。 - 要約されるのはアクティブなイベントのみです。撤回された決定が記録として残ることはありません。行き詰まった事例は注意喚起の事実として保持されます。
- 元のデータは削除せず、アーカイブします(監査可能で、元に戻せます)。
ADR-0006 を参照してください。
既存の履歴をインポートする
すでにあるデータからプロジェクトのメモリを初期化することで、何もない状態ではなく、最初の瞬間から役立つようにします。
handoff-import git ./my-repo --project my-project # commit history → memory
handoff-import claude session.jsonl --project my-project # a Claude Code transcript
- git は各コミットを、決定事項(件名)と変更ファイルのメモに変換し、コミット日時を付与します。すべて決定的に処理され、LLM は使用しません。
- claude は Claude Code のトランスクリプトから、最初のプロンプトを目標として、ファイル編集をファイルイベントとして取り込みます(ベストエフォート)。
- インポートは冪等です(ID はソースから導出されるため、再実行しても新しい項目のみが追加されます)。同じ共有ボールト(
HANDOFF_VAULT)に書き込みます。
クイックスタート
uv venv && uv pip install -e ".[dev]"
# Run the two-session demo: session 1 works, session 2 reads the brief.
python examples/two_sessions_demo.py
MCP クライアントを接続する
Claude Code — 1 分でインストール(推奨):
/plugin marketplace add kirill-sviridov/handoff-mcp
/plugin install handoff-mcp@handoff-mcp
これにより、サーバー(uvx 経由で PyPI から自動インストール。uv が PATH に必要です)、メモリプロトコルを読み込むセッション開始フック、および session-handoff/session-planning スキルがまとめて設定されます。以下の手動設定は、他のクライアントを使用する場合(または設定を明示したい場合)に使用してください。
handoff-mcp は標準の MCP over stdio に対応しているため、あらゆる MCP クライアントで動作します。Claude、Cursor、Codex、Kilo Code、Windsurf、Cline、VS Code、Zed などに対応しています。設定はどの環境でもほぼ同じで、異なるのはファイルの場所(および Codex の場合は形式)だけです。
標準設定 — Claude、Cursor、Kilo Code、Windsurf、Cline など、多くのクライアントで使われる mcpServers JSON ブロック:
{
"mcpServers": {
"handoff": {
"command": "handoff-mcp",
"env": {
"HANDOFF_VAULT": "/path/to/your/vault",
"HANDOFF_PROJECT": "my-project"
}
}
}
}
| クライアント | 設定場所 |
|---|---|
| Claude Code | claude mcp add handoff -- handoff-mcp、またはプロジェクト内の .mcp.json |
| Claude Desktop | claude_desktop_config.json |
| Cursor | .cursor/mcp.json(プロジェクト)または ~/.cursor/mcp.json(グローバル) |
| Kilo Code | Settings → MCP → Add Server → Local (stdio)、または .kilocode/mcp.json |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
| Cline / Roo Code | 拡張機能の MCP パネル → cline_mcp_settings.json |
| VS Code(Copilot) | .vscode/mcp.json — 下記の異なるスキーマに注意してください |
Codex CLI は ~/.codex/config.toml の TOML を使用します(または codex mcp add を実行します)。
[mcp_servers.handoff]
command = "handoff-mcp"
[mcp_servers.handoff.env]
HANDOFF_VAULT = "/path/to/your/vault"
HANDOFF_PROJECT = "my-project"
VS Code は "servers" と明示的なタイプを使用します。
{ "servers": { "handoff": { "type": "stdio", "command": "handoff-mcp",
"env": { "HANDOFF_VAULT": "/path/to/your/vault", "HANDOFF_PROJECT": "my-project" } } } }
注意:
handoff-mcpがPATH上にある必要があります。ツールとしてインストールするか(uv tool install handoff-mcp、またはソースからuv tool install git+https://github.com/kirill-sviridov/handoff-mcp)、チェックアウトから"command": "python", "args": ["-m", "handoff_mcp.server"]を使用してください。- エージェント/リポジトリごとに
HANDOFF_PROJECTを設定し、すべてのエージェントでHANDOFF_VAULTが同じ共有ボールトを指すようにしてください(下記参照)。0.4.0 以降、HANDOFF_PROJECTが未設定の場合、プロジェクト名は git ルート/cwd のベース名がデフォルトとなり、設定不要でリポジトリごとの名前空間が作成されます。明示的に設定した場合は、そちらが優先されます。Claude Code では、ディレクトリにはサーバーの cwd ではなくCLAUDE_PROJECT_DIR(セッションのプロジェクト)が使用されます(0.4.1 以降)。 - uv を使ってチェックアウトから実行する場合は、
--directoryではなくuv run --project /path/to/handoff-mcp handoff-mcpを使用してください。--directoryを指定するとサーバーの cwd がチェックアウト先に移動するため、CLAUDE_PROJECT_DIRを設定しないクライアントでは、すべてのプロジェクトがhandoff-mcp配下に記録されます。
メモリの保存場所
共有の保管庫を1つ用意し、その中にプロジェクトごとのフォルダーを作成します。
~/.handoff-mcp/vault/ # HANDOFF_VAULT (default; override per machine)
├── .index.db # derived SQLite index — rebuildable, gitignore it
├── my-project/
│ ├── sessions/<id>.md # episodic notes
│ └── entities/<Name>.md # durable knowledge
└── another-project/…
- リポジトリごとに分けず、保管庫は1つにします。 プロジェクト横断の検索(
search_memory)が機能するのは、すべてのプロジェクトが1つのストアに保存されているからです。すべてのエージェントのHANDOFF_VAULTを同じディレクトリに設定し、HANDOFF_PROJECTだけを変えてください。 - コードリポジトリの外に保存されるため、作業中のプロジェクトに誤ってコミットされることはありません。 プロジェクトのリポジトリをクリーンに保てます。
- バックアップや複数デバイス間の同期が必要ですか? 保管庫はプレーンな Markdown なので、独立してバージョン管理できます(プライベート Git リポジトリ、Obsidian Sync、Dropbox など)。デバイス間の組み込み Git 同期(起動時の pull、チェックポイント時の push、競合のないエンティティのマージ)については、複数デバイス間の同期を参照してください。
handoff-sync --setupを実行すると、リモートが設定され、派生インデックスが Git の対象外になるよう設定されます。 - 1つのリポジトリと一緒に持ち運べるメモリが必要ですか?
HANDOFF_VAULTをそのリポジトリ内(例:./.handoff)に設定できますが、その場合、検索対象はそのプロジェクトだけになります。共有の保管庫をおすすめします。
複数デバイス間の同期(任意)
保管庫はプライベート Git リポジトリにすぎないため、複数のマシン間でメモリを同期できます。同期は明示的に有効にした場合のみ行われます。Git を設定しなくても、1台のデバイスでメモリをすべて利用できます。
| ティア | 設定 | 利用できる機能 |
|---|---|---|
| ローカルのみ(デフォルト) | なし | メモリをすべて利用可能。1台のデバイスで使用。アカウント不要 |
| 手動 | handoff-sync --setup <private-repo-url> を1回実行 | handoff-sync(または sync ツール)で、必要に応じて pull、commit、push を実行 |
| 自動 | 上記の設定に加えて HANDOFF_AUTO_SYNC=1 | セッション開始時に pull、チェックポイント時に push |
エンティティのノートは、Git に組み込まれている union ドライバーを使ってマシン間で適切にマージされます(設定時に保管庫の .gitattributes に */entities/*.md merge=union が書き込まれます)。シェルを使えないクライアント(例:Cursor)では、エージェントに同期を依頼してください。sync ツールはターミナルを必要としません。設定には、利用可能な Git 認証(gh auth login または SSH キー)が必要です。push に失敗した場合は、修正方法がコマンドに表示されます。
エージェントとの連携
いつ使うかを判断するための仕組みです。 サーバーからモデルに何かが送られることはありません。ツールを呼び出すタイミングはモデルが判断します。最も汎用的な方法から最も高機能な方法まで、4つの層で確実に機能させます。
-
ツールの説明(組み込み) — 各ツールに、呼び出すタイミングが記載されています。あらゆる MCP クライアントで機能します。
-
サーバーの
instructions(組み込み) — 接続時にサーバーから送られる短い手順です(開始時に概要を読み込み、作業中に記録し、最後にチェックポイントを作成します)。Claude Desktop、Cursor、その他の MCP クライアントで利用できます。 -
Claude Code スキル(
skills/) — ワークフローを定義し、特に口語的な合図に反応するようにします。session-handoff— 「次のセッションに引き継いで」や「今日はここまで」と言うと、エージェントが自動でcheckpointを実行します。また、初回の使用時にプロジェクトの指示ファイル(CLAUDE.md、またはクライアントに応じてAGENTS.md/.cursor/rules/handoff.mdc/.windsurfrules)を用意します。session-planning— 任意の補助スキルです。大きなタスクをセッションごとに扱える大きさに分割し、計画をメモリに保存します。
スキルのディレクトリにコピーしてインストールします。
cp -r skills/handoff skills/planning ~/.claude/skills/ # user-wide # or .claude/skills/ inside a specific project(スキルは Claude Code / claude.ai の機能です。他のエージェントは1〜2層を利用します。)
Claude 以外のクライアントでは、
handoff-initCLI を使ってメモリのブロックをプロジェクトの指示ファイルに追加します(何度実行しても同じ結果になります)。handoff-init # CLAUDE.md handoff-init --client codex # AGENTS.md · --client cursor / windsurf -
Claude Code プラグイン — 1回のインストールで1〜3層を利用できます。MCP クライアントを接続するを参照してください。
Claude Code では、スキルがなくても概要が自動で読み込まれるよう、CLAUDE.md に次の内容も追加してください。
セッションの開始時に
get_briefを呼び出してください。作業中は、決定事項、行き詰まった箇所、次の手順をlog_eventで記録してください。呼び出しごとに1つの独立した項目(理由を添えた1〜2文)を記録し、セッション全体の要約にはしないでください。長期的に有効なノートは[[Entity]]で参照してください。終了前にcheckpointを実行してください。過去の作業や別のプロジェクトについて言及された場合は、search_memoryを呼び出してください。
制限事項
v0.4 の率直な制約です。採用する際の参考にしてください。
- 置き換えは明示的に指定する必要があり、推測されません。 handoff-mcp が独自に、あるメモリが別のメモリを廃止すると判断することはありません。エージェントが
supersedes(ID 指定)またはsupersedes_query(最適な一致による指定)を使って明示する必要があります。これは意図的な設計です(ブリーフの決定性と監査可能性を保つためです)が、メモリの品質はエージェントが実際に撤回を記録するかどうかに左右されます。LLM による抽出を試みるストアのように、矛盾を暗黙に重複排除することはありません。例外はnext_stepです。新しい次のステップを記録すると、それ以前のセッションで有効だった次のステップは、ルールに基づいて自動的に廃止され、イベントに記録されます(ADR-0009)。廃止されたステップがまだ有効な場合は、改めて記録してください。 - エージェントの規律に依存します。 サーバーから情報がプッシュされることはありません。適切なタイミングでモデルが
log_event/get_brief/checkpointを呼び出すことで価値が生まれます。ツールの説明とスキルはその実行を促しますが、ツールを一度も呼び出さないクライアントでは、ボールトは空のままです。セッションをまたぐメモリの質は、記録された内容の質に左右されます。 - デフォルトのセマンティックバックエンド(
hashing)は語句ベースであり、言い換えには対応していません。 言い換えを含む実用的な検索には、localまたはopenaiが必要です(セマンティック検索を参照)。決定論的なブリーフ自体は、埋め込みを一切使用しません。 - トークン予算は目安です。 イベントの内容に上限を設けます。セクション見出しと「関連ナレッジ」ブロックはその上に加わるため、生成されるブリーフが上限を少し超えることがあります。履歴が増えてもブリーフを上限内に保ち、簡潔にするためのものであり、バイト数の厳密な上限ではありません。
- 最新情報の反映は単一プロセス単位です。 1 つのボールトを複数のプロセスやエージェントで共有できます(SQLite WAL とビジータイムアウトにより、複数の書き込みが共存できます)。ただし、実行中のプロセスがボールトの状態を更新するのは起動時(
_sync_index)です。自プロセスの書き込みは即時に反映されますが、別プロセスで新たに追加されたイベントは、次回起動時まで反映されません(手動のsync、またはブリーフ取得時に同期するHANDOFF_AUTO_SYNCを使えば、新しいイベントを取得してセッション中に再インデックスできます)。1 つのプロセス内で複数のスレッドが同時にアクセスする場合は、共有インデックスへのアクセスをロックで直列化します。 - 個人・チーム規模向けです。 ランキングでは、プロジェクトのイベントをメモリに読み込みます。数千件のセッションには適していますが、数百万件向けに最適化されてはいません(その時点で必要になる、対象を絞った修正についてはADR-0005を参照してください)。
開発
uv pip install -e ".[dev]"
ruff check . && mypy && pytest
python examples/two_sessions_demo.py # the hand-off in action
python examples/demo_presentation.py # paced/narrated version (for recording a GIF)
python examples/stdio_smoke.py # run it as a real stdio MCP server
python benchmarks/brief_reconstruction.py # brief vs naive full-dump
python benchmarks/supersession_benchmark.py # supersession on vs off, in isolation
ライセンス
MIT — LICENSEを参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。