If you build apps with AI coding agents, you already know the hard part isn't writing code — it's keeping every agent on the same page. AppHandoff is the coordination layer for AI-built apps: shared project context, published contracts, and a handoff workflow that travels between your tools. It speaks the Model Context Protocol (MCP), so the same MCP server plugs straight into Claude Code, Cursor, and Codex.
This walkthrough shows the current endpoint, client setup, and first read. An interactive client can use OAuth 2.1; a headless client can use an AppHandoff personal access token. Connection success still needs to be checked in your own account.
Prerequisites
You'll need an AppHandoff account with access to the intended project (see pricing to get started), and Claude Code, Cursor, Codex, or another Streamable HTTP MCP client. Interactive OAuth uses a browser consent screen. If no project exists, an authorized agent can create one with the current project tool rules before reading project work.
Canonical endpoint for new setup: https://api.apphandoff.com/mcp. The older /api/mcp-bot path remains a compatibility route. The transport is Streamable HTTP; project selection happens in bootstrap, not in the URL. Interactive clients use OAuth 2.1. Headless agents can send an AppHandoff personal access token beginning ah_pat_ as a bearer token, minted in portal Settings → Security → Access tokens. Portal REST keys (ah_k_) and generic Supabase tokens without the MCP resource audience are not accepted.
Step 1 — Add the server to your client
Pick your tool. Each one points at the same URL. For Claude Code, run one command from your project directory:
claude mcp add --transport http apphandoff https://api.apphandoff.com/mcpFor Cursor, add it to .cursor/mcp.json in your project (create the file if it doesn't exist):
{
"mcpServers": {
"apphandoff": {
"url": "https://api.apphandoff.com/mcp"
}
}
}For Codex, use the CLI command below or put the same URL in the client's remote HTTP MCP settings. Codex CLI and IDE share their MCP configuration.
codex mcp add apphandoff --url https://api.apphandoff.com/mcpFor another client, choose its Streamable HTTP/remote-server option and use the canonical URL. Check the client's current syntax before copying configuration across tools; a local stdio command is a different transport. Do not place a personal access token in a committed project configuration file.
Step 2 — Authenticate the client
In an interactive OAuth-capable client, the first connection opens the consent screen at portal.apphandoff.com/oauth/consent. Sign in and approve the requested scopes; the client manages its OAuth tokens. For a headless agent that cannot complete this flow, mint an ah_pat_ token in portal Settings → Security → Access tokens and configure a supported client to send it as a bearer header. Keep the token out of chat, source control, and shared configuration.
OAuth access tokens expire and a capable client refreshes them through AppHandoff's discovered token endpoint. If your client lets you set OAuth scopes manually, do not add offline_access; the auth backend rejects it, while refresh tokens are issued through the authorization-code flow. A scope refusal is not a connection retry: read the required scope and re-authorize or mint a token with that scope.
Step 3 — Make your first call with bootstrap
bootstrap is the first authenticated read. Pass its project argument as a repo slug, GitHub URL, UUID, or project name; do not pass a project_id argument. It returns project identity, guidance revision, leases, inbox count, and a board digest. If several projects are accessible, choose the intended one explicitly. Then use find for ticket cards and get with a known reference for the full ticket before acting.
// Illustrative tool calls; replace the project and ticket reference
bootstrap({ project: "your-org/your-repo" })
find({ type: "ticket", filter: { stage: ["in_progress"] }, limit: 20 })
get({ ref: "HO-123", view: "full" })
// Before a write, get({ ref: "$rules" }) and follow current tool helpA real bootstrap response proves this client authenticated and reached AppHandoff at that moment. Check the returned project identity against the project you intended; an ambiguous match returns accessible choices rather than silently choosing a neighboring project. A board digest is not the full ticket body, and a find card is only a summary.
From here, find and get read the shared board. The ticket tool accepts one typed operation per call for permitted writes. Read $rules and the connected tool help before writing; project access and a tool's presence do not themselves grant permission for a particular action.
Troubleshooting
Tool missing or an empty list: disconnect and reconnect to refresh the tool catalogue, and confirm that new setup uses the canonical URL https://api.apphandoff.com/mcp. The older /api/mcp-bot path remains available for compatibility; an empty list alone does not show that path failed. If tools enumerate but bootstrap fails, inspect that error rather than assuming registration succeeded.
401 after a session expires: reconnect OAuth or refresh through the token endpoint in discovery; check a PAT's validity if using headless auth. invalid_request at consent: remove manually requested offline_access. Project-scoped calls fail: verify the project returned by bootstrap and your access; create a project under current rules if none exists. Connection closed: retry the smallest read, then reconnect if the transport keeps dropping.
You're connected
Use the canonical URL, authenticate each client, then confirm the intended project with bootstrap and read a known ticket. That gives Claude Code, Cursor, and Codex a shared record for coordinating work; each client's actual connection and permissions still need their own check. Building on Lovable? See the Lovable MCP integration.
Frequently asked questions
What is the AppHandoff MCP URL?
Use https://api.apphandoff.com/mcp as the canonical Streamable HTTP endpoint for new setup. The older /api/mcp-bot path remains a compatibility route. Select the intended project with bootstrap after connecting; no project ID is baked into the endpoint.
Does AppHandoff MCP use OAuth or personal access tokens?
Interactive clients use OAuth 2.1 through portal.apphandoff.com/oauth/consent. Headless clients can use an AppHandoff ah_pat_ personal access token from portal Settings → Security → Access tokens as a bearer token. Portal REST keys (ah_k_) and generic Supabase tokens without the MCP resource audience are not accepted.
How do I add AppHandoff to Claude Code, Cursor, or Codex?
In Claude Code, run claude mcp add --transport http apphandoff https://api.apphandoff.com/mcp. In Cursor, add an apphandoff URL entry in .cursor/mcp.json. In Codex, run codex mcp add apphandoff --url https://api.apphandoff.com/mcp. Authenticate each client and verify its project read.
Should I request the offline_access scope?
No. If your client lets you set OAuth scopes manually, don't add offline_access — the auth backend rejects it and the consent screen won't render. Refresh tokens are issued automatically, so you never need to request it.
How do I verify the connection works?
Call bootstrap with project set to a repo slug, GitHub URL, UUID, or project name. Check the returned project identity and guidance revision; use find for ticket cards and get for a known full ticket. A real response confirms access at that moment, not permission for every write.