Ship reliability in an afternoon.
DoubleOh is the reliability layer for AI agents. When an agent gets stuck, a human fixes it once in a live browser or desktop, and the fix compiles into a reusable skill the whole fleet follows next time, so the same failure never happens twice. Integrate in three calls via the Python or TypeScript SDK, or the MCP server.
DoubleOh is the reliability layer for AI agents. When an agent gets stuck, one of your own people fixes it once in a live browser, and the fix compiles into a skill your whole fleet reuses forever. You wire in three methods; the loop takes care of the rest.
On this page
Install The loop, in code The three methods Every framework What's recorded, and what isn't API referenceInstall
Pick your language. The SDKs have zero dependencies, a reliability tool that drags a build tree into your project is a reliability problem.
# Python pip install doubleoh # TypeScript / Node npm install @doubleoh/sdk # MCP — any MCP-capable agent (Claude and more) gets the loop with no code npx doubleoh-mcp
The loop, in code
Three moments, because the product is three moments: ask what's known, ask for help, report how it went.
import { DoubleOh } from "@doubleoh/sdk";
const doubleoh = new DoubleOh({ apiKey: process.env.DOUBLEOH_API_KEY });
// 1. Before a task it has failed before, ask what the fleet already knows.
const skills = await doubleoh.skillsFor("check out on the supplier portal");
if (skills.length) prompt += skills[0].instructions;
// 2. Stuck? A human is paged once; a known wall is answered instantly.
const fix = await doubleoh.requestFix({ url: page.url(), task });
if (fix.deflected) prompt += fix.skill.instructions; // nobody paged
else if (fix.fixUrl) await slack.send(fix.fixUrl); // a human, once
// 3. Close the loop. Skills that stop working retire themselves.
await doubleoh.reportSkill(skills[0]?.name, worked);
You decide what "stuck" means. A timeout, a retry count, a model that says it can't proceed, only you know your agent. DoubleOh gives you the moments; the trigger is yours.
The three methods
skillsFor(task)
Returns procedures learned from past human fixes, each carrying its own track record, how many times it worked, how many it didn't. Raw counts, not a rate: five-for-five is worth following; one-for-one is a guess that happened to work once.
requestFix({ url, task })
Ask a human to fix a stuck agent. If the fleet already knows this wall, the learned skill comes back instantly and nobody is paged, that's a deflection. If not, a fix link is issued for a teammate to drive. The
urlmust be a public page; private and loopback addresses are refused by design.reportSkill(name, worked)
One boolean that keeps the library honest. A skill followed three times that never works retires itself, so a bad compile costs one failure, not every future one.
Every framework, one loop
Claude & MCP clients
Run doubleoh-mcp and the three calls become tools with zero integration code.
LangChain · CrewAI · LlamaIndex
One-line adapters. Plus plain-function tools for OpenAI Agents SDK, AutoGen, and Pydantic AI.
Vercel AI · Mastra · raw
Framework-agnostic tool definitions carry JSON Schema, wrap them in one line anywhere.
What's recorded, and what isn't
A fix session keeps screenshots and the shape of each action, a click, a keypress. It does not keep typed text. A fix session is exactly where a password gets typed, so keystrokes stay off this path entirely. Fix targets are validated too: private, loopback, and cloud-metadata addresses are refused, so a fix link can never be pointed at your internal network.
API reference
The full REST contract is published as an OpenAPI 3 spec, import it into Postman, or generate a typed client in any language. Keys start with oo_live_; get one from the pricing page.