
Why should Claude be the only one with a browser? Orvima gives any MCP-capable AI (Claude, Cursor
Why should Claude be the only one with a browser? Orvima gives any MCP-capable AI (Claude, Cursor, Copilot, your own agent) eyes and hands on your own Chrome or Edge — your logins, your machine, your watch. Self-hosted, local-first, MIT. MCP-native browse_* tools + live viewport.
·
Your browser, driven by any AI — with a live viewport you control.
Orvima is a self-hosted, local-first agent that gives any MCP-capable AI tool (Claude, Cursor, Copilot, your own agent) 49 tools across 8 domains - browser, mail, WhatsApp, voice, media, math, science, and a safety gate - all running on your own machine against your own browser, your own logins, and your own data. Navigate, click, type, extract, verify, send email, message on WhatsApp, speak with a distinctive voice, fetch YouTube transcripts, solve equations, convert units, and classify risk - all while you watch every step in a live viewport and stop it whenever you like.
any AI tool MCP / stdio +--------------------+
(Claude, Copilot, │ | Orvima (localhost) |
Cursor, your agent) └────browse_*──────▶| YOUR browser with |
| your logins |
| live viewport |
| pause / approve |
+--------------------+No cloud, no API key to try it, no account. Install it, point your AI at it, done.
| Domain | Tools | What they do |
|---|---|---|
| browser | 22 | Navigate, click, type, fill, select, scroll, snapshot, screenshot, extract, eval, tabs, wait, download, set files |
| 2 | Send email (SMTP), read inbox (IMAP) | |
| 5 | Status, list chats, read messages, send, react (via parley/WhatsApp Desktop) | |
| voice | 4 | Speak (Edge TTS + Ultron modulation), listen (Whisper STT), set/list styles |
| media | 4 | YouTube transcript, YouTube search, music search, music play |
| compute | 7 | Math solve/simplify/derivative/integral/plot, unit convert, science constants |
| gate | 3 | Risk classify, describe action, check risk concepts (sentinel-backed) |
| router | 2 | List recipes, route goal to reviewed recipe or refuse (errands-backed) |
All tools are plain dict-in, dict-out over one contract. Credentials come from environment variables, never hardcoded. Everything runs on 127.0.0.1.
| Live viewport | See exactly what the agent sees — frames stream in real time via SSE. |
| Human-in-the-loop | Pause or resume a run at any time. An optional fail-closed approval gate holds risky actions for a human - see Approvals. |
| Verified steps | Every action confirms the DOM result (snapshot) before the agent proceeds — no silent failures, no guessed success. |
Local-first. Everything runs at 127.0.0.1. Your cookies, sessions and scrapes never leave your computer. Bring your own brain: plug in any OpenAI-compatible model (OpenAI, OpenRouter, Groq, local Ollama), or use your MCP client (Claude, Cursor, Copilot) as the brain.
# Windows (PowerShell)
irm https://raw.githubusercontent.com/Sachitt-AV-08/orvima/main/install.ps1 | iex
# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/Sachitt-AV-08/orvima/main/install.sh | shAgainst a real browser — your own Chrome, Edge or Brave. The default, so there is no flag to get wrong:
orvima serve # local dashboard + API at http://127.0.0.1:8301
orvima run "summarize the top story on hacker news"orvima serve puts a control dashboard at http://127.0.0.1:8301 — watch every step stream into a live viewport, pause or resume a run, and approve held actions. orvima run launches a browser you own, with a persistent profile so your logins survive restarts. Autonomous runs need a brain — set ORVIMA_LLM_BASE and ORVIMA_LLM_KEY (any OpenAI-compatible endpoint, including local Ollama) — or just drive it through MCP and let your assistant be the brain.
Plug your AI into it (MCP):
Copy the exact config for your client:
Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows):
{
"mcpServers": {
"orvima": {
"command": "orvima",
"args": ["mcp"],
"type": "stdio"
}
}
}Claude Code (add to your project or global config):
claude mcp add orvima orvima mcpCursor (.cursor/mcp.json in your project root):
{
"mcpServers": {
"orvima": {
"command": "orvima",
"args": ["mcp"],
"type": "stdio"
}
}
}Copilot / VS Code (settings.json):
{
"mcp": {
"servers": {
"orvima": {
"command": "orvima",
"args": ["mcp"],
"type": "stdio"
}
}
}
}These configs start a real browser — that is the default, so there is no --mode flag to get wrong. Add --mode demo if you specifically want the offline simulator.
Then just tell your assistant things like
"open the top hacker news story and summarize the comments".
It will browse_navigate, browse_snapshot, and report back — verified, not guessed.
The real browser (this is the default):
Orvima launches your installed Chrome, MS Edge or Brave — visible, with a persistent profile at ~/.orvima/profile, so your logins survive restarts. Your everyday profile is never touched. Want it to drive the browser you already have open?
orvima serve # watch it work at :8301
orvima run "compare prices on two flights" # autonomous, needs a brainFor autonomous orvima run, give it a brain — any OpenAI-compatible endpoint (OpenAI, OpenRouter, Groq, or local Ollama):
export ORVIMA_LLM_BASE=http://localhost:11434/v1 # or https://api.openai.com/v1
export ORVIMA_LLM_KEY=sk-… # ORVIMA_LLM_MODEL=llama3.1 (default gpt-4o-mini)Attach to a browser you already have running (parley-style, over CDP):
orvima --attach http://127.0.0.1:9222 mcpStart that browser with --remote-debugging-port=<port> to expose the endpoint.
Against a browser you actually use every day, add --attach-tab. Chromium's
browser-level connect_over_cdp enumerates and auto-attaches to every target
before the handshake completes, so a profile with extension service workers,
reCAPTCHA iframes and a dozen open tabs can stall it indefinitely — we measured
one still hanging at 90s with no other client attached. Naming a single tab skips
that enumeration and returns in milliseconds:
export ORVIMA_ATTACH_TAB=linkedin.com # substring of the tab url or title
orvima --attach http://127.0.0.1:9335 mcpIf the endpoint answers but the handshake still stalls, attach fails fast rather
than hanging — ORVIMA_ATTACH_TIMEOUT (default 10s) bounds the wait, and
ORVIMA_TYPE_DELAY_MS (default 0) sets per-character typing delay.
--browser {chrome,msedge,brave,chromium}, --attach <cdp-url>, --headless, --max-steps are global flags — they work with any subcommand.
--mode demo= offline simulator, opt-in. Perfect for CI and tours. no flag = your own installed browser, streaming frames to the dashboard (the default) flags:--browser {chrome,msedge,brave,chromium},--attach <cdp-url>,--headless,--max-steps
No browser, no internet, no keys? Try the offline tour instead:
orvima run "send a message to Acme support" --mode demoThat goal gets planned and executed step by step against Orvima's built-in simulator — the same browse_* tools, the same verify-every-step loop, nothing installed except orvima itself. Add --mode demo anywhere to stay there.
| Orvima | Playwright MCP | Chrome DevTools MCP | browser-use | |
|---|---|---|---|---|
| Live viewport | ✅ SSE stream | ❌ | ❌ | ❌ |
| Human approval | pause/resume always; optional fail-closed gate holds risky actions | ? | ? | ? |
| Verified steps | ✅ DOM-confirmed | ❌ | ❌ | ❌ |
| Your logins / your profile | ✅ persistent | ❌ fresh | ✅ your profile | ❌ fresh |
| Local-first / loopback only | ✅ | ✅ | ✅ | ✅ |
| MCP stdio | ✅ | ✅ | ✅ | ❌ |
| Any OpenAI-compatible brain | ✅ | ❌ | ❌ | ✅ |
| Offline demo / CI | ✅ | ❌ | ❌ | ❌ |
| Self-hosted, MIT | ✅ | ✅ | ✅ | ✅ |
Comparison based on verifiable features: live viewport, human-in-the-loop controls, DOM-verified actions, and profile persistence. "brain" flexibility refers to supporting any OpenAI-compatible endpoint vs. vendor-locked models.
| tool | does |
|---|---|
browse_navigate(url) | open a URL and wait for it to be interactive |
browse_click(selector) | click the first element matching a selector |
browse_hover(selector) | hover (reveals menus, tooltips) |
browse_type(selector, text) | type into a field character by character |
browse_fill(selector, text) | replace a field's value wholesale |
browse_select(selector, value) | pick an option in a dropdown |
browse_press(key) | press Enter / Escape / Tab / … |
browse_go_back() | one page back |
browse_wait(ms) | breathe (after submits, before verifying) |
browse_wait_for(selector) | wait until an element exists |
browse_scroll(direction) | down / up |
browse_snapshot() | the compact DOM outline agents plan from |
browse_extract(selector) | pull text out of one element |
browse_screenshot() | base64 PNG of the live viewport |
browse_eval(expression, reason) | run a JS expression - an escape hatch, not a sandbox. Refuses expressions that look irreversible, and reports mutating measured from a before/after DOM signature |
browse_eval_audit() | every browse_eval this session: expression, reason, effect |
browse_download(selector) | click something that downloads a file and save it locally; fails explicitly when no download starts |
browse_set_files(paths, selector) | attach files to an <input type=file>, and report what the page's own FileList ended up holding |
browse_open_tab(url) / browse_list_tabs() | multi-tab research |
browse_switch_tab(index) / browse_close_tab(index) | move between / close tabs |
browse_click and browse_navigate also take optional expectations - expect_url, expect_text, expect_count (+ expect_for). They are polled for up to expect_timeout_ms, because the result of a click is often asynchronous, and an unmet expectation is a hard error naming every mismatch rather than a verified: false you can ignore. Omit them and behaviour is exactly as before, with no extra keys in the result.
Every mutating tool (browse_click, browse_type, browse_fill, browse_select, browse_press, browse_navigate, browse_go_back, browse_wait_for, browse_open_tab, browse_switch_tab, browse_close_tab, browse_download, browse_set_files) returns {"ok": true, ...} with a verified flag after the page has confirmed the result. Read tools (browse_snapshot, browse_screenshot, browse_extract, browse_eval_audit, browse_hover, browse_wait, browse_scroll, browse_go_back, browse_list_tabs) return ok: true without a verified field. browse_eval returns mutating rather than verified, because "did anything change" is the wrong question for arbitrary JS.
What browse_eval does not do. It is not a sandbox. The guard matches destructive API names and guard words in the source text, so an expression that achieves the same effect another way will run. It raises the cost of a mistake; it does not make one impossible. Every call is recorded in the audit trail with the reason you stated, and the point of the audit is that you can read afterwards exactly what ran on a logged-in page.
Refs from a snapshot work anywhere, including inside frames (f2:e3), and survive re-render: a ref is a remembered identity, not a position. If the original element is gone, Orvima looks for a substitute and refuses rather than guessing when two candidates are equally good.
| piece | what |
|---|---|
src/orvima/browser.py | BrowserController — your Chrome/Edge/Brave (persistent profile or CDP attach) with verify-first ops |
src/orvima/cdp.py | page-level CDP client — attaches to a single open tab's own socket, skipping the browser handshake that stalls on busy profiles |
src/orvima/demo.py | DemoBrowser — the same surface, scripted, offline, CI-friendly |
src/orvima/tools.py | the browse_* tools as plain dict-in/dict-out functions |
src/orvima/planner.py | adaptive step-planner: LLMPlanner (any OpenAI-compatible endpoint) + DemoPlanner |
src/orvima/agent.py | sessions, the event bus, and the agent loop (snapshot → decide → act → verify) |
src/orvima/api.py | FastAPI app + SSE events (live frames, transcript, controls); serves the dashboard at / and the owner page at /owner |
src/orvima/dashboard.py | the control dashboard — one self-served HTML file, no framework, no CDN |
src/orvima/owner.py | the passphrase-gated owner analytics page + collect_analytics() |
src/orvima/mcp_server.py | MCP (stdio) binding so any AI tool can drive it |
src/orvima/cli.py | argparse CLI with demo/serve/mcp/run/doctor |
expect_url / expect_text / expect_count)browse_evalirm … | iex / curl … | sh)http://127.0.0.1:8301 — live viewport, pause/resume/cancel, approvals queue, owner analytics page (passphrase-gated)browse_download)Whether an action waits for you depends on how you started orvima and what is installed. This is worth stating plainly, because the three cases behave very differently and the failure mode in the second one looks like a broken install.
| How you run it | What actually happens |
|---|---|
orvima run (CLI) | Fully unattended. No gate is constructed; every action runs without being judged |
orvima serve (HTTP API), sentinel not installed | Every action waits for you, including reads like browse_snapshot. Nothing can be judged, so nothing is auto-approved |
orvima serve with sentinel installed | Only actions the gate flags are held for a human verdict |
ORVIMA_SENTINEL=off | Fully unattended, deliberately. Reported as gate: "off" at /api/gate/stats |
sentinel is an optional package and is not a declared dependency - not even
an extra. So the second row is what a fresh install from the GitHub Release
gives you (the sentinel extra is not pulled in): an API that holds every
action for approval because there is no classifier to judge it. That is the
fail-closed default working, and the refusal message tells you both ways out -
install sentinel, or set ORVIMA_SENTINEL=off and accept that nothing is
being checked.
Check what you have:
curl -s localhost:8000/api/gate/stats
# {"gate": "degraded", "available": false, ...} <- nothing is being judged
# {"gate": "on", "available": true, ...} <- judging is in force
# {"gate": "off", ...} <- deliberately unattendedon, degraded and off are kept distinct on purpose. "A human switched this
off" and "the gate failed to load" call for opposite responses, and collapsing
them is how a malfunction quietly becomes a policy.
What the gate is not: it is a classifier plus a word list, and it is wrong in both directions. A genuinely dangerous action behind an innocuously-worded button may pass; a harmless action may prompt. It reduces how much you have to read carefully. It does not replace judgement.
Orvima is loopback-only by default and stores nothing of yours remotely. It is a tool for your browser and your accounts: only run it on machines you trust, and never expose the API port publicly. Real-mode sessions use your real browser profile — an agent can act as you on the websites you are already logged into, in a browser you can physically watch. Pause it (browse_control / the UI), read the transcript, and let it do one thing at a time.
| Area | Status | Notes |
|---|---|---|
| CAPTCHAs / 2FA | ❌ Not supported | Human takeover (pause/resume) is the intended workflow |
| File dialogs | ❌ Not supported | Human takeover required |
| Browser updates | may break selectors | Fixture tests catch regressions; update fixtures when needed |
| CAPTCHAs on login | not solvable | Pause, solve manually, resume |
| Media playback | not supported | On roadmap. File downloads are supported via browse_download |
| Unreachable frames | partial | Same-origin iframes and shadow roots are traversed and get frame-scoped refs (f2:e3). A frame Chromium cannot read is listed in notTraversed with its src and the reason rather than silently missing |
These are honest constraints — not bugs. Orvima is designed for human-in-the-loop automation where the human handles the hard edge cases.
Orvima is free to self-host, but wiring it into your stack takes time. I'll do it for you.
Flat-scope, 48-hour tasks:
browse_click as destructive vs safe, hold payment steps for a humanPricing (INR, paid by UPI):
Contact: [email protected] — or reply on GitHub with one sentence about what you want automated.
Note: I'm under 18. A parent or guardian should be the contracting party so the agreement holds. The tech is mine; the paperwork is theirs.
MIT. Free forever. Self-host it, fork it, run it on your own boxes.
Made with care — and a browser that keeps its eyes on the page.
Pick your client and paste the snippet. Each one is the same server, written the way that client expects it.
claude mcp add orvima -- orvima mcp{
"mcpServers": {
"orvima": {
"args": [
"mcp"
],
"type": "stdio",
"command": "orvima"
}
}
}code --add-mcp '{"name":"orvima","args":["mcp"],"type":"stdio","command":"orvima"}'[mcp_servers.orvima]
command = "orvima"
args = ["mcp"]Runs locally on your device. Your client starts the server itself, so nothing has to be hosted.
Paste this prompt into your agent. It reads this page and does the setup for you.
Read https://aiagentslisting.com/mcp/orvima to learn what the "Orvima" MCP server does and how to install it. Add it to my coding agent's MCP configuration as documented on that page, then confirm the server connects and list the tools it exposes.Agents can also browse this directory over MCP at https://aiagentslisting.com/api/mcp
claude mcp add orvima orvima mcpThis server runs locally, so we can't read its tool list over the web yet.
We could not run this server: it ships no npx package for our sandbox and no public endpoint. The four checks that need a live server are left out, and the grade tops out at B until one exists.
Maintain this server? Claiming proves you own the listing and earns the last 4 points.
Claim this listingPaste this line near the top of your repository's README. The badge always renders the current score.
[](https://aiagentslisting.com/mcp/orvima)Nothing comparable is listed yet.
v0.1.6Orvima v0.1.6Release notesv0.1.5Orvima v0.1.5Release notesv0.1.4Orvima v0.1.4Release notesv0.1.3Orvima v0.1.3Release notesv0.1.2Orvima v0.1.2Release notesv0.1.1Orvima v0.1.1Release notesv0.1.0Orvima v0.1.0Release notesConnect to the AI Agents Listing MCP server at https://aiagentslisting.com/api/mcp using the HTTP transport and complete the sign-in when it asks. Then call the submit_review tool for the listing "orvima" with a rating from 1 to 5 and a short note on what worked and what did not.One email a week. New agents, MCP servers and skills, and what is actually getting traction.