{"id":"1589ad1f-a359-47eb-a1b8-d367dcf8ee98","slug":"statepilot","kind":"mcp","name":"statepilot","summary":"Predictable browser runtime for AI agents with memory, validation, recovery, and MCP integration.","owner":"newsbruno","repoUrl":"https://github.com/newsbruno/statepilot","license":"MIT","licenseTier":"permissive","trust":"community","stars":1,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-05-21T01:52:43.000Z","addedAt":"2026-10-21T08:54:54.897Z","logoUrl":"https://avatars.githubusercontent.com/u/13912498?u=75e6fad1e31102b01b9e745459983a4cbff15c6c&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["browser-web","developer-tools","memory-knowledge"],"tags":["agent-runtime","ai-agent","automation","browser-agent","browser-automation","claude-code","codex","cursor"],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-23T03:40:13.821Z","sample":false,"url":"https://conduits.dev/tools/statepilot","language":"TypeScript","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# StatePilot\n\n### A predictable browser runtime for AI agents\n\n<p align=\"center\">\n  <img alt=\"npm v0.1.0\" src=\"https://img.shields.io/badge/npm-v0.1.0-CB6D30?style=flat&labelColor=555555\" />\n  <img alt=\"License MIT\" src=\"https://img.shields.io/badge/License-MIT-C9B900?style=flat&labelColor=555555\" />\n  <img alt=\"Node.js 18+\" src=\"https://img.shields.io/badge/Node.js-18%2B-8CC84B?style=flat&labelColor=555555\" />\n  <br />\n  <img alt=\"Windows supported\" src=\"https://img.shields.io/badge/Windows-supported-0078D4?style=flat&labelColor=555555\" />\n  <img alt=\"macOS supported\" src=\"https://img.shields.io/badge/macOS-supported-0078D4?style=flat&labelColor=555555\" />\n  <img alt=\"Linux supported\" src=\"https://img.shields.io/badge/Linux-supported-0078D4?style=flat&labelColor=555555\" />\n  <br />\n  <img alt=\"Claude Code supported\" src=\"https://img.shields.io/badge/Claude%20Code-supported-7D2AE8?style=flat&labelColor=555555\" />\n  <img alt=\"Cursor supported\" src=\"https://img.shields.io/badge/Cursor-supported-7D2AE8?style=flat&labelColor=555555\" />\n  <img alt=\"Codex CLI supported\" src=\"https://img.shields.io/badge/Codex%20CLI-supported-7D2AE8?style=flat&labelColor=555555\" />\n  <img alt=\"opencode supported\" src=\"https://img.shields.io/badge/opencode-supported-7D2AE8?style=flat&labelColor=555555\" />\n</p>\n\nStatePilot gives AI agents a browser runtime with memory, validation, recovery, and agent-native integration.\n\nIt is designed for Claude Code, Codex CLI, Cursor, opencode, and custom agents that need to operate real websites without treating every click as a fresh reasoning problem.\n\n```txt\nObserve -> Predict -> Execute -> Validate -> Learn -> Recover\n```\n\n## Executive Summary\n\nModern AI agents are powerful at reasoning, but browser automation punishes pure reasoning loops. A typical agent sees a page, asks an LLM what to do, clicks, waits, observes again, asks again, and repeats. That works for demos. It becomes slow, expensive, and fragile for repeated workflows.\n\nStatePilot takes a different approach.\n\nInstead of making the model think from zero on every step, StatePilot turns browser work into a predictable runtime:\n\n- observe a compact representation of the browser state;\n- predict the next action from memory and heuristics;\n- execute the action through a browser adapter;\n- validate the actual next state against the expected next state;\n- learn successful transitions;\n- recover or escalate when reality diverges.\n\nThe product value is simple:\n\n> Supercharge Claude Code, Codex CLI, Cursor, opencode, and custom AI agents with predictable browser automation that can be replayed, validated, audited, and improved over time.\n\n## Why This Exists\n\nBrowser agents often fail for the same reasons:\n\n- they overuse LLM calls for routine steps;\n- they click stale, hidden, or irrelevant elements;\n- they lose track of whether an action actually changed the page correctly;\n- they rely on raw page text or screenshots when a compact state would be enough;\n- they make every new run expensive, even when the flow is already known;\n- they force the agent to glue together tool output with shell scripts or ad hoc parsing.\n\nStatePilot exists to make repeated browser work feel like runtime execution, not improvisation.\n\nIt is especially useful for:\n\n- portal login and search workflows;\n- article and research extraction;\n- form submission;\n- table and document retrieval;\n- repeated SaaS/admin tasks;\n- agent smoke tests across Claude Code, Codex CLI, Cursor, and opencode;\n- custom browser workers that need predictable state transitions.\n\n## The Runtime Model\n\nStatePilot is inspired by JEPA-style prediction: predict future representations, not raw pixels.\n\nIn browser terms, the runtime asks:\n\n```txt\ncompact BrowserState + candidate Action -> expected next BrowserState\n```\n\nThen it compares:\n\n```txt\nexpected next state vs actual next state\n```\n\nIf the difference is small, the runtime continues and can store the transition as useful memory.\n\nIf the difference is large, StatePilot treats that as divergence. It can retry, choose another prediction, use heuristics, report the failure, or escalate to a heavier planner.\n\nThis gives agents a practical kind of predictability:\n\n- known states can map to known actions;\n- every action has an expected result;\n- failures have structured reasons;\n- repeated flows get cheaper and more reliable;\n- LLM reasoning is reserved for ambiguity, not routine clicks.\n\n## Architecture\n\nStatePilot is split into small packages so the runtime stays testable and adapters stay replaceable.\n\n| Package | Role |\n| --- | --- |\n| `@statepilot/action-model` | Serializable browser actions and validation |\n| `@statepilot/browser-state` | Compact browser-state encoding and deterministic hashes |\n| `@statepilot/predictor` | Hybrid prediction from memory and heuristics |\n| `@statepilot/validator` | Energy-style validation of expected vs actual state |\n| `@statepilot/memory` | In-memory and SQLite transition memory |\n| `@statepilot/core` | Runtime orchestration and adapter contracts |\n| `@statepilot/playwright` | Playwright browser adapter |\n| `@statepilot/testing` | Deterministic mock adapter and test utilities |\n| `@statepilot/cli` | CLI, MCP server, installers, doctor, and smoke tests |\n\nThe runtime loop is intentionally adapter-based:\n\n```txt\nAgent or App\n  |\n  v\nStatePilot CLI / MCP / TypeScript API\n  |\n  v\nCore Runtime\n  |\n  +-- Browser State Encoder\n  +-- Prediction Engine\n  +-- Validation Engine\n  +-- Transition Memory\n  |\n  v\nBrowser Adapter\n  |\n  v\nPlaywright, mock adapter, or future adapters\n```\n\n## Install\n\nInstall the CLI globally:\n\n```bash\nnpm install -g @statepilot/cli\n```\n\nThen run setup:\n\n```bash\nstatepilot setup --target=all --location=global\n```\n\n`setup` does two things:\n\n- installs the Playwright Chromium browser StatePilot needs for real browser tasks;\n- writes MCP config and instruction files for the selected agent targets.\n\nRestart the agent after setup so it reloads the MCP server.\n\nTo install only in the current project:\n\n```bash\nstatepilot init . --install --target=claude,cursor,codex,opencode\n```\n\nTo check the installation:\n\n```bash\nstatepilot doctor\nstatepilot doctor --fix\nstatepilot doctor --location=all\n```\n\n`doctor --fix` repairs the most common first-run issue: missing Playwright Chromium.\n\n## Agent Integration\n\nStatePilot exposes a stdio MCP server:\n\n```bash\nstatepilot serve --mcp\n```\n\nThe installer writes each agent's native config so agents can call StatePilot as tools.\n\n| Agent | Config | Instructions |\n| --- | --- | --- |\n| Claude Code | `.claude.json` or `~/.claude.json` | `CLAUDE.md` or `~/.claude/CLAUDE.md` |\n| Cursor | `.cursor/mcp.json` or `~/.cursor/mcp.json` | `.cursor/rules/statepilot.mdc` |\n| Codex CLI | `.codex/config.toml` or `~/.codex/config.toml` | `AGENTS.md` or `~/.codex/AGENTS.md` |\n| opencode | `.opencode/opencode.jsonc` or opencode config dir | `AGENTS.md` |\n\nUseful commands:\n\n```bash\nstatepilot install --target=claude --location=global\nstatepilot install --target=codex --location=local\nstatepilot install --print-config cursor\nstatepilot doctor --target=all --location=all\n```\n\n## MCP Tools\n\nStatePilot currently exposes these MCP tools:\n\n| Tool | Purpose |\n| --- | --- |\n| `statepilot_status` | Check project/runtime status |\n| `statepilot_init_project` | Create `.statepilot/config.json` |\n| `statepilot_run_task` | Run a browser task through the StatePilot runtime |\n| `statepilot_research_site` | Open an index page, collect links, select article URLs, extract articles, and return consolidated JSON |\n| `statepilot_agent_instructions` | Return guidance for agents using StatePilot |\n\nAgents should prefer `statepilot_research_site` for multi-page research. It prevents the agent from needing shell, Python, `cat`, `jq`, or saved tool-result files to merge outputs.\n\n## Basic Browser Task\n\nFor a simple page extraction:\n\n```json\n{\n  \"goal\": \"Open https://techcrunch.com/ and extract page text\",\n  \"headless\": true,\n  \"timeoutMs\": 60000\n}\n```\n\nStatePilot infers the URL from the goal and adds an extraction step. A healthy run returns:\n\n- `result.url`;\n- `result.title`;\n- `result.text`;\n- `result.links`;\n- `result.metadata`;\n- metrics such as action count, duration, recovery count, and prediction confidence.\n\nYou can also pass structured input:\n\n```json\n{\n  \"goal\": \"Open TechCrunch and extract page text\",\n  \"input\": {\n    \"url\": \"https://techcrunch.com/\"\n  },\n  \"extractText\": true,\n  \"headless\": true,\n  \"timeoutMs\": 60000\n}\n```\n\nIf a run only navigates and returns `result: null`, ask with explicit extraction language such as “extract page text” or “collect article links”, then restart the agent if it has an old MCP server loaded.\n\n## Article Extraction\n\nFor article pages, use article mode:\n\n```json\n{\n  \"goal\": \"Open the article URL and extract title, author, date, body, claims, and evidence\",\n  \"input\": {\n    \"url\": \"https://example.com/2026/05/20/article/\"\n  },\n  \"articleMode\": true,\n  \"includeEvidence\": true,\n  \"headless\": true,\n  \"timeoutMs\": 60000\n}\n```\n\nArticle mode extracts deterministic fields from:\n\n- JSON-LD;\n- meta tags;\n- `article` and `main` DOM content;\n- paragraph evidence;\n- field-level evidence;\n- claim candidates.\n\nAgents should build summaries and structured output from `result.article`, especially:\n\n- `result.article.title`;\n- `result.article.author`;\n- `result.article.publishedAt`;\n- `result.article.description`;\n- `result.article.claims`;\n- `result.article.paragraphEvidence`;\n- `result.article.evidence`.\n\n## Multi-Article Research\n\nFor research workflows, use the consolidated research tool:\n\n```json\n{\n  \"url\": \"https://techcrunch.com/category/artificial-intelligence/\",\n  \"topic\": \"AI startup news\",\n  \"limit\": 5,\n  \"includeEvidence\": true,\n  \"responseMode\": \"compact\",\n  \"maxClaimsPerArticle\": 4,\n  \"maxCitationsPerArticle\": 4,\n  \"maxSnippetChars\": 320,\n  \"maxResponseBytes\": 60000,\n  \"headless\": true,\n  \"timeoutMs\": 60000\n}\n```\n\nThe workflow:\n\n1. Opens the source page.\n2. Extracts normalized links.\n3. Scores links against the topic.\n4. Selects article URLs.\n5. Opens each selected article.\n6. Extracts article fields, claims, citations, and evidence.\n7. Returns one JSON object with `articles`, `failures`, `metrics`, and `budget`.\n\nThis is the recommended path for agent research because the agent receives one structured result instead of many large tool-result files.\n\nUse `responseMode: \"compact\"` by default. Use `responseMode: \"full\"` only for raw article payloads.\n\n`maxResponseBytes` caps the serialized response and reports reductions in `budget.reductions`.\n\n## Real-Agent Smoke Tests\n\nStatePilot includes a smoke-test workflow for validating real agent integrations.\n\nRun the deterministic baseline:\n\n```bash\nstatepilot smoke run\n```\n\nPrint prompts for real agents:\n\n```bash\nstatepilot smoke prompt --target=claude\nstatepilot smoke prompt --target=codex\nstatepilot smoke prompt --target=cursor\nstatepilot smoke prompt --target=opencode\n```\n\nThe generated prompt asks the agent to call `statepilot_research_site` with `smokeMode: true`.\n\n`smokeMode` still runs the full index-to-article workflow, but returns a compact verification payload:\n\n- links collected;\n- links selected;\n- article count;\n- URL/title/author/date checks;\n- claims present;\n- citations present;\n- failures;\n- metrics;\n- response budget;\n- pass/fail checks.\n\nThis makes real-agent testing much less fragile. The agent does not need to echo huge claim and citation text back into the final answer.\n\nRecord real-agent results:\n\n```bash\nstatepilot smoke record --target=claude --status=pass --response-bytes=4532 --articles=5 --selected-links=5 --failures=0 --used-shell=false --read-tool-results=false --notes=\"Real Claude Code MCP run passed with smokeMode true.\"\nstatepilot smoke matrix\n```\n\nThe matrix is stored at `.statepilot/smoke-matrix.json`.\n\n## Testing and Verification\n\nFor contributors:\n\n```bash\npnpm install\npnpm typecheck\npnpm lint\npnpm test\npnpm build\npnpm smoke\n```\n\nRecommended pre-release check:\n\n```bash\npnpm check\npnpm build\npnpm smoke\n```\n\n`pnpm smoke` uses the mock adapter, so it does not require network access.\n\nFor real browser testing, run:\n\n```bash\nstatepilot smoke run --real\n```\n\n## TypeScript API\n\nStatePilot can also be used directly as a TypeScript runtime:\n\n```ts\nimport { createRuntime } from \"@statepilot/core\";\nimport { createInMemoryPredictionMemory } from \"@statepilot/memory\";\nimport { createMockBrowserAdapter } from \"@statepilot/testing\";\n\nconst runtime = createRuntime({\n  adapter: createMockBrowserAdapter(),\n  memory: createInMemoryPredictionMemory()\n});\n\nawait runtime.run({\n  id: crypto.randomUUID(),\n  goal: \"Open the login page\",\n  siteKey: \"demo\",\n  input: {\n    url: \"https://example.com/login\"\n  },\n  priority: \"normal\",\n  timeoutMs: 30000,\n  retryLimit: 1,\n  createdAt: new Date()\n});\n```\n\nUse the TypeScript API when embedding StatePilot inside a worker, service, or custom agent runtime.\n\nUse the CLI/MCP path when Claude Code, Codex CLI, Cursor, or opencode should call StatePilot as a tool.\n\n## Release Process\n\nPublic npm distribution is centered on the CLI package:\n\n```bash\nnpm install -g @statepilot/cli\n```\n\nThe CLI depends on internal `@statepilot/*` packages. A public release publishes the workspace packages first, then `@statepilot/cli`. An alternative release strategy is to bundle the internal runtime packages into the CLI package and publish only the CLI.\n\nRelease checklist:\n\n1. Confirm the `@statepilot` npm organization/scope exists and the publishing account has access.\n2. Add final package metadata: license, repository, homepage, keywords, and author.\n3. Build the workspace.\n4. Dry-run package publishing and inspect generated manifests.\n5. Publish the internal packages in dependency order.\n6. Publish `@statepilot/cli`.\n7. Verify from a clean machine or temp directory with `npm install -g @statepilot/cli`.\n8. Run `statepilot doctor --fix` and `statepilot smoke run`.\n\nPackage dependency order for the current workspace:\n\n1. `@statepilot/action-model`\n2. `@statepilot/browser-state`\n3. `@statepilot/memory`\n4. `@statepilot/validator`\n5. `@statepilot/predictor`\n6. `@statepilot/core`\n7. `@statepilot/playwright`\n8. `@statepilot/testing`\n9. `@statepilot/cli`\n\nThe root package is private and should not be published.\n\nUseful release checks:\n\n```bash\npnpm build\npnpm check\npnpm smoke\npnpm publish -r --dry-run\n```\n\nPublish command:\n\n```bash\npnpm publish -r --access public\n```\n\nBefore publishing, inspect the packed `package.json` files and confirm that no published package contains unresolved `workspace:*` or `catalog:` dependency ranges.\n\n## Troubleshooting\n\nnpm publish returns `404 Scope not found`:\n\nThe `@statepilot` scope must exist on npm before scoped packages can be published. Create the `statepilot` npm organization, grant publish access to the release account, then rerun `pnpm publish -r --access public`. If the scope is not available, rename package scopes consistently before publishing.\n\nMissing Playwright browser:\n\n```bash\nstatepilot doctor --fix\n```\n\nAgent cannot see StatePilot tools:\n\n```bash\nstatepilot doctor --location=all\n```\n\nThen restart the agent.\n\nResearch result too large:\n\n- use `responseMode: \"compact\"`;\n- lower `limit`;\n- lower `maxClaimsPerArticle`;\n- lower `maxCitationsPerArticle`;\n- lower `maxSnippetChars`;\n- set `smokeMode: true` for integration tests.\n\nAgent tries to read saved tool-result files:\n\n- use `statepilot_research_site` instead of multiple `statepilot_run_task` calls;\n- use the generated prompt from `statepilot smoke prompt`;\n- keep `maxResponseBytes` small enough for inline output.\n\n## Current Status\n\nStatePilot currently includes:\n\n- core runtime orchestration;\n- serializable action model;\n- compact browser-state encoder;\n- hybrid prediction engine;\n- energy-style validator;\n- in-memory and SQLite transition memory;\n- Playwright adapter;\n- deterministic mock adapter;\n- MCP server;\n- agent installers;\n- doctor and browser repair commands;\n- consolidated research workflow;\n- real-agent smoke prompt and result matrix.\n\nThe architecture note that started the project is in [statepilot-architecture.md](./statepilot-architecture.md).\n"}