1つのhandoff、2つの既存surface
Agent間のhandoffで新しいAPIを追加する必要はありません。書き込み側のagentはTypeScript SDK workflow helpersのtaskStart、recordDecision、recordBugFix、taskEndを使え、受け取り側のagentはMCP toolのrecall_contextまたはSDK methodのrecallContextを使えます。以下のagent名は既存requestが運ぶattribution値であり、API keyまたはOAuth grantとmemory:read / memory:write scopeが引き続きアクセスを認可します。
- Claudeは接続済みadapterまたはSDK clientを通じてdecisionを書き込みます。
- Codexは範囲を限定したcontextをrecallし、修正を記録してtaskを閉じます。
- 認証済みownerと要求されたscopeが許可すれば、Claudeはrecall_contextを再度呼び出して共有されたdecisionと修正を受け取ります。
Handoffのtimeline
lifecycleの順序はtaskStart → recall_context → recordDecision → recordBugFix → taskEnd → 別agentのrecall_contextです。taskStartとtaskEndは既定でstartedおよびcompleted statusのworking memory typeを使い、recordDecisionとrecordBugFixは既定でsemantic memoryを使います。すべてのSDK capture helperはCaptureResultに解決されるため、callerはmemoryが書き込まれたと仮定する前にshouldCaptureを確認する必要があります。
1. Claude: client.taskStart(...)
2. Codex: recall_context({ query, max_items, max_tokens })
3. Claude: client.recordDecision(...)
4. Codex: client.recordBugFix(...)
5. Codex: client.taskEnd(...)
6. Claude: recall_context({ query, max_items, max_tokens })SDKでdecisionを書き込む
SDK methodは既存のAgentWorkflowOptions fieldsを使います。handoffの間はsource、agent identity、sessionId、taskId、scopeを一貫させ、API keyをoptionsや記録するcontentに入れないでください。
const scope = 'memory-os';
const sessionId = 'handoff-session-1';
const taskId = 'handoff-1';
await claude.taskStart('Review the deployment adapter', {
source: 'claude', sessionId, taskId, scope,
});
const decision = await claude.recordDecision(
'Use the hosted network MCP transport for remote agents.',
{ source: 'claude', sessionId, taskId, scope },
);
if (!decision.shouldCapture) {
throw new Error('Decision was not captured: ' + decision.reason);
}Recallし、修正してtaskを閉じる
MCP recall_contextはmemory:readを必要とする、範囲を限定したmulti-memory context packです。SDKのrecallContext methodはPOST /v1/recall/contextを呼び出し、構造化されたJSON objectを返します。Codexはどちらのsurfaceでもreadを行い、その後既存のSDK helperでbug fixとtask closeを実行できます。
const context = await codex.recallContext(
'deployment adapter decision and current bug',
{ scope, maxItems: 6, maxTokens: 1200, preferWorking: true },
);
await codex.recordBugFix(
'Fixed streamable-http token identity fallback.',
{ source: 'codex', sessionId, taskId, scope },
);
await codex.taskEnd(
'Deployment adapter fix completed for handoff.',
{ source: 'codex', sessionId, taskId, scope },
);
console.log(context.version, context.items);同等のMCP read
Public MCP surfaceでは、既存のunderscore形式のtoolとpublic snake_case argumentであるquery、max_items、max_tokensを使います。接続済みprofileが認証済みownerとagent identityを提供し、serverは返却itemにagent boundary objectを注釈します。max_itemsとmax_tokensがcontext pack全体を制限します。toolは### XMemo Contextで始まるpublic text responseを返します。
recall_context({
query: "deployment adapter decision and current bug",
max_items: 6,
max_tokens: 1200
})contentだけでなくboundary fieldも読む
Recall resultには既存のagent boundary objectが注釈として付きます。Codexがagent_id=claudeで書かれたmemoryを読む場合、relationとownershipはother_agentです。論理的なagent_idが同じでもinstallation hashが異なる場合、relationはsame_agent_other_instanceになります。agent_idとagent_instance_id_hashの両方が一致するとselfです。boundary_authorityはattribution_onlyのままで、identity sourceがtoken-boundの場合だけcurrent_agent_trustがtoken_boundになり、それ以外はclient_assertedです。
{
"relation": "other_agent",
"ownership": "other_agent",
"current_agent_id": "codex",
"current_agent_trust": "client_asserted",
"boundary_authority": "attribution_only",
"memory_agent_id": "claude",
"explanation": "memory agent_id differs from this caller"
}同じscopeと範囲を限定したqueryで再開する
Claudeのfollow-up recallは同じ認証済みaccountとscopeを使いますが、独自のagent_idとagent_instance_idを使います。memoryが共有されるのは、callerのcredential、memory:read scope、owner boundary、要求されたretrieval filtersが許可する範囲だけです。Agent boundary labelはattributionの証拠であり、authorizationを回避する手段ではありません。
recall_context({
query: "deployment adapter decision, Codex fix, and handoff status",
max_items: 6,
max_tokens: 1200
})
# Inspect the returned context and boundary summary before continuing.