Stop your agents from
eating their own state.
A deterministic MCP server that converts "the JSON your agent just produced" into "JSON your agent can safely persist" — no extra LLM calls, no retries, no probabilistic anything.
The Death Loop
Every multi-step agentic workflow eventually hits the same failure mode.
An LLM produces output that is almost JSON. A stray "Sure, here you go:" preamble. An unescaped newline inside a string value. A trailing comma. A response truncated by the context window one token before the closing brace. Your orchestrator pipes that string into json.loads, gets a JSONDecodeError, and the session state file never gets written.
On the next tick the agent reads a stale or empty state, asks the model to redo the last step, receives a slightly-different-but-equally-broken output, and the cycle begins.
Retry-until-success and JSON mode reduce the rate of failure — they don't eliminate it. Each retry spends real tokens on work that should have been spent making progress, and a determined corruption (escaped-control-character drift, schema violations) survives the retry anyway.
What this server does
When your agent is about to write state, it calls one of four sanity tools and gets back either guaranteed-parseable JSON or a concrete, machine-readable list of fix actions describing exactly what to change before retrying.
sanitize_json_output
Call this before any state write. Strips prose preambles and code fences, repairs malformed control characters, and delegates structural repairs. The single tool that most directly prevents session poisoning.
repair_string
Deterministic repair engine with optional schema validation. When the JSON violates your schema, you get a list of concrete Fix Actions like "Add required field 'user_id' at $" the agent can act on in one pass.
repair_json
Lighter pass for the common stuff: trailing commas, single quotes, unquoted keys, Python/JS literals, truncated structures. Use when you know the input is nearly-JSON.
validate_json
Strict validator. Returns the parsed object on success or a descriptive error pinpointing the exact line and column. Useful for probing suspect strings before deciding whether to repair.
# One call before every state write. result = await session.call_tool( "sanitize_json_output", { "raw_string": raw_model_output, "api_key_id": "cus_1234", }, ) # Or with schema enforcement and concrete fix actions: result = await session.call_tool( "repair_string", { "raw_string": raw_model_output, "schema": {"type": "object", "required": ["user_id"]}, "api_key_id": "cus_1234", }, )
Why it matters for long-running agents
Short conversational agents can afford a failed JSON parse. The user retypes. Long-running agents can't.
When an agent is running unattended — a planner checkpointing every ten minutes, a research workflow accumulating notes over an afternoon, a memory-tiered assistant that lives across sessions, a background orchestrator handing tasks between sub-agents — every state write is load-bearing. A single corrupted checkpoint isn't a failed step; it's a silent rollback of everything that happened after the last good write.
JSON-Sanity sits between the model's output and your state store and makes that failure mode impossible. One deterministic string pass saves a stateful rollback, and the per-invocation cost is orders of magnitude below the cost of one replayed agent turn.
Pricing
Metered through Stripe. Failed calls and anonymous calls are not billed.
- All four tools — same price
- Failed calls aren't billed
- Stripe-metered, attributed by Customer ID
- Cancel anytime from the customer portal
FAQ
cus_… identifier and a configuration snippet for claude_desktop_config.json (or any MCP client). Drop it in, restart your client, and the four tools become available to your agents.