@thehappyboy/opencli-mcp-http
v0.1.2
Published
HTTP MCP server wrapping opencli — managed MCP for Claude Desktop 3p with persistent tool authorization
Maintainers
Readme
opencli-mcp-http
HTTP MCP server wrapping opencli — designed for Claude Desktop 3p managed MCP with persistent tool authorization.
16 browser automation tools that automatically use your existing Chrome login state (cookies, including HttpOnly).
Why HTTP / managed MCP?
Claude Desktop 3p runs in a VM sandbox. Only MCP connections can cross the VM boundary, but standard stdio MCP requires clicking "Allow Once" for every tool call. Managed MCP (HTTP transport) lets you authorize tools once and they stay authorized.
This server exposes the same opencli browser tools over HTTP, so Claude Desktop 3p can connect via URL with persistent authorization.
Architecture
Claude Desktop 3p (VM) ──HTTP──> Express + MCP Streamable HTTP (port 31337)
│
│ POST /command X-OpenCLI: 1
▼
opencli daemon (127.0.0.1:19825)
│
▼
Chrome Extension → BrowserPrerequisites
Install opencli + Chrome extension:
npm install -g @jackwener/opencli # Install the Chrome extension from: # https://chromewebstore.google.com/detail/opencli/ildkmabpimmkaediidaifkhjpohdnifk opencli doctor # verify all greenNode >= 18
Install
npm install -g @thehappyboy/opencli-mcp-http
opencli-mcp-http --install-daemon # installs launchd daemon, auto-starts on loginAfter this, the server is always running at http://127.0.0.1:31337/. You never need to start it manually.
Manual start (for testing)
npx -y @thehappyboy/opencli-mcp-httpDaemon management
# Check status
curl http://127.0.0.1:31337/health
# Stop daemon
launchctl unload ~/Library/LaunchAgents/com.opencli.mcp-http.plist
# Start daemon
launchctl load ~/Library/LaunchAgents/com.opencli.mcp-http.plist
# View logs
tail -f ~/Library/Logs/opencli-mcp-http.logRunning
The server listens on http://127.0.0.1:31337 (all paths route to MCP).
Health check
curl http://127.0.0.1:31337/health
# {"status":"ok","name":"opencli-mcp-http","version":"0.1.0","tools":16}Claude Desktop 3p — Managed MCP Configuration
在 ~/Library/Application Support/Claude-3p/configLibrary/<YOUR_UUID>.json 中添加 managedMcpServers 数组:
{
"managedMcpServers": [
{
"name": "opencli",
"url": "http://127.0.0.1:31337/",
"toolPolicy": {
"browser_open": "allow",
"browser_navigate": "allow",
"list_tabs": "allow",
"select_tab": "allow",
"close_tab": "allow",
"browser_state": "allow",
"browser_get": "allow",
"browser_find": "allow",
"browser_frames": "allow",
"browser_screenshot": "allow",
"browser_click": "allow",
"browser_type": "allow",
"browser_select": "allow",
"browser_scroll": "allow",
"browser_back": "allow",
"exec_in_tab": "allow"
}
}
]
}After configuring, restart Claude Desktop 3p. All 16 opencli tools appear with persistent authorization — no more "Allow Once" prompts.
Claude Code — Plugin (optional)
This package also works as a Claude Code plugin via stdio:
claude --plugin-dir /path/to/opencli-mcp-httpOr register directly:
claude mcp add --scope user opencli-http -- node /path/to/opencli-mcp-http/bin/server.jsTools (16)
Tab management
| Tool | Description |
|---|---|
| browser_open(url) | Open URL in a NEW tab. Chrome auto-attaches login cookies. |
| browser_navigate(url, tab_id) | Navigate existing tab to a new URL. |
| list_tabs() | List all tabs in the automation window. |
| select_tab(tab_id) | Make a tab active. |
| close_tab(tab_id) | Close a tab. |
Inspection
| Tool | Description |
|---|---|
| browser_state(tab_id) | Get URL/title/viewport + interactive-elements list. |
| browser_get(what, target?, tab_id) | Get title / url / html / text-of-selector. |
| browser_find(css, limit?, text_max?, tab_id) | CSS-selector search. |
| browser_frames(tab_id) | List cross-origin iframes. |
| browser_screenshot() | PNG of active tab. |
Interaction
| Tool | Description |
|---|---|
| browser_click(target, tab_id) | Click element by CSS selector. |
| browser_type(target, text, tab_id) | Set input/textarea value with proper events. |
| browser_select(target, option, tab_id) | Pick <select> option. |
| browser_scroll(direction, amount?, tab_id) | Scroll up/down. |
| browser_back(tab_id) | Browser history back. |
Core
| Tool | Description |
|---|---|
| exec_in_tab(tab_id, code) | Execute arbitrary JS. Use fetch(..., {credentials:'include'}) to call same-origin APIs with full login state. |
Typical workflow
User: "Check my recent 5 Yuque docs"
LLM:
1. tabId = browser_open("https://www.yuque.com")
→ Chrome already has yuque cookies, fully authenticated
2. exec_in_tab(tabId, `(async()=>{
const r = await fetch('/api/v2/users/me/docs?limit=5', {credentials:'include'});
return await r.json();
})()`)
→ returns JSON directly
3. close_tab(tabId)Environment variables
| Variable | Default | Description |
|---|---|---|
| PORT | 31337 | HTTP server port |
Limitations
- Automation window only —
list_tabsreturns tabs in opencli's automation window, not your daily Chrome tabs. - Single Chrome profile — uses the profile where the opencli extension is installed.
- Active tab for screenshot —
browser_screenshotcaptures the active tab; useselect_tabfirst. - localhost only — server binds to
127.0.0.1for security. For VM access, configure port forwarding or use a reverse proxy.
License
MIT
