# Handover

> An open JSON format and local toolchain for carrying an AI assisted project's working state between agents, tools and model providers.

- **Type:** MCP server
- **Install:** `agentstack add mcp-nativesoil-handover`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [nativesoil](https://agentstack.voostack.com/s/nativesoil)
- **Installs:** 0
- **Category:** [Integrations](https://agentstack.voostack.com/c/integrations)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [nativesoil](https://github.com/nativesoil)
- **Source:** https://github.com/nativesoil/handover
- **Website:** https://nativesoil.dev

## Install

```sh
agentstack add mcp-nativesoil-handover
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Soil Handover

[](https://github.com/nativesoil/handover/actions/workflows/ci.yml)
[](.github/workflows/ci.yml)
[](docs/compatibility.md)
[](LICENSE)

**Your AI knows your project. Until you change tools.**

Detailed diagram description

The cover of the Soil Handover repository. On an off-white ground, the Native
Soil wordmark sits above the tagline pair: your AI knows your project, until
you change tools. Below, two carbon terminal panels stand on layered ground
that is split by a break between them. In the left panel the command soil save
stores handover 001, checked on save and scanned for secrets; in the right
panel the command soil load brings it back in another tool or another model,
and the session continues from there. The layers of the ground stop at the
break. One
deep green seam is the only layer that crosses it, marked by small green seed
blocks, and where it crosses it carries a white card stamped handover.json.

Soil Handover is an open JSON format and local toolchain for carrying the
working state of an AI-assisted project between agents, tools and model
providers. It preserves decisions and their reasons, constraints, rejected
approaches, the current task and the next step in a human-readable,
machine-validated document.

Open format · Local by default · No account or telemetry required

**[Build and try the developer preview →](#build-and-try-the-developer-preview)**

[Build an implementation](spec/README.md) ·
[Connect an MCP client](docs/quickstart.md) ·
[Run the team server](docs/server.md) ·
[Hosted service](https://nativesoil.dev)

## What a handover looks like

A real subset, from
[docs/examples/readme-example.json](docs/examples/readme-example.json); the
full document has 17 sections and validates against the schema on every test
run. Every section declares its status, so a section the thread never covered
is a visible gap, not a silent omission.

```json
{
  "soilHandover": "1.0",
  "projectId": "orchard-checkout",
  "title": "Checkout rework: payment retry design",
  "sections": {
    "decisions": {
      "status": "available",
      "summary": "The address is kept in the server session, so a declined card re-mounts the payment widget with the address intact. Locked because the current code returns the subscriber to an empty form, and re-entering everything is where retries are abandoned."
    },
    "constraints": {
      "status": "available",
      "summary": "Card data never touches Orchard's servers. The hosted widget stays the only place card details are entered. This is a compliance boundary, not a preference."
    },
    "currentTask": {
      "status": "available",
      "summary": "Designing the payment retry path: about half done, the session shape is agreed, the re-mount behaviour is not written yet. Next step: write the decline message, because the founder wants to review that string before the logic lands."
    },
    "rejectedPaths": {
      "status": "missing",
      "summary": null
    }
  }
}
```

## Build and try the developer preview

Nothing here is on a package registry yet; installation becomes one line at
the first release. Today, from the root of a checkout of this repository:

```bash
pnpm install && pnpm build

# 1. print the recipe and paste it into the session you want to keep
node packages/cli/bin/soil.js save

# 2. the model answers with one JSON block. paste it back:
node packages/cli/bin/soil.js save -

# 3. anywhere else, in another tool or model:
node packages/cli/bin/soil.js load '#001'
```

Step 3 prints a paste-ready restore prompt: paste it into the new session and
keep working. Your handovers are in `~/.soil/handovers/`, one JSON file each,
readable with `cat`: if this repo vanished tomorrow they would still be
readable, which is rather the point.

Every save answers with a receipt. Gaps are stated, never hidden, and so is
what was held back on purpose. This is the real output of
`soil save examples/orchard-checkout.json`, checked against the renderer by
`scripts/check-cards.mjs`:

```
  ┌─ SOIL · handover saved ──────────────────── #001 ─
  │
  │   Checkout rework: address step split, payment
  │   retry pending
  │   orchard-checkout
  │
  ├─ written by ──────────────────────────────────────
  │
  │   client      claude-code
  │   model       opus-4.8
  │   provider    anthropic
  │   recipe      1.0.0
  │
  ├─ what this document carries ──────────────────────
  │
  │   17 / 17 sections carrying content
  │   provenance  repo_verified, user_locked_memory,
  │               model_reported, owner_observed
  │
  ├─ stated gaps ─────────────────────────────────────
  │
  │   ▸ Conversion numbers since Monday's
  │     address-step deploy had not accumulated at
  │     capture, so the effect of that deploy is
  │     unknown.
  │   ▸ The payment provider's documented behaviour
  │     on widget re-mount after a decline could not
  │     be confirmed, because the sandbox was
  │     returning intermittent errors.
  │
  ├─ unresolved contradictions ───────────────────────
  │
  │   ▸ The bundle ceiling is described as 180 KB
  │     gzipped in the project notes and as 'about
  │     175' in an earlier conversation. The
  │     stricter figure is used here; the exact
  │     number was not re-confirmed.
  │
  ├─ held back · by design ───────────────────────────
  │
  │   ▸ Payment provider API credentials exist and
  │     are set as environment variables in the
  │     deployment platform. Values withheld.
  │   ▸ The delivery partner webhook signing secret
  │     exists and is configured in the deployment
  │     platform. Value withheld.
  │
  ├─ local ───────────────────────────────────────────
  │
  │   stored on this machine · no account · no
  │   network
  │
  └─ load it in another thread, model, or tool

          ❯ soil load #001
```

The worked example, end to end, is in [`examples/`](examples/README.md), and
[docs/quickstart.md](docs/quickstart.md) carries on from here.

> **Open source and hosted service.** This repository is the open format and
> tools, and works entirely locally. Native Soil Cloud is the optional hosted
> service; [nativesoil.dev](https://nativesoil.dev) is where to read about
> that one, and nothing in this repository calls it, needs it, or degrades
> without it.
>
> **Soil Handover** is the open format and everything in this repository.
> **`soil`** is the command.
> **Native Soil Cloud** is the optional hosted service from Native Soil (the
> brand and company).

## Why a handover, not a transcript?

A session fills up, compacts or ends, and the work moves: another tool,
another model, a teammate. A transcript preserves what was said, not which
decisions are current or why constraints bind. A summary is smaller, and
compression drops the reasons first: "use X" survives, "use X because Y failed
under load, and do not reopen Z" often does not. A decision without its reason
is a decision waiting to be relitigated.

So a handover extracts the working state into named sections: decisions keep
their reasons, rejected approaches keep what failed, constraints keep why they
bind, current work keeps its blockers and next step, and what still holds is
kept structurally apart from what was only true at the capture. Gaps are
declared, never hidden. Memory features sit on the other side of this
boundary: memory helps an agent remember inside one system, Soil Handover
moves the working state between systems.

Detailed diagram description

How context moves, left to right. One session in one client, on one model: the
command soil save captures the work, the decisions and the reasons behind
them, and stores handover 001. In the centre, what crosses: handover.json, a
document that declares all 17 sections, even the empty ones, among them
decisions with their reasons, constraints and why they bind, rejected paths
and what failed, the current task and the next step, and the restore
instructions, the boot prompt the next model reads first. On save the document
is validated against the schema and scanned for credential-shaped values and
private paths; a document that fails either gate is not stored, and gaps are
declared rather than hidden. On the right, another session in another client,
on another model: soil load brings handover 001 back as the restore prompt,
nothing has to be re-explained, and the work continues from there.

The whole move in one picture: one session saves, the document crosses,
another session continues.

The full argument, including drift and the context ghost, is in
[docs/concepts.md](docs/concepts.md).

## How it works

Detailed diagram description

Where a handover lives, left to right. The AI clients as plain text names on a
layered ground, because behind every client runs a model, from any provider:
Claude Code, Codex CLI, Cursor and VS Code run on your machine; ChatGPT,
Claude, Lovable and v0 live in a browser or a phone app. In the centre, your
computer, the default place: the soil command line and a local MCP server your
client starts as a process, writing one plain JSON file under a home
directory, readable with cat, and after install this route needs no account,
no network and no telemetry. On the right, the two optional servers: the
self-hostable preview from this repository, on hardware you own with bearer
tokens your operator hands out, and Native Soil Cloud, the hosted service with
accounts, which is how the browser and phone clients connect and which nothing
in this repository calls or needs. Three numbered routes connect them: the
local round trip, your team's server over HTTP, and the hosted route. A client
in a browser or on a phone has only the hosted route; a client on your machine
is not limited to the local one. Every route reads and writes the same
document.

Two kinds of client, three routes, one document; the hosted route is
[Native Soil Cloud](https://nativesoil.dev), and the other two are in this
repository. Every route is the same three steps:

1. **Capture.** The extraction recipe asks the model for the working state as
   one JSON block: decisions with their reasons, constraints, rejected paths,
   the current task and the next step.
2. **Validate and store.** Every save is validated against the schema and
   scanned for credential-shaped values and private paths; a document that
   fails either gate is not stored. Pattern-based scanning reduces risk; it
   cannot identify every possible secret.
3. **Restore elsewhere.** A load renders the stored document as a paste-ready
   restore prompt for a new session, in another tool or on another model.
   [docs/switch-clients.md](docs/switch-clients.md) shows the switch as real
   transcripts, in both directions.

## Choose your integration

| You want                               | Use                                                               | Where                                                             |
| -------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- |
| A save and a load in your terminal     | The `soil` CLI                                                    | [docs/quickstart.md](docs/quickstart.md)                          |
| Your AI client to save and load itself | The local MCP server: `soil_save`, `soil_load`, `soil_list`       | [docs/quickstart.md](docs/quickstart.md)                          |
| An agent to do the install for you     | The agent-readable install instruction                            | [docs/install-with-an-agent.md](docs/install-with-an-agent.md)    |
| A shared server for your team          | The self-hostable server preview                                  | [docs/server.md](docs/server.md)                                  |
| The managed service                    | Native Soil Cloud: accounts, sync, shared team projects, support  | [nativesoil.dev](https://nativesoil.dev)                          |
| To build on the format                 | Five SDKs held to one conformance contract, and the specification | [`spec/`](spec/README.md) · [conformance/](conformance/README.md) |

A client that runs only in a browser or a phone app cannot start a local
process; those clients connect through the hosted connector, and
[docs/compatibility.md](docs/compatibility.md) says which clients that
covers. Runnable examples beside LangGraph, Mem0, Letta and Block buzz are
in [examples/](examples/README.md), with per-client connection pages in
[examples/clients](examples/clients/README.md).

## Status and compatibility

Eight surfaces ship in this repository and run on your own machine: the local
CLI, the local MCP server and the self-hostable server (preview), and five
SDKs held to one conformance contract. Every one of those rows is backed by an
artefact in this repository that reproduces it, in continuous integration on
three operating systems. Claude Code (CLI) and Codex (CLI) have recorded
sessions against the local MCP server, with the session reports committed
here.

The third-party client surfaces are a separate list with separate evidence. Of
the seventeen client rows, two are real runs with session reports committed
here, ten rest on the maintainers' internal log for runs through the hosted
Native Soil connector, and five rest on documentation or a reading of source,
never a run. Installing this repository gives you none of the hosted rows.

The complete compatibility and evidence matrix, every row with how it was
proven and when, is in [docs/compatibility.md](docs/compatibility.md).

## Maturity

Three dimensions, separately honest: **format contract, frozen for 1.x** ·
**implementation, public preview (0.2.0)** · **conformance, passing (five
implementations)**. The specification is versioned independently from the
tooling: Specification 1.0 is frozen for the 1.x line, and the CLI and SDK
packages remain pre-1.0 while their distribution and APIs mature.

Now: portable handovers, local CLI/MCP, deterministic checking and a
self-hosted server preview. Next: published packages and server hardening.
Out of scope: merging and accumulated project memory.

Each claim has an artefact behind it, one link deep:
[docs/format.md](docs/format.md) explains the document,
[spec/versioning.md](spec/versioning.md) holds the compatibility rules,
[conformance/README.md](conformance/README.md) holds the suite and its two
classes, [docs/architecture.md](docs/architecture.md) walks the save gates
rule by rule, and [docs/checking.md](docs/checking.md) holds the
deterministic save-time check.

Status by area

| Area                                               | Status                                         | Notes                                                                                                                                                            |
| -------------------------------------------------- | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The section format                                 | ✅ Format contract: frozen for 1.x             | A fixed, versioned list of named sections                                                                                                                        |
| JSON Schema                                        | ✅ Format contract: frozen for 1.x             | Draft 2020-12. Cross-checked against the SDK validator on every fixture                                                                                          |
| The `observations` shape                           | ✅ Format contract: frozen for 1.x             | The envelope: `kind`, `data`, `producedBy`, `producedAt`. Specified and enforced                                                                                 |
| Standard observation kinds                         | ✅ Format contr

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [nativesoil](https://github.com/nativesoil)
- **Source:** [nativesoil/handover](https://github.com/nativesoil/handover)
- **License:** Apache-2.0
- **Homepage:** https://nativesoil.dev

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-nativesoil-handover
- Seller: https://agentstack.voostack.com/s/nativesoil
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
