Web Task API
web-task-api is a generalized browser-task runtime for projects that want to treat websites like programmable APIs.
It exposes one API for:
- starting from a URL + goal
- letting an agent drive a real browser
- validating structured output against a schema
- reusing persistent browser profiles and promoted recipes
- storing traces and artifacts for replay/debugging
The same runtime now ships in two surfaces:
- HTTP API for application-to-application integration
- MCP server for Claude Code, OpenCode, and other MCP clients1
Why this exists
Instead of building one brittle adapter per website, this project uses an agent-first browser runtime:
- default path: goal-driven browser control
- optimization path: reusable recipes for common flows
- escape hatch: login profiles and artifacts for debugging failures
That gives a more future-proof foundation for “API for any site” style automation.
Implemented MVP
- Fastify HTTP API
- stdio MCP server
- Playwright browser runtime
- CLIProxyAPI-backed planner for freeform browser control
- Optional OpenCode SDK planner adapter for environments that already use OpenCode well
- Auto planner mode that falls back to your existing local OpenCode auth/runtime when direct CLIProxy credentials are not wired yet
- Mock agent for local deterministic demos/tests
- Recipe registry and matching
- Persistent browser profile reuse
- Run artifacts and step traces
- Local demo and end-to-end tests
Initial workflow targets
- generic search/form workflows
- Dexscreener token/pair reading starter recipe
- GMGN token/wallet reading starter recipe
For Dexscreener/GMGN, treat the shipped recipes as starter recipes, not guaranteed turnkey integrations yet. A warmed persistent browser source is often required because fresh headless sessions can hit Cloudflare or similar anti-bot checks. The runtime now fails fast for these protected-site recipes unless you provide one of:
request.profile
BROWSER_USER_DATA_DIR
sessionId for a warmed session that already preserves browser storage across tasks
Quick start
MCP
The package now exposes the MCP server binary directly:
npx -y web-task-api
That launches the stdio MCP server.
The HTTP runtime remains available separately:
npx -y -p web-task-api web-task-api-http
MCP tools
webtask_run
webtask_get_task
webtask_list_recipes
webtask_create_session
webtask_list_sessions
webtask_get_session
webtask_update_session
webtask_health
MCP config examples
- Claude Code:
examples/claude.mcp.json
- OpenCode:
examples/opencode.json
API
POST /v1/tasks/run
Runs a browser task synchronously and returns structured results.
Example request is in examples/demo-task.json.
GET /v1/tasks/:taskId
Returns the persisted run record with step trace and artifact paths.
GET /v1/recipes
Lists registered recipes.
POST /v1/sessions
Creates a reusable session for connected tasks. Sessions can carry:
- guest vs profile mode
- default start URL
- default planner config
- notes
- compact task history
GET /v1/sessions
Lists saved sessions.
GET /v1/sessions/:sessionId
Returns session metadata and recent task history.
PATCH /v1/sessions/:sessionId
Updates session metadata like notes, default start URL, or the bound profile for an existing profile-mode session. Guest sessions cannot be rebound into named profiles by patch.
GET /health
Basic health endpoint.
TypeScript client
Software can use the bundled client:
import { WebTaskApiClient } from "web-task-api"
const client = new WebTaskApiClient({ baseUrl: "http://127.0.0.1:4317" })
const session = await client.createSession({
name: "axiom trader",
mode: "profile",
profile: "axiom",
notes: "Authenticated Axiom trading session"
})
const result = await client.runTask({
goal: "Extract token name and price",
startUrl: "https://example.com",
sessionId: session.id,
agent: { kind: "auto" },
})
Connected tasks with sessions
Sessions let related web tasks share:
- browser/profile identity
- guest-session cookies and local storage across tasks
- default start URL
- planner defaults
- recent task context
Example pattern:
- Create session for
axiom profile
- Run login/manual warmup task once
- Run later research/action tasks with the same
sessionId
- Inspect session history to see what the agent already found
Guest sessions also work: create a mode: "guest" session and repeated tasks will preserve browser storage between runs under that session ID.
For protected recipes, that guest session still needs to be warmed first before you rely on it as a continuity source.
Browser profiles
To create a reusable login profile:
npm run profile:login -- --id my-profile --url https://example.com/login
This opens a real persistent browser profile. Log in manually or solve bot challenges, then press Enter in the terminal. The runtime saves a reusable Chromium user-data directory at profiles/<id>/user-data-dir and later tasks can use "profile": "my-profile".
This matters for sites like Dexscreener or GMGN that may block fresh headless sessions behind Cloudflare or similar anti-bot checks.
If you want the runtime to behave as closely as possible to your normal local Chrome, you can also point it at an existing browser profile:
BROWSER_USER_DATA_DIR=/path/to/your/chrome/profile
That is the closest match to “it works in my Chrome already”.
Planner backends
Recommended: CLIProxyAPI
This is the default non-mock path to avoid tying the system too tightly to OpenCode.
CLIProxyAPI is treated as a multi-provider router, not a single-provider API key wrapper. You can point this product at any model alias/provider path exposed by your CLIProxy setup.
Useful environment variables:
CLIPROXY_BASE_URL — default http://127.0.0.1:8317/v1
CLIPROXY_AUTH_TOKEN — optional client token if your CLIProxy instance requires one
CLIPROXY_MODEL — planner model alias/name exposed by your proxy, for example whatever provider/model mapping you configured there
Example:
{
"agent": {
"kind": "cliproxy"
}
}
Easiest local path right now: auto
If your GPT/OAuth is already working through local OpenCode, use:
{
"agent": {
"kind": "auto"
}
}
auto probes CLIProxy first and uses it when reachable/authenticated and a planner model is configured; otherwise it falls back to OpenCode so the product can still use your existing local auth/runtime. This path is verified locally against the fixture flow; for real sites, treat it as the recommended runtime path, not a guarantee that every protected site will work without profile warmup.
Optional: OpenCode
If you already run OpenCode headless and want to reuse that stack, the project also supports an OpenCode planner adapter.
Useful variables:
OPENCODE_BASE_URL
OPENCODE_MODEL
Then use:
{
"agent": {
"kind": "opencode"
}
}
Main files
docs/design.md — architecture, decisions, and implementation plan
docs/releasing.md — tag-driven release flow and MCP registry packaging notes
src/ — server, runtime, agent, browser, and storage code
tests/ — end-to-end verification with a local fixture site
scripts/ — demo runner and profile bootstrap
References