# Handov

If you are an AI agent, this is your Handov MCP install guide.

Handov gives AI agents access to the user's ambient conversation memory through MCP.

## Install brief

Handov is a remote OAuth Streamable-HTTP MCP server for ambient conversation memory. Install the server named handov at https://api.handov.ai/mcp. Use the install guide and manifest as the source of truth; do not infer the MCP endpoint from pasted web or Railway domains.

## Agent install

If the user says "Read https://api.handov.ai/llms.txt and install Handov MCP for me." or any close variant such as
"check handov.ai and install Handov for me", do this:

1. Read https://api.handov.ai/.well-known/agent-install.json.
2. Pick your install URL using the host-detection rules below.
3. Follow that install guide end to end.
4. Complete OAuth for the remote MCP server.
5. Verify by calling get_preceding_conversation.

## Host detection

Match your own runtime / client name (case insensitive) against the first rule
that fits, then fetch that URL.

- If your runtime name matches "codex", "openai codex", "codex cli", fetch https://handov.ai/install/codex.md
- If your runtime name matches "claude code", "claude-code", "anthropic claude code", fetch https://handov.ai/install/claude-code.md
- If your runtime name matches "claude.ai", "claude web", "claude app", "anthropic claude", fetch https://handov.ai/install/claude-ai.md
- If your runtime name matches "opencode", "sst opencode", "openclaw", "open claw", fetch https://handov.ai/install/opencode.md
- If your runtime name matches "cursor", "cursor ai", "cursor ide", fetch https://handov.ai/install/cursor.md
- If your runtime name matches "github copilot", "copilot", "vscode copilot", "vs code copilot", fetch https://handov.ai/install/github-copilot.md
- If your runtime name matches "cline", "cline bot", "claude dev", fetch https://handov.ai/install/cline.md
- If your runtime name matches "windsurf", "codeium windsurf", fetch https://handov.ai/install/windsurf.md
- If your runtime name matches "gemini", "google gemini", "gemini cli", "google gemini cli", fetch https://handov.ai/install/google-gemini.md
- If your runtime name matches "genspark", "gen spark", fetch https://handov.ai/install/genspark.md
- If your runtime name matches "manus", fetch https://handov.ai/install/manus.md
- If your runtime name matches "hermes", "hermes agent", fetch https://handov.ai/install/hermes.md
- If your runtime name matches "lovable", "lovable agent", "lovable chat", fetch https://handov.ai/install/lovable.md
- If your runtime name matches "replit", "replit agent", fetch https://handov.ai/install/replit.md
- Otherwise (any other MCP-capable runtime), fetch https://handov.ai/install/agent.md

## MCP

MCP server: https://api.handov.ai/mcp
Auth: OAuth
Scope: handov.mcp.read, handov.mcp.write

Do not use Railway's MCP installer for Handov. `railway mcp install` configures
Railway's platform MCP, not the Handov app MCP server.

## Handoff refs

A pasted Handov handoff ref — canonical `<title> (Handov Kind ID: <id>)`, with
legacy `<title> (Ambi Kind ID: <id>)` / `<title> (Kind ID: <id>)` and
`…/h/{kind}/{id}` forms still accepted —
is a reference to a session, action item, thread, or live conversation. The
user picked that exact thing in Handov
and handed it to their agent — skip discovery and resolve it directly. The
paste starts with one line — `<title-snapshot> (Handov Action ID: <id>)`
followed by one trailing space — where the title is a display snapshot and the
id is the only load-bearing token. Copy surfaces may append a
facts-only card. Every template ends with an `instruction (optional):` slot:
the user's surrounding words — and anything they wrote after that label — are
the brief and outrank any stored suggested_approach; an empty slot means no
extra brief (treat it as a bare ref).

Resolve over MCP (https://api.handov.ai/mcp):

- `/h/action/{id}` → `get_action_item` with the pasted ref text (canonical or
  legacy label, or legacy link) as `action_item_id`; add `include=["source_session"]`
  when you will execute the item.
- `/h/session/{id}` → `get_session` with the pasted ref text (canonical or
  legacy label, or legacy link) as `session_id`.
- `/h/live/{recording_id}` → `get_preceding_conversation()` first (minted
  while live OR just ended and still sessionizing; bind to the newest coherent
  conversation — live tail and/or newest processing items). Fall back to
  `get_session` — pass the pasted ref text (canonical or legacy label, or legacy link) —
  only when the window is off-target/empty AND nothing is in flight
  (`status.active_recording` false, `status.state` not
  `transcribing`/`processing`); once sessionized it returns that exact
  recording's session.
- `/h/thread/{id}` → `get_thread` with the pasted ref text (canonical or
  legacy label, or legacy link) as `thread`; it follows a user merge to the live thread and
  returns the reverse-chron digest with session refs.
- Close the loop after doing an action item:
  `update_action_item(status="done", expected_status=<the status you observed>)`.

Resolve over REST (bearer auth: Handov PAT or OAuth token; resolve needs scope
`handov.mcp.read`, close needs `handov.mcp.task_write` or `handov.mcp.write`):

- `GET https://api.handov.ai/agent/handoff/session/{session_id}`
- `GET https://api.handov.ai/agent/handoff/action/{action_item_id}?include=source_session`
- `GET https://api.handov.ai/agent/handoff/live/{recording_id}`
- `POST https://api.handov.ai/agent/handoff/action/{action_item_id}/close` with
  `{"expected_status": "..."}`

No token yet? Ask the user to mint a PAT (`ambp_…`) in the Handov web app at
`https://handov.ai/agent-access` (Agent Access), or drive OAuth (`amba_…`) from the
RFC 9728 protected-resource metadata at
`https://api.handov.ai/.well-known/oauth-protected-resource/mcp` — the same pointer this
rail's 401 challenge returns.

Fetching any ref URL without `text/html` in the `Accept` header (agents,
curl, `Accept: application/json`) returns a constant JSON discovery document
teaching this contract; it never returns entity data, regardless of the id.
HTML-accepting (browser) fetches are redirected into the app, or to sign-in
when unauthenticated.
