auto-any
goal + URL -> signature -> exact receipt? -> deterministic replay
\-> local/remote engine -> browser -> distiller -> receipt
Run with uvicorn auto_any.main:app. For local development install RTR first with
uv pip install -e C:/Users/KR-ultra/Source/code_base/repos/replayable-test-runner.
Configuration uses the AANY_ prefix; see .env.example.
Install / share
One command gets a teammate from zero to "auto-any MCP Connected":
pwsh install/install.ps1
macOS, Linux, or Git Bash:
bash install/install.sh
See install/README.md for options (custom venv path, local wheel) and the two .env knobs you must set.
Reuse my Chrome logins
To run against a cloned copy of an already-authenticated Chrome profile:
$env:AANY_PROFILE_MODE = "clone"
$env:AANY_CHROME_SOURCE_PROFILE = "Profile 2" # or Default
uvicorn auto_any.main:app
The clone is created under AANY_PROFILES_DIR, and the source User Data tree is
never written. Chrome may be left open; a cookie written very recently may not
have been flushed yet. AANY_PROFILE_KEEP=false removes the clone after the run.
Cloning copies live authentication cookies, so treat the profiles directory as
sensitive and do not commit or share it. Set AANY_BLOCK_PRIVATE_NETWORKS=true
for hosted deployments; the default is false so operator-owned localhost and
LAN targets remain usable. For a persistent named profile, use
AANY_PROFILE_MODE=named and select it with profile: {"name":"work"} (or use
a pack that declares profile_name, such as linkedin_apply). Named profiles
are managed with GET /profiles and DELETE /profiles/{name}.
Capabilities
| Capability | Action kinds | Runner |
|---|---|---|
| browser | playwright |
RTR Playwright meta-runner |
| shell | shell |
RTR shell runner (allow/deny policy) |
| http | http_request |
RTR HTTP runner |
| extract | extract |
typed Pydantic model |
| verify | verify |
explicit RTR assertion |
Add a capability by implementing the Capability contract, registering its
name in CAPABILITIES, and registering an RTR StepRunner for each action
kind. CapabilityGate then dispatches it without changing the engine loop.
Rubricon / EFA scoring
Install the optional evaluator integration with pip install 'auto-any[efa]'
and select it with score="efa" in an automation request. The adapter uses
Rubricon's dynamic criteria generation and per-criterion evaluator to attach
RAS, APR, and criterion scores to the run result. It evaluates the completed
response only; replay remains deterministic and does not invoke an LLM.
Paused OTP/CAPTCHA/confirmation turns emit needs_input; resume with
POST /automations/{run_id}/resume. Secret values are stored in receipts only
as {"$var":"field"}. Trace artifacts are per-run and video is opt-in.
Storage layout
The storage root is AANY_HOME, defaulting to Path.home() / ".auto_any".
Relative AANY_RECEIPTS_DIR and AANY_ARTIFACTS_DIR values resolve under this
root; absolute values are honored as supplied.
~/.auto_any/
├── receipts/ # replayable receipts
├── artifacts/<run_id>/ # per-run screenshots + trace.zip
│ ├── 001_open.png
│ ├── 002_click.png
│ └── trace.zip
├── ledger.jsonl # append-only run history
└── site_profiles.json # site → browser-profile mapping
Browser screenshots are captured automatically after browser actions, with
zero-padded ordered names such as 001_open.png and 002_click.png. Capture
is non-fatal and is enabled by the auto_screenshot=True driver constructor
option. A run without an explicit ID uses a timestamped artifact directory.
The run ledger is enabled by default as an append-only JSONL file; pass
AANY_LEDGER=null to opt out, AANY_LEDGER=kr_hub for the remote ledger, or
AANY_LEDGER=<path>.db to keep using the previous SQLite backend.
Economics: replayed runs cost 0 LLM tokens; planned runs cost N LLM tokens.
MCP server
auto_any can run as a STDIO Model Context Protocol (MCP) server so Claude and other MCP clients can invoke it in-process.
# install the MCP extra
uv pip install -e ".[mcp,browser]"
# register with Claude Desktop (do not edit ~/.claude manually)
claude mcp add-json auto-any '{"command": "auto-any-mcp"}'
The server boots one shared headless runtime (AANY_PROFILE_MODE=fresh) and
exposes five tools:
| Tool | Purpose |
|---|---|
auto_any_list_packs |
List installed packs + parameter schemas |
auto_any_run_pack |
Run a pack by name with validated params |
auto_any_run |
Run a free-text goal + URL |
auto_any_list_receipts |
List saved receipts (signature key + title) |
auto_any_replay |
Replay a receipt with zero LLM tokens |
Start it manually with auto-any-mcp.
Three Lanes
auto_any exposes the same automation engine through three interfaces. All three delegate to the shared automation_events generator in api/automations.py.
| Lane | Command | Description |
|---|---|---|
| CLI | auto-any run --goal "..." --url "..." |
Direct command-line execution |
| HTTP | auto-any serve (starts uvicorn) |
REST API at POST /automations |
| MCP | python -m auto_any.mcp_server |
STDIO tools for Claude Desktop |
All lanes accept the same request shape: goal, url, mode (auto/always_plan/replay_only), and return streaming events containing run_started, progress, run_finished, and optionally receipt_saved.
Additional CLI commands:
auto-any receipts— list stored receipts (signature key + title)auto-any replay <signature_key>— replay a receipt with zero LLM tokensauto-any version— print the running build's identity
Receipt Contract
A receipt is a deterministic, replayable record of an automation run. It contains:
- signature_key: SHA256 hash of
goal + url + context— the identity for exact-match replay - title: Human-readable description
- steps: Ordered list of actions (goto, click, type, extract, verify...)
- url: Target URL at time of execution
What replay guarantees:
- Same goal + same URL → same actions in same order
- Zero LLM tokens consumed (deterministic playback)
- Pass/fail per step — if a page element changed, replay reports failure
What replay does NOT guarantee:
- External state (logged-in sessions, database data, third-party API responses)
- Timing/performance — replay is deterministic but not real-time
- Cross-browser parity — receipts are driver-specific (Playwright vs Selenium)
- Future site changes — replay fails if UI changed; this is the intended behavior
The signature key is the lookup key for both auto-any receipts and the MCP auto_any_replay tool.
How to Tell Which Build is Running
On 2026-07-26, the MCP server ran for hours importing stale code from a different git worktree while reporting healthy. Nothing revealed which build was actually executing.
Two ways to verify the running build:
# CLI — prints version, git SHA, dirty flag, and import path
$ auto-any version
auto-any 0.1.0 git:bf3545d
$ auto-any version --json
{"version": "0.1.0", "git_sha": "bf3545d", "dirty": false, "import_path": "C:\\Users\\...\\src\\auto_any"}
# MCP — check the startup log line
$ python -m auto_any.mcp_server
selected browser driver=playwright tier=config_explicit task_hint=
MCP server starting: auto-any 0.1.0 git:bf3545d; import_path=C:\Users\...\src\auto_any
The import_path field shows the exact directory from which auto_any was loaded. If this differs from the expected worktree, the running code is stale.
Quickstart — adopt it for any UI automation
uv venv && uv pip install -e ".[dev,browser]"
uv run playwright install chromium # real browser lane
# list built-in automation packs (smoke_test, form_fill, linkedin_apply)
uv run auto-any packs
# run the API
uv run auto-any serve --port 8080
# POST /automations free-text goal (the raw engine)
# GET /packs installed packs + their param schemas
# POST /packs/{name}/run typed params -> same pipeline -> receipt
# reuse your real Chrome logins (no interactive auth):
# AANY_PROFILE_MODE=clone AANY_CHROME_SOURCE_PROFILE="Profile 2"
# real LLM to drive arbitrary UIs:
# AANY_LLM_PROVIDER=anthropic AANY_LLM_API_KEY=...
Packs quickstart
The built-in packs are smoke_test, form_fill, and linkedin_apply. For a
local unauthenticated development server, set AANY_AUTH_DISABLED=true, then
inspect schemas and run smoke_test as an SSE stream:
export AANY_AUTH_DISABLED=true
uv run auto-any serve --port 8080
curl http://127.0.0.1:8080/packs
curl -N -X POST http://127.0.0.1:8080/packs/smoke_test/run \
-H 'Content-Type: application/json' \
-d '{"base_url":"http://127.0.0.1:8080","checks":[{"path":"/health","expect_text":"ok"}]}'
With authentication enabled, add -H "Authorization: Bearer <token>" to both
requests.
Add a new use-case as a pack (no core edits) - see ARCHITECTURE.md.
Multi-vendor execution
AANY_BROWSER_DRIVER=playwright|selenium|appium|auto selects the per-action driver.
Install optional integrations with uv pip install -e ".[selenium]" or .[appium];
absent SDKs and servers produce an actionable unavailable event. A request can
override this with {"driver":"selenium"}. Export receipts with
POST /receipts/{key}/export and {"format":"cypress"} (playwright and
robot are also supported). $var values become vendor environment lookups and
are never written as secrets. Set score to passmark for a tolerant score report.
Tests
uv run pytest -q # hermetic unit suite (fakes only, no browser)
AANY_E2E=1 uv run pytest tests/test_e2e_real_browser.py # real headless Chromium
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file auto_any-0.1.0.tar.gz.
File metadata
- Download URL: auto_any-0.1.0.tar.gz
- Upload date:
- Size: 185.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b6f7c5b11f92945300272b4c7308bcd9f8699443224640c23a47382af0702608
|
|
| MD5 |
fbefb3efac69f7c64150b58e1b88f3bd
|
|
| BLAKE2b-256 |
2b4bd63f99db1fd12b743d5b89f12dcd7466ef3561e29f2ad4ff48f54c17e895
|
File details
Details for the file auto_any-0.1.0-py3-none-any.whl.
File metadata
- Download URL: auto_any-0.1.0-py3-none-any.whl
- Upload date:
- Size: 169.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c7f0de1c22d8f4b2788b83d3cc3fdfe304a9f8bb6958e849d3038fe530c88097
|
|
| MD5 |
b7c5f25056acfb2f11ac06ccc1cb3912
|
|
| BLAKE2b-256 |
56f662ac6a3b709c2bb873e7397cc9a3ef466748656d948e33458c5564167647
|