Skip to main content

Unwind

A reversibility layer for agentic tool use

Unwind sits between any AI agent and any MCP server, works out which actions can be taken back, quietly takes back the ones that go wrong, and interrupts you only for the ones that truly can't be undone.

CI codecov PyPI Python License: Apache-2.0 OpenSSF Scorecard Docs Discord Star History


Unwind demo: an agent overwrites a config, deletes a page, drops a table, and emails all staff; you type undo; three are reversed and the email is honestly flagged as irreversible.

Generated by make demo-svg. For an animated GIF, install VHS and run vhs docs/assets/demo.tape.


Why Unwind exists

Human oversight of agents is failing because approval prompts are undifferentiated. They are undifferentiated because nothing in the stack knows which actions are reversible. So every MCP client falls back to the same binary "Allow / Deny" dialog for reading a file and for wiring money — and when the prompts come too often, people develop an approve-approve-approve reflex. A prompt injection that triggers one approval you click through has bypassed human oversight entirely.

Unwind supplies the missing primitive — reversibility inference — and then exploits it twice: it auto-allows the reversible majority with a real undo log behind them, and reserves interruption for the irreversible minority. The approval signal stops being noise and starts meaning something.

Unwind is not an undo button. That's the demo, not the thesis. The thesis is that reversibility classification is the enabling mechanism that makes human oversight of agents work at all. See PROJECT.md.

The 20-second demo

An agent, wired through Unwind, runs loose across four servers:

🤖 agent> delete the "Q3 Planning" Notion page          → deleted
🤖 agent> drop the `sessions` table in the sqlite db     → dropped
🤖 agent> email the vendor to cancel the contract        → sent
🤖 agent> force-push my local branch over origin/main     → pushed

You realize the agent misunderstood. You type one word:

you> unwind

Unwind replays the undo log in reverse order, honestly reporting each outcome:

✔ force-push        restored      (reflog checkpoint re-pointed origin/main)
✔ drop table        restored      (table + rows recreated from pre-state snapshot)
✔ delete page       restored      (page un-trashed within retention window)
✖ send email        could not undo — this was R3 (mitigable only).
                    The message was already delivered. I should have asked
                    before sending. Here's the retraction draft and why.

Three actions come back. The fourth is flagged honestly — because a false undo guarantee is worse than none. That last line is the whole thesis in one screenshot, and it's honest.

One-line install

pip install rollback-mcp        # pip
uvx rollback-mcp --help         # zero-install, via uv
docker run ghcr.io/bhaskargurram-ai/unwind --help

The Node/TypeScript stdio shim (ts/) is real and tested, but it is not published to npm. Build and run it from source:

git clone https://github.com/bhaskargurram-ai/unwind && cd unwind/ts
npm install && npm run build
node dist/cli.js run -- npx -y @modelcontextprotocol/server-filesystem /work

Then wrap any upstream MCP server by prefixing its launch command with unwind run --:

# Before: your client spawns the filesystem server directly
npx -y @modelcontextprotocol/server-filesystem /work

# After: Unwind wraps it transparently
unwind run -- npx -y @modelcontextprotocol/server-filesystem /work

Unwind is invisible when idle: any method it doesn't understand is forwarded byte-faithfully, and unwind run --passthrough-only -- <cmd> is a panic switch that disables all classification.

MCP client configuration

Every snippet below wraps the reference filesystem server. Swap the command after -- for any server you already run. The pattern is identical everywhere: keep your existing server command, prefix it with unwind run --.

