Package Exports
- @thinkrun/mcp
- @thinkrun/mcp/dist/src/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@thinkrun/mcp) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@thinkrun/mcp
MCP (Model Context Protocol) server for ThinkRun. Gives AI agents the ability to control your actual Chrome browser — with all your cookies and active sessions — or a cloud browser for headless automation.
Why ThinkRun vs Playwright MCP
| Capability | ThinkRun MCP | Playwright MCP |
|---|---|---|
| Uses your real Chrome cookies | ✅ Local mode — browse as you | ❌ Fresh context, no auth |
| Access sites you're logged into | ✅ LinkedIn, Salesforce, internal tools | ❌ Requires scripted login every time |
| Cloud headless sessions | ✅ Isolated Playwright browser on demand | ❌ Local browser only (no ThinkRun cloud) |
| Runtime local ↔ cloud switching | ✅ set_mode tool, no restart |
❌ Single mode per server |
| Structured content extraction | ✅ Reader layer (articles, structured data) | ❌ Raw DOM access only |
| Session recording + sharing | ✅ Full video, screenshots, AI analysis | ❌ |
| Persistent sessions | ✅ Resume across agent invocations | ❌ Single-run only |
| Direct browser actions | ✅ Browser tools + local_action_* |
✅ Browser tools |
| AI task planning | ✅ task_create / task_execute |
❌ |
TL;DR: Use ThinkRun when you need to browse as yourself (authenticated sites, internal tools). Use Playwright MCP for stateless public-web automation.
For the current checked-in parity contract and its supporting evidence, see:
Installation
First-run local setup
Use this path when you want the MCP server to control your real Chromium browser with your existing cookies and logged-in sessions:
npx @thinkrun/mcp doctor
npx @thinkrun/mcp install-native-host
npx @thinkrun/mcp doctorThen open or reload Chrome with the ThinkRun extension enabled. doctor will tell you exactly what is missing: extension, native-host manifest, native-host binary, bridge port file, extension connection, or cloud API key.
install-native-host writes the ThinkRun native-host binary/config and browser native-messaging registration under your user profile. It delegates to a pinned compatible @thinkrun/cli installer so the download, checksum, and manifest behavior stay on the same path as the CLI.
On Windows, Chrome native messaging registration is stored in the registry. doctor reports that registry inspection as limited instead of treating the missing macOS/Linux manifest file as a setup failure.
Claude Code
claude mcp add thinkrun --transport stdio \
-e THINKRUN_API_KEY=your-key \
-- npx @thinkrun/mcpClaude Desktop / Cursor / VS Code
Add to your MCP config file:
| Tool | Config file |
|---|---|
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Cursor | .cursor/mcp.json in project root |
| VS Code (Copilot) | .vscode/mcp.json in project root |
Auto mode (recommended) — tries local Chrome first, falls back to cloud:
{
"mcpServers": {
"thinkrun": {
"command": "npx",
"args": ["@thinkrun/mcp"],
"env": {
"THINKRUN_API_KEY": "your-key"
}
}
}
}Local only (Chrome extension, no API key needed):
{
"mcpServers": {
"thinkrun": {
"command": "npx",
"args": ["@thinkrun/mcp", "--mode", "local"]
}
}
}Cloud only:
{
"mcpServers": {
"thinkrun": {
"command": "npx",
"args": ["@thinkrun/mcp", "--mode", "cloud"],
"env": {
"THINKRUN_API_KEY": "your-key"
}
}
}
}Security note: MCP config files (.cursor/mcp.json, .vscode/mcp.json) are often committed to git. Use environment variable references where supported, or add these files to .gitignore to avoid leaking your API key.
Global install (alternative)
npm install -g @thinkrun/mcp
thinkrun-mcp --mode autoModes
| Mode | Backend | Requires |
|---|---|---|
auto |
Tries local first, falls back to cloud | Either of the below |
local |
Chrome extension + native host | Chrome with ThinkRun extension |
cloud |
ThinkRun REST API (Fly.io) | API key from thinkrun.ai |
Page cache tools (page_cache_html, page_cache_text, page_cache_screenshot): stateless POST /api/cache/* on the service. In local mode, set THINKRUN_BASE_URL and THINKRUN_API_KEY (or pass --base-url / --api-key so the native host client can reach the API — the native host itself has no /api/cache routes).
Runtime switching: Use the set_mode tool to switch between local and cloud without restarting.
Local mode setup
MCP Server ──HTTP──> Native Host ──stdio──> Chrome Extension ──> Chrome tabs- Install the ThinkRun Chrome extension
- Diagnose setup:
npx @thinkrun/mcp doctor - Install/register the native host:
npx @thinkrun/mcp install-native-host - Open or reload Chrome with the extension enabled
- Verify:
npx @thinkrun/mcp doctor - Add MCP config above
For unpacked/dev extensions, pass the browser extension ID explicitly:
npx @thinkrun/mcp install-native-host --extension-id <id>Available Tools (53 + 1 optional)
53 tools are always registered.
set_modeis registered when the server is started with mode-switch support (the default CLI binary enables it).
Session Lifecycle
| Tool | Description | Modes |
|---|---|---|
session_create |
Create a new browser session | all |
session_status |
Get session URL, title, action count | all |
session_delete |
Terminate session, preserve artifacts | all |
session_list |
List all active sessions | all |
session_wait_ready |
Poll until session is ready (use after create in cloud mode) | all |
session_use |
Set default session ID for subsequent tool calls | all |
set_auditing |
Enable or disable local audit mode for the current tab-backed session | local |
session_release |
Release the current local session ownership without closing the tab | local |
session_artifacts |
List screenshots and recordings for a session | cloud |
Mode Switching
| Tool | Description | Modes |
|---|---|---|
set_mode |
Switch between local/cloud/auto at runtime without restart | all |
Stateless Page Cache
| Tool | Description | Modes |
|---|---|---|
page_cache_html |
Fetch rendered HTML without creating a session | all |
page_cache_text |
Extract plain text without creating a session | all |
page_cache_screenshot |
Capture a screenshot without creating a session | all |
Navigation
| Tool | Description | Modes |
|---|---|---|
navigate |
Go to a URL, wait for page load | all |
go_back |
Navigate back in browser history | all |
go_forward |
Navigate forward in browser history | all |
wait_for_element |
Wait for a CSS selector to appear | all |
Interaction
| Tool | Description | Modes |
|---|---|---|
click |
Click an element by CSS selector with button, count, delay, and timeout controls | all |
click_at |
Click at viewport-relative CSS pixel coordinates | local |
type_text |
Type text into an element (appends, optional delay control) | all |
fill |
Fill a form field (replaces content) | all |
press_key |
Press a keyboard key (Enter, Tab, Escape, etc.) | all |
scroll |
Scroll the page or a specific element using x/y or CLI-style direction/amount/to aliases |
all |
hover |
Hover over an element (triggers tooltips/menus) | all |
select_option |
Select from a <select> dropdown |
all |
Observation
| Tool | Description | Modes |
|---|---|---|
snapshot |
Get accessibility tree (lightweight page overview) | all |
screenshot |
Capture page screenshot (png/jpeg/webp, full-page or selector-targeted). MCP returns inline image content and includes artifact metadata when available. | all |
extract |
Extract text, HTML, DOM data, evaluated results, or element attributes; supports selector scoping and multi-match extraction | all |
evaluate |
Run JavaScript in the page context with optional timeout control | all |
get_url |
Return the current page URL | all |
get_title |
Return the current page title | all |
get_html |
Return current page HTML with explicit truncation metadata when large | all |
sleep |
Pause for a bounded duration in milliseconds | all |
Tab Management
| Tool | Description | Modes |
|---|---|---|
tab_list |
List all open browser tabs | local |
tab_new |
Open a new tab (optionally with URL) | local |
tab_close |
Close a tab by ID | local |
tab_attach |
Attach to an existing local tab and bind it as the default session | local |
tab_switch |
Switch the active local browser tab without rebinding the default session | local |
focus |
Bring the currently bound local browser tab/window to the foreground | local |
window_new |
Open a new local browser window and bind it as the default session | local |
Dialog Handling
| Tool | Description | Modes |
|---|---|---|
get_dialog |
Check for open alert/confirm/prompt dialogs | all |
handle_dialog |
Accept or dismiss a dialog with optional text | all |
Wait
| Tool | Description | Modes |
|---|---|---|
wait_for_text |
Wait for specific text to appear on the page | all |
Monitoring
| Tool | Description | Modes |
|---|---|---|
console_messages |
Get browser console messages (log, warn, error) | all |
network_requests |
Get network requests made by the page | all |
clear_logs |
Clear console and network logs for a clean capture | all |
Local Actions
| Tool | Description | Modes |
|---|---|---|
local_action_run |
Run a direct native-host action against the currently attached local tab | local |
local_action_status |
Check the status of a previously started local action | local |
local_action_cancel |
Cancel a running local action | local |
Local Diagnostics And Recovery
| Tool | Description | Modes |
|---|---|---|
local_diagnostics |
Inspect the current local continuity, lock owner, reclaim audit, and bridge recovery state | local |
local_reset_connection |
Reset the local bridge connection using the bounded circuit-breaker recovery path | local |
Task Planning
| Tool | Description | Modes |
|---|---|---|
task_create |
Create an AI task plan from natural language | cloud |
task_execute |
Execute a task plan | cloud |
task_status |
Check task execution status | cloud |
Hosted Remote Browser Control
ThinkRun also supports a hosted remote-agent flow for agents that are not running on the same machine as the browser.
This flow does not create a second browser-control surface. Hosted MCP remote browser access still goes through the same ThinkRun backend session APIs and ext-* relay path used by the existing browser control layer.
Remote-agent control tools
| Tool | Purpose |
|---|---|
agent_identity |
Return the remote agent identity and link state |
browser_request_control |
Request a short-lived user-approved browser control grant |
browser_grant_status |
Poll request/grant status |
browser_release_control |
Cancel a pending request or revoke an active grant |
V1 rules
- remote agents authenticate as themselves with remote-agent credentials, not with the user's ThinkRun API key
- the user must already know and link the agent before browser access can be granted
- approval requires a logged-in ThinkRun session plus a live extension-connected browser session
- mutating scopes still require extension confirmation before use
- every remote command is authorized against live backend grant state
evaluateremains denied for remote agents in v1 even if requested
Hermes / OpenClaw notes
For Hermes/OpenClaw-style agents running remotely:
- register the agent and link it to the user account
- call
browser_request_control - wait for app approval and extension confirmation
- use normal browser tools once the grant is active
- release with
browser_release_control
V1 usefulness is intentionally biased toward non-evaluate flows: snapshot, screenshot, click, fill, waits, tab tools, and artifact tools.
Remote workflows without evaluate
Remote-agent workflows in v1 should assume evaluate is unavailable even if a requested scope mentions it.
Recommended pattern:
browser_request_controlbrowser_grant_statussnapshotto inspect page structureextractfor text, HTML, or attributesclick/fill/type_textwait_for_elementorwait_for_textscreenshotfor visual confirmationbrowser_release_control
Good first-fit remote tasks in v1:
- inspect a dashboard and read current status
- click a refresh button and wait for updated text
- fill and submit ordinary non-sensitive form fields
- switch tabs and capture screenshots or artifacts
Not part of the default v1 path:
- arbitrary script execution
- password-field automation
- auth or payment submission flows
- destructive account actions on sensitive surfaces
Claude.ai compatibility
Claude-compatible hosted MCP clients can use the same request/grant/release contract, but v1 does not block release on unverified Claude.ai-specific connector or transport requirements outside the current ThinkRun MCP protocol surface.
If a Claude.ai integration has connector-specific auth or transport constraints, treat that as an integration concern rather than a reason to widen the remote browser authorization model.
Safety summary
- no remote direct connection to the extension WebSocket
- no approval authority in email links
- no
evaluatefor remote agents in v1 - sensitive-domain and high-risk operation blocking
- audited request/grant/command lifecycle
See docs/remote-browser-sharing.md for the user/admin model, operator runbook, and release checklist.
Local Session Semantics
The new local lifecycle tools intentionally distinguish between ownership-changing operations and focus-only operations:
tab_attachrebinding: attaches to an existing local Chrome tab and sets it as the default session for subsequent session-scoped tool calls.window_newrebinding: opens a fresh local window and sets the resulting tab as the default session.tab_switchfocus-only: changes the active local browser tab, but does not steal or rewrite the current default session just because browser focus changed.focusfocus-only: foregrounds the currently bound local tab/window without rebinding or switching the default session.session_releaseclearing: releases the current local session ownership and clears the default session when that bound local context is released.
Lock safety follows the same high-level contract as the CLI:
- contested live local locks fail explicitly
- same-owner rebinds can succeed idempotently
- stale locks may be replaced only when the existing owner is no longer live
This package also exposes structured local diagnostics and bounded recovery rather than full CLI admin commands:
local_diagnosticsis the MCP equivalent for continuity/bridge truth that CLI users get fromdoctorandsession debuglocal_reset_connectionis the MCP equivalent for the CLI’s boundedreset-connectionrecovery path- install/bootstrap/config flows remain CLI-only
This package now exposes the CLI's local native-host execution flow as:
local_action_runlocal_action_statuslocal_action_cancel
The naming is intentional:
actionmeans a direct operation against a browser contexttaskmeans a higher-level cloud multi-step planning/execution workflow
CLI Options
thinkrun-mcp [options]
Options:
--mode <mode> cloud, local, or auto (default: auto)
--api-key <key> API key for cloud mode (or set THINKRUN_API_KEY)
--base-url <url> Cloud API URL (default: https://api.thinkrun.ai)
--port <port> Override native host port
--session-id <id> Default session ID (enables session_use)
-h, --help Show help
-v, --version Show versionEnvironment Variables
| Variable | Description |
|---|---|
THINKRUN_API_KEY |
API key for cloud mode |
THINKRUN_BASE_URL |
Cloud API base URL |
THINKRUN_BRIDGE_PORT |
Override native host port |
THINKRUN_LOCAL |
Set to true to force local mode |
Port Discovery
The native host writes its port to ~/.thinkbrowse/port on startup. This path stays stable until the native-host cutover moves it to ~/.thinkrun/port. The MCP server reads this automatically.
Priority: --port flag > THINKRUN_BRIDGE_PORT env > ~/.thinkbrowse/port > 3012
Testing
# Unit tests
bun test
# Smoke test — full session lifecycle against cloud
THINKRUN_API_KEY=your-key bun run scripts/smoke-mcp-parity.ts
# Manual local parity smoke — requires live native host + extension bridge
bun run smoke:local-parity
# Manual local parity soak — repeats the same local parity assertions
THINKRUN_MCP_SOAK_ITERATIONS=50 bun run soak:local-parity
# Smoke test — clear_logs only
bun run test:smokeProgrammatic Usage
Basic:
import { createServer, CloudClient } from '@thinkrun/mcp';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const client = new CloudClient({
baseUrl: 'https://api.thinkrun.ai',
apiKey: process.env.THINKRUN_API_KEY!,
});
const server = createServer(client);
await server.connect(new StdioServerTransport());With runtime mode switching:
import { createServer, CloudClient } from '@thinkrun/mcp';
import type { ClientRef } from '@thinkrun/mcp';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const client = new CloudClient({
baseUrl: 'https://api.thinkrun.ai',
apiKey: process.env.THINKRUN_API_KEY!,
});
const clientRef: ClientRef = { current: client };
const server = createServer(client, {
clientRef,
onSetMode: async (mode) => {
// Return a new client for the requested mode
return new CloudClient({ baseUrl: '...', apiKey: '...' });
},
});
await server.connect(new StdioServerTransport());License
MIT