Four hard-won lessons on MCP write APIs: atomic undo, stale idempotency keys, model-facing errors

jangtrinh · reddit · 2026-10-30

The author of DESIGN:OS Studio (a native design editor in Rust) shares four decisions from the write path of its local stdio MCP server designos-mcp (36 tools), highly relevant for anyone building agent-writable tools:

1. Make undo part of the tool contract. designosapplybatch takes 1–200 ops as one atomic transaction and one undo group, supports dryrun, and lets later ops reference earlier ones via $prev/@handle. Without batching, 40 small agent writes mean 40 undo steps for the human.

2. Check undo itself. One edit plus Cmd+Z once changed 80 layers by up to 1332px because undo re-solved auto layout outside the undo step. The fix replays the recorded inverse exactly; re-solving is kept only for undoing agent/MCP edits.

3. Retries can lie. Writes take an optional idempotencykey — same key and args return the first reply and write nothing. Trap: agent writes with key K, human undoes it, agent retries with K; replaying the old reply would report a success that no longer exists. The ledger now returns IDEMPOTENCYKEYSTALE, which persists across reconnects, forcing the agent to decide again.

4. Write errors for the model, not the log. Every error is one JSON shape with code, path, received, expected, validoptions, correctedexample, safetoretry, nextstep; failed ops in a batch report which one failed and why.

Still open: nothing stops an agent from looping on the same failing tool since only keyed writes are deduplicated (#1290).

The app is free, source-available (PolyForm Shield), no telemetry, and reuses your agent CLI sign-in.

Original post →

More from coding & agent

coding & agent channel →