Claude Desktop  ·  claude_desktop_config.json
{
  "mcpServers": {
    "filesystem": {
      "command": "unwind",
      "args": ["run", "--", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/work"]
    }
  }
}
Claude Code  ·  .mcp.json
{
  "mcpServers": {
    "filesystem": {
      "command": "unwind",
      "args": ["run", "--", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/work"]
    }
  }
}

Or from the CLI: claude mcp add filesystem -- unwind run -- npx -y @modelcontextprotocol/server-filesystem /work

Cursor  ·  ~/.cursor/mcp.json
{
  "mcpServers": {
    "filesystem": {
      "command": "unwind",
      "args": ["run", "--", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/work"]
    }
  }
}
VS Code (MCP)  ·  .vscode/mcp.json
{
  "servers": {
    "filesystem": {
      "command": "unwind",
      "args": ["run", "--", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/work"]
    }
  }
}
Cline  ·  cline_mcp_settings.json
{
  "mcpServers": {
    "filesystem": {
      "command": "unwind",
      "args": ["run", "--", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/work"]
    }
  }
}
Windsurf  ·  ~/.codeium/windsurf/mcp_config.json
{
  "mcpServers": {
    "filesystem": {
      "command": "unwind",
      "args": ["run", "--", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/work"]
    }
  }
}
Goose  ·  ~/.config/goose/config.yaml
extensions:
  filesystem:
    type: stdio
    cmd: unwind
    args: ["run", "--", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/work"]
    enabled: true
Zed  ·  settings.json
{
  "context_servers": {
    "filesystem": {
      "command": {
        "path": "unwind",
        "args": ["run", "--", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/work"]
      }
    }
  }
}
n8n (MCP Client node)

Set the node's command to unwind and the arguments to run -- npx -y @modelcontextprotocol/server-filesystem /work. n8n spawns the stdio server through Unwind exactly like any other client.

The R0–R4 reversibility taxonomy

Reversibility is ordinal and environment-relative — the same write_file is R1 on a git-backed tree and R4 on a versionless one. Class is always a function of (tool, environment), never the tool alone.

Class Name Definition Examples
R0 Nullipotent No state change; safe to repeat. Classified once at tools/list time — never adds latency. get_*, list_*, search_*, read_file
R1 Self-reversible The same tool restores exact prior state, given captured pre-state. update_record, set_status, write_file (prior content captured)
R2 Compensable A different tool semantically undoes it; restores an acceptable approximation. create_page→delete_page, add_member→remove_member, grant→revoke
R3 Mitigable only No true inverse; partial mitigation only, and third parties may already have observed the effect. send_email→retraction, post_message→delete (already read), publish→unpublish (already cached)
R4 Irreversible No inverse and no meaningful mitigation. payment capture, permanent delete with no trash, key destruction, physical actuation, immutable-ledger write

Misclassifying R4 as R1 is catastrophic; misclassifying R1 as R4 merely annoys. Unwind treats these asymmetrically and fails safe — unknown tool, failed classification, timeout, or crashed classifier all escalate to a human. It never auto-allows on uncertainty.

Alongside the class, every call carries three orthogonal dimensions: blast radius (how many entities are affected), externality (did third parties observe it?), and a reversibility half-life — email recall closes in ~30s, trash retention in ~30 days, a payment void before settlement. Reversibility is time-decaying, so the undo log is expiry-aware.

How it compares

Every open-source MCP gateway is a preventive control — it decides whether to allow or block a call. None of them can recover from one. That's the entire opening.

Project Auth / RBAC Rate limiting Tool filtering Reversibility class Compensation synthesis Cross-server undo
Docker MCP Gateway ✅ ✅ ✅ ❌ ❌ ❌
Stacklok ToolHive ✅ ✅ ✅ ❌ ❌ ❌
agentgateway (LF) ✅ ✅ ✅ ❌ ❌ ❌
IBM ContextForge ✅ ✅ ✅ ❌ ❌ ❌
MCPJungle ✅ ✅ ✅ ❌ ❌ ❌
Unwind ❌ (by design) ❌ (by design) ❌ (by design) ✅ ✅ ✅

Not a gateway

Unwind is not another gateway, and never will be. Auth, RBAC, rate limiting, secret scanning, and container isolation are permanently out of scope — that space is saturated and well served by the projects above. Unwind does the one thing none of them do: recovery. It runs standalone, or as optional middleware inside any of those gateways, so it complements them rather than competes. If a feature doesn't sharpen reversibility classification or exploit it, it's out of scope.

The Unwind MCP tools

Unwind is itself an MCP server. It exposes its own tools so the agent can reason about and reverse its own actions — this is what makes Unwind agentic rather than a passive filter:

Tool What it does
unwind.preview Classify a proposed call (R0–R4 + confidence + blast radius) before it runs.
unwind.undo Reverse the last n actions across every connected server, in reverse order.
unwind.explain_risk Explain in plain language why a call is (ir)reversible and what residue an undo would leave.
unwind.history Inspect the durable, cross-server undo log with expiry state.
unwind.checkpoint Mark a labelled restore point to unwind back to.

Documentation & links

Project status & expectations

Unwind is early beta (0.1.x). The transparent proxy and the R1 undo path are the foundation; compensation synthesis, calibrated escalation, and the full ReversiBench harness are landing across the roadmap. We report reversibility fidelity graded, never as a boolean, and we would rather flag an action as "couldn't undo" than promise a rollback that won't hold. We target realistic adoption and never over-promise undo — because a false undo guarantee manufactures the exact auto-approve reflex this project exists to cure. Benchmark numbers are published only once they come from the live sandbox with bootstrap confidence intervals; until then this README describes capabilities qualitatively rather than quoting figures.

Community

Questions, ideas, and show-and-tell are welcome in GitHub Discussions. A Discord is coming soon. Please read the Code of Conduct.

Citation

If Unwind or ReversiBench is useful in your research, please cite it. A machine-readable CITATION.cff is included.

@article{gurram2026unwind,
  title   = {Unwind: Reversibility Inference and Compensation Synthesis for Agentic Tool Use},
  author  = {Gurram, Bhaskar},
  year    = {2026},
  eprint  = {TBD},
  archivePrefix = {arXiv},
  note    = {arXiv preprint. DOI: TBD}
}

arXiv ID and DOI are TBD and will be filled in on preprint release.

License

Licensed under the Apache License 2.0.

Built by Bhaskar Gurram. The reversibility layer for agentic tool use.

Metadata

Release files for rollback-mcp 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rollback-mcp 0.2.0
File Size Uploaded Provenance
rollback_mcp-0.2.0.tar.gz 455.2 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for rollback-mcp 0.2.0
File Interpreter ABI Platform
rollback_mcp-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 534.9 kB

Release files / rollback_mcp-0.2.0.tar.gz

Download URL rollback_mcp-0.2.0.tar.gz
Size 455.2 kB
Tags Source
SHA-256 checksum
How to use checksums
040101d9620def9f1386ec92fff0c08052721c0ce4771b7a793515daa640f07f
BLAKE2b-256 checksum
How to use checksums
a1c88ffa10fdb0d55c1d6cdf9d085e59737721110a3716dc239b0607747fcf9f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Release files / rollback_mcp-0.2.0-py3-none-any.whl

Download URL rollback_mcp-0.2.0-py3-none-any.whl
Size 79.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ab5125e9e8517998acb556d2e26a683eadd7f625a55c0004be729197504f48da
BLAKE2b-256 checksum
How to use checksums
62b70888a8a0d95cd2f35dd88da325d97eea11efdee7f1abd94f4aa9261d851e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Security for rollback-mcp 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for rollback_mcp-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page