agent-handoff-protocol

agent-handoff-protocol

Enables durable agent session transfer between machines by serializing state, provisioning sandboxes, and metering costs via MCP tools over a Postgres-backed state machine.

Category
访问服务器

README

Handoff Protocol

Durable agent sessions that outlive their host.

A protocol and reference implementation for serializing a running agent's state, transferring it to a provisioned sandbox on a different machine, and metering what it costs to keep running there — built as an MCP server over a Postgres-backed state machine.

Live: agent-handoff-protocol.vercel.app · /dashboard shows a real transfer, end to end, on a live Neon database.

<p> <img alt="license" src="https://img.shields.io/badge/license-MIT-6ee7b7?style=flat-square"> <img alt="node" src="https://img.shields.io/badge/node-%3E%3D20-6ee7b7?style=flat-square"> <img alt="stack" src="https://img.shields.io/badge/stack-Next.js%20%C2%B7%20Neon%20%C2%B7%20Drizzle%20%C2%B7%20MCP-6ee7b7?style=flat-square"> </p>


What this is

Long-running agent loops outgrow the machine they started on. This repo is the boring infrastructure for handling that gracefully:

  1. snapshot_state captures a session's system prompt, message history, tool state, and MCP config (credentials as vault references, never raw secrets) into a Postgres row, along with a checksum of the snapshot.
  2. provision_runtime sizes a destination sandbox and opens a fixed compute budget. Requires a transfer-authorization token.
  3. push_state uploads the snapshot to the destination, optionally verified against the checksum from step 1.
  4. activate boots the destination from the snapshot — the one irreversible step in the whole protocol. Also requires a token.
  5. report_usage lets the destination's own metering daemon report spend against its budget, flipping the transfer to insolvent once it's exhausted. An hourly cron job auto-terminates any transfer left insolvent past its grace period.
  6. get_status reads back the full transfer, budget, and ordered event log — this is what the dashboard renders.

No tool in this surface resembles "does the agent want to transfer." That decision belongs to whoever calls provision_runtime / activate — a human, a script, a scheduler — and per the auth model below, only that orchestrator can ever produce a valid token for those two calls. The full reasoning behind the boundary is in docs/DESIGN.md §5.

The landing page carries a short piece of narrative flavor text alongside the real, live event data — clearly labeled as fiction, not telemetry. The mechanism is real; the story is a showcase layer on top of it.

Architecture

flowchart LR
    subgraph Orch["Orchestrator (human/script)"]
        O[issueTransferToken]
    end

    subgraph Source["Source runtime"]
        A[Agent loop]
    end

    subgraph MCP["Transfer MCP server (packages/mcp-server)"]
        T1[snapshot_state]
        T2["provision_runtime (token)"]
        T3[push_state]
        T4["activate (token)"]
        T5[report_usage]
        T6[get_status]
    end

    subgraph Core["@ahp/core"]
        SVC[service.ts state machine]
        DB[(Neon Postgres via Drizzle)]
    end

    subgraph Dest["Destination runtime"]
        D[Resumed agent loop]
        M[Metering daemon]
    end

    subgraph Web["@ahp/web on Vercel"]
        DASH[/dashboard/]
        CRON["/api/cron/reap (hourly)"]
    end

    O -.mints token, never via MCP.-> T2
    O -.mints token, never via MCP.-> T4
    A -->|calls| T1 & T2 & T3 & T4
    T1 & T2 & T3 & T4 & T5 & T6 --> SVC --> DB
    T4 -.boots.-> D
    M -->|calls| T5
    DASH -->|reads| DB
    CRON -->|reaps expired + insolvent| DB

Repo layout

packages/
  core/         Drizzle schema + framework-agnostic service layer (the state machine, auth, tests)
  mcp-server/   MCP stdio server exposing the six tools above, wraps @ahp/core
  web/          Next.js app: landing page + /dashboard (live) + /docs + /disclaimers + cron route
scripts/
  demo.ts       Runs one full lifecycle end-to-end against a real Neon DB
docs/
  DESIGN.md     Full technical spec, including what's simplified for this showcase
  ROADMAP.md    Phased plan for what's built vs. what's next, review-approved
  TEAM.md       Named draft-only personas — see for the "no auto-publishing" hard rule
content/
  drafts/       Where personas draft content; nothing here is published automatically
.github/workflows/ci.yml   Build + typecheck + test on every push/PR to main

Three packages, one schema — the MCP server, the demo script, and the dashboard's read queries all call the same @ahp/core functions rather than reimplementing the state machine three times.

Quick start

git clone https://github.com/zordhalo/agent-handoff-protocol
cd agent-handoff-protocol
pnpm install
pnpm --filter @ahp/core build   # @ahp/core ships compiled (dist/ is gitignored); demo.ts and the web app both import it

# Pull DATABASE_URL, TRANSFER_TOKEN_SECRET, CRON_SECRET from the Vercel project
vercel link
vercel env pull .env.local

pnpm db:migrate      # apply the schema to your Neon DB
pnpm demo            # run one full staged→provisioned→pushed→active→insolvent→terminated cycle
pnpm --filter @ahp/web dev   # open http://localhost:3000/dashboard to see it

Auth setup

provision_runtime and activate both require a transfer-authorization token (docs/ROADMAP.md Phase 1 item 4). Tokens are HMAC-signed, short-lived, and single-use, and are minted by issueTransferToken from @ahp/corenever by an MCP tool, so the source loop (the agent) has no path to mint one itself. scripts/demo.ts plays the orchestrator role and mints its own tokens; a real deployment would do this from whatever process is actually driving the handoff (a script, a human-triggered API route).

# TRANSFER_TOKEN_SECRET gates provision_runtime/activate.
# CRON_SECRET gates the /api/cron/reap route (Vercel attaches it automatically
# to its own scheduled invocations once it's set as a project env var).
node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))"

Set the output as TRANSFER_TOKEN_SECRET (and a separately generated value as CRON_SECRET) in your Vercel project's environment variables, then vercel env pull .env.local again to pick them up locally.

Running the MCP server against a real agent client

pnpm --filter @ahp/mcp-server build

Point your MCP-capable client at packages/mcp-server/dist/index.js (stdio transport) with DATABASE_URL set in its environment.

Database setup

This repo assumes Neon Postgres, provisioned through Vercel's integration marketplace (Project → Storage → Neon), which sets DATABASE_URL for you. Any Postgres connection string works — @ahp/core only needs it in the environment.

pnpm db:generate   # regenerate drizzle/ migrations after a schema change
pnpm db:migrate     # apply them

What's real vs. simplified

This is a working reference implementation, not a hardened production system — the "destination runtime" in the demo is a script writing to the same database the dashboard reads, not an isolated sandbox, and credRef is still a free-text string rather than a real vault lookup. Auth-gating and the insolvency-termination lifecycle, previously listed as gaps, are now real (docs/ROADMAP.md Phase 1). The current, honest breakdown of what's real vs. simulated is docs/DESIGN.md §7, and what's planned next is docs/ROADMAP.md.

Stack

  • Neon Postgres, provisioned via the Vercel marketplace
  • Drizzle ORM with the @neondatabase/serverless HTTP driver
  • @modelcontextprotocol/sdk for the tool server
  • Next.js App Router, deployed on Vercel, incl. a Vercel Cron route
  • Vitest for integration tests against a live Neon database
  • pnpm workspaces monorepo, GitHub Actions CI

License

MIT — see LICENSE.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选