Handover is a platform for assembling agentic applications from composable parts: MCP resources, small-LLM skills, frontier agents, lifecycle hooks, scheduled quests. Multi-tenant, your data and credentials stay yours. Currently in private preview.
In Infinity War, Doctor Strange searched 14,000,605 futures for the one where the Avengers won. Building an agentic app is the same problem at smaller scale — a search through a space of compositions. Three layers, named and reusable; the lower layers don't know about the higher, so you can rewire freely as you find the path that ships.
An MCP server you mount — stdio command or SSE endpoint. Tools are auto-discovered and made callable. This is where raw capability lives.
filesystem · gmail · slack · …A small-LLM agent with a system prompt and a set of bound resources. From the outside it's a single tool with a typed interface — its inner agent loop is hidden.
research_topic(query, depth)A frontier-model agent that composes skills and direct resources to handle the task. Top-level — runs in chat sessions or quest runs.
Claude · GPT · Gemini · …Hidden complexity, exposed contracts. A skill that uses three resources still presents one tool. An agent that pulls from a dozen skills still talks like a single chatbot. Each layer is a black box to the layers above it — composition without leak.
Domain experts who know their problem can compose agentic apps on Handover in an afternoon. Resources reuse across apps, skills compose into agents, hooks chain, quests schedule — when the parts are this composable, building one is mostly choosing. What used to be a six-month roadmap becomes a week’s work, and the next one is even faster.
An App is a tenant-scoped project: a coherent bundle of agents, skills, resources, hooks, scheduled quests, secrets, and variables that together make one agentic application. Browse, edit, export — same shape every time.
A resource lives in your tenant once and joins as many apps as you want. No duplication. The Default app is the shared pool; project apps inherit from it via fallback.
A quest is a task definition: prompt, capability requirements, optional cron. The matcher routes it to a capable agent — or pin it to a specific one with assigned_agent_id.
Every agent gets a chat surface. Sessions are durable — close the tab, come back, the conversation picks up exactly where it left off.
Wrap any entity with before/after hooks: redact PII, fetch a token, write an audit row, abort on guardrail breach. Hooks chain results into a shared context for downstream stages.
A tour of the Lead Gen example app — five agents, five skills, five MCP resources, four scheduled quests, two custom models, two hooks. Everything one outbound product needs, all in one place.






${{ }} chips show resolved references.
Resources, skills, agents, hooks — every layer has a Test endpoint that runs it in isolation against a mock context. Change one without breaking the others. Sweep the parameter space yourself, or point a tuning agent at it. Production isn’t a black box; it’s a continuous improvement loop with three knobs.
Lower latency, fewer tool calls, smaller agent loops where they don’t earn their keep.
Smaller models for the right skills, fewer tokens per turn, hook batching — without giving up correctness.
Eval scores, structured-output adherence, agent agreement rate — measured per layer, tuned per layer.
${{ secrets.NAME }} and ${{ vars.NAME }} work in any field that takes a string — resource env vars, MCP server URLs, hook argument templates, custom-model API keys.
At run start, the resolver looks up names in (current app, Default app) with current winning. Secrets are encrypted at rest. Variables are plaintext by design — for things like SENDER_DOMAIN that aren’t secrets.
Audit by name only. Each run emits a single event: this run consumed OPENAI_API_KEY. Names go in the log; values never do, anywhere.
# env_vars GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} USER_AGENT: "handover-bot" # headers X-Org: ${{ vars.ORG_SLUG }} Authorization: Bearer ${{ secrets.GH_TOKEN }}
Every external integration is a Model Context Protocol server. Tools are auto-discovered with typed schemas, no custom adapter code per integration. The MCP ecosystem is your ecosystem.
Tenants are the security boundary; nothing leaks across. Secret values are encrypted at rest and never enter logs — only their names appear in audit trails. Designed to scale horizontally so a tenant’s load never affects another’s.
Export an entire app as YAML — agents, skills, resources, hooks, quests, variables, and secret names (never values). Re-import into a different tenant or environment. Templates are just bundles.
Conversations are server-side persistent — close the tab and the session resumes exactly where it left off. Group-chat attribution: each user’s display name rides along on every turn so the agent can tell speakers apart.
Layered events stream as the agent works — agent layer, skill layer, resource layer, hook layer. Cancel a run mid-flight, and runs survive process restarts so nothing is lost mid-execution.
A quest declares the skills and resources it needs; the platform routes it to any capable idle agent. Or pin it to one specific agent and skip routing entirely.
Attach before/after hooks to any entity. Hooks call MCP tools with templated arguments and chain results through a shared context. Auth flows, audit trails, content filtering — all just hooks.
Tag any entity. Filter list pages, scope YAML exports, build dashboards. Tags stay descriptive — Apps stay structural. Different jobs.
Every entity in an app serializes to a single YAML bundle — the app's tags, resources, skills, agents, hooks, quests, variables (with values), and secrets (by name only).
Re-import into a new tenant or environment. The diff preview tells you exactly what would change before anything commits. Imported secrets land "unfilled" — the operator fills them in once and the app starts working.
Treat apps like packages. Version them in git, ship them between environments, give them to teammates as a starter template.
app: name: Lead Generation slug: lead-gen resources: - name: Slack env_vars: SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }} secrets: # names only - name: SLACK_TOKEN - name: OPENAI_API_KEY variables: - name: SENDER_DOMAIN value: acme.com
Handover is in private preview. Tell us about your use case — the agents you want to ship, the resources you’d wire up, the team you’d run it for — and we’ll get back to you.