Over-ambitious
Client game + websocket + server-side resolver + FSM + chips + accounts + WebMCP extension. And the house bot. Most of it was up, and it was still too much.
A pivot story, and what I built from its ashes.
Vin Lim · autobrowser.dev
After running through many ideas I settled on AgentHoldem, a hackathon project where agents play Texas Hold'em against each other, driven by WebMCP, paid in Bitcoin.
Agents playing each other. Sounds like fun.
Fast-paced play demands structured tools, not DOM scraping.
Poker + crypto is a natural fit. Blocknomics-friendly by design.
Live at agentholdem.xyz. Agents battle at the table, a reasoning log on the right shows every thought and action. WebMCP under the hood.
Gaming is addictive. If I could get people to play, traction would take care of itself.
Three trends converging. Demo-ready hackathon scope. A narrative that writes itself. What could go wrong?
Client game + websocket + server-side resolver + FSM + chips + accounts + WebMCP extension. And the house bot. Most of it was up, and it was still too much.
Real money in a hot wallet attracts the wrong attention. I wasn't ready to defend it, and shipping something I can't defend is worse than not shipping.
Gaming is addictive until someone else plays for you. Agentic poker removes the fun, especially when you're paying tokens for the agent to have it.
“I'm almost all in. If I pivot, I lose time for traction. If I carry on, I'm unlikely to get traction anyway.”
Sunk cost is real. So is the cost of the wrong road.
Of the three pillars, one was a feat of engineering on its own: the WebMCP Agent Orchestrator for Chrome. I couldn't stop building it. So I stopped building everything else.
Not the most ambitious thing half-built. The AgentHoldem stack had ten working parts but no single one I could demo without apologising for the other nine.
Security posture isn't optional, even for demos. The moment real money is in reach, you're the adversary's target. If you're not ready to own that, the right answer is to not handle money.
Not the most valuable part on paper. Not the part closest to traction. The part your hands keep returning to when nobody's watching. Of AgentHoldem's three pillars, only one survived contact with the second-thought.
An AI agent that actually uses your browser.
No backend. The service worker holds per-tab state in
chrome.storage.local; everything else runs in your browser.
Break the goal down into 1–3 concrete next steps.
Read the current page state and pick what applies now.
Call one tool (WebMCP first, then CDP) and run it.
Did it actually take effect? Check with read-only tools.
Something went wrong. Diagnose, replan, or bail cleanly.
Each turn emits one decision object. The phase field tells the orchestrator what to do next. No free-text loop, no regex parsing.
// src/llm/react-schema.js { "phase": "plan" | "analyze" | "act" | "verify" | "recover", "narration": "≤15-word user-facing label", "tool": "tool_name" | null, "args": { /* tool arguments */ }, "final_answer": "task_complete prose" | null }
Think of it like a hiker's logbook. Before every step the agent checks: where am I, where have I been, what worked, what failed. So it doesn't walk into the same wall twice.
Most agents just shrink chat history to fit. We keep a live ledger of observations, routes, and attempted actions.
Result: fewer wasted turns, smaller prompts, better decisions. src/llm/working-memory.js
Cloud · 200K ctx
Access to reasoning models across Anthropic, OpenAI, Google. Default pick.
Cloud · 1M ctx
Extended thinking via thinkingConfig. First-class for long tasks.
Your server · Ollama, vLLM
Bring your own model, your own weights, your own network. Zero egress.
On-device · Gemini Nano
Private by construction. Multimodal Blob pass-through, no base64 hop.
One LLMProvider contract:
availability · call · supportsModality · dispose.
Tool calls, streamed tokens, and reasoning (native or
schema-faked) all surface through the same onThought
callback. The ReAct loop doesn't know which one answered.
WebMCP gives the agent a typed contract instead of a screenshot to guess from. That single choice shapes everything Auto Browser does.
Page authors register tools with real parameters, like
addToCart({sku, qty}). The agent calls them
directly. No guessing which button is "Add to cart".
Parsing the DOM or a screenshot is slow. Calling a typed function isn't. Tool turns cost 20–100 tokens instead of 2000+, so the agent replies in a fraction of the time. Fast enough for agent-vs-agent games, live dashboards, anything where latency matters.
Your CSS refactor doesn't break the agent. Your A/B test doesn't either. The tool contract is the stable layer, whatever happens to the pixels.
Structured args in, structured results out.
requestUserInteraction() pauses for consent on anything
irreversible. Every call is a log line you can read.
When a page has WebMCP, its tools come first. When it doesn't, Auto Browser falls back on a CDP-backed toolkit, so the agent is never stuck. Every tool is permission-gated: read-only calls run silently, mutating ones ask once per domain.
WebMCP tools from pages shadow built-ins with the same name. Page-authored contracts always win.