MCP Server
Set up BabelWrap as an MCP server and give your AI agent the ability to browse, interact with, and extract data from any website.
Setup
Installation
Install the BabelWrap MCP server package using your preferred method:
# Using pip
pip install babelwrap-mcp
# Using uvx (recommended -- no install required)
uvx babelwrap-mcp
# Using pipx (isolated environment)
pipx install babelwrap-mcp
uvx, you do not need to install the package. The MCP client will download and run it automatically each time.Claude Desktop Configuration
Add BabelWrap to your Claude Desktop configuration file. The file location depends on your operating system:
| OS | Config Path |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
| Linux | ~/.config/Claude/claude_desktop_config.json |
Add the following to your config file (using uvx):
{
"mcpServers": {
"babelwrap": {
"command": "uvx",
"args": ["babelwrap-mcp"],
"env": {
"BABELWRAP_API_KEY": "bw_your_api_key_here"
}
}
}
}
If you installed with pip or pipx, use the binary directly:
{
"mcpServers": {
"babelwrap": {
"command": "babelwrap-mcp",
"args": [],
"env": {
"BABELWRAP_API_KEY": "bw_your_api_key_here"
}
}
}
}
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
BABELWRAP_API_KEY |
Yes | -- | Your BabelWrap API key. Get one from the dashboard. |
BABELWRAP_BASE_URL |
No | https://api.babelwrap.com/v1 |
Override the API base URL. Useful for self-hosted or development instances. |
BABELWRAP_MCP_MODE |
No | stdio |
Transport mode. Supported values: stdio, sse. |
Testing the Connection
After saving the config, restart Claude Desktop. You should see the BabelWrap tools listed in the tools panel. To verify everything works, try asking Claude:
Navigate to https://example.com and tell me what you see.
Claude will call babelwrap_new_session, then babelwrap_navigate, and describe the page contents. If you see a response with the page title and content, the connection is working.
Tools Reference
BabelWrap exposes 16 MCP tools. Every action tool returns a structured snapshot of the page after the action is performed.
babelwrap_new_session
Create a new isolated browser session. Each session has its own cookies, storage, and browsing context.
| Parameter | Type | Required | Description |
|---|---|---|---|
metadata | object | No | Optional key-value metadata to attach to the session for tracking. |
Example call:
{
"name": "babelwrap_new_session",
"arguments": {
"metadata": { "task": "price-check" }
}
}
Example response:
{
"session_id": "ses_a1b2c3d4e5",
"status": "active",
"created_at": "2026-04-04T10:30:00Z",
"metadata": { "task": "price-check" }
}
babelwrap_close_session
Close and clean up a browser session. Releases all resources (browser context, cookies, memory). Always close sessions when you are done.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | The session ID to close. |
Example call:
{
"name": "babelwrap_close_session",
"arguments": {
"session_id": "ses_a1b2c3d4e5"
}
}
Example response:
{
"status": "closed",
"session_id": "ses_a1b2c3d4e5",
"duration_seconds": 47.2
}
babelwrap_navigate
Navigate the browser to a URL. Waits for the page to load and returns a snapshot of the resulting page.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | The session to navigate. |
url | string | Yes | The URL to navigate to. Must include the protocol (https://). |
Example call:
{
"name": "babelwrap_navigate",
"arguments": {
"session_id": "ses_a1b2c3d4e5",
"url": "https://news.ycombinator.com"
}
}
Example response:
{
"snapshot": {
"url": "https://news.ycombinator.com",
"title": "Hacker News",
"content": "Hacker News new | past | comments | ask | show | jobs...",
"actions": [
{ "id": "new-link", "label": "new", "type": "link" },
{ "id": "login-link", "label": "login", "type": "link" }
],
"inputs": [],
"navigation": ["new", "past", "comments", "ask", "show", "jobs"]
},
"action_id": "act_f6g7h8i9j0"
}
babelwrap_snapshot
Get a structured snapshot of the current page without performing any action. Useful for reading the page state after waiting, or to re-read a page you've already visited.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | The session to snapshot. |
Example call:
{
"name": "babelwrap_snapshot",
"arguments": {
"session_id": "ses_a1b2c3d4e5"
}
}
Example response:
{
"snapshot": {
"url": "https://news.ycombinator.com",
"title": "Hacker News",
"content": "Hacker News new | past | comments...",
"inputs": [],
"actions": [/* ... */],
"navigation": [/* ... */],
"forms": [],
"alerts": []
},
"action_id": "act_k1l2m3n4o5"
}
babelwrap_click
Click an element on the page using a natural language description. BabelWrap uses LLM-powered resolution to find the element that best matches your description.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | The session to act on. |
target | string | Yes | Natural language description of the element to click (e.g., "the Login button", "the first search result"). |
Example call:
{
"name": "babelwrap_click",
"arguments": {
"session_id": "ses_a1b2c3d4e5",
"target": "the login link"
}
}
Example response:
{
"snapshot": {
"url": "https://news.ycombinator.com/login",
"title": "Login",
"content": "Login username: password:",
"inputs": [
{ "id": "user-field", "label": "username", "type": "text" },
{ "id": "pw-field", "label": "password", "type": "password" }
],
"actions": [
{ "id": "login-btn", "label": "login", "type": "button", "primary": true }
],
"forms": [
{ "id": "login-form", "fields": ["user-field", "pw-field"], "submit": "login-btn" }
]
},
"action_id": "act_p6q7r8s9t0"
}
babelwrap_fill
Fill a form input field with a value. The target is a natural language description of the field you want to fill.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | The session to act on. |
target | string | Yes | Natural language description of the input field (e.g., "the email field", "search box"). |
value | string | Yes | The value to type into the field. |
Example call:
{
"name": "babelwrap_fill",
"arguments": {
"session_id": "ses_a1b2c3d4e5",
"target": "the username field",
"value": "my_username"
}
}
Example response:
{
"snapshot": {
"url": "https://news.ycombinator.com/login",
"title": "Login",
"inputs": [
{ "id": "user-field", "label": "username", "type": "text", "value": "my_username" },
{ "id": "pw-field", "label": "password", "type": "password" }
],
"actions": [/* ... */],
"forms": [/* ... */]
},
"action_id": "act_u1v2w3x4y5"
}
babelwrap_submit
Submit a form on the page. If you omit the target, BabelWrap submits the most prominent form. Waits for navigation or page update before returning the snapshot.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | The session to act on. |
target | string | No | Natural language description of the form to submit. If omitted, the most prominent form is submitted. |
Example call:
{
"name": "babelwrap_submit",
"arguments": {
"session_id": "ses_a1b2c3d4e5",
"target": "the login form"
}
}
Example response:
{
"snapshot": {
"url": "https://news.ycombinator.com/",
"title": "Hacker News",
"content": "Hacker News new | past | comments | ask | show | jobs...",
"actions": [
{ "id": "logout-link", "label": "logout", "type": "link" }
],
"alerts": []
},
"action_id": "act_z6a7b8c9d0"
}
babelwrap_extract
Extract structured data from the current page using a natural language query. The response includes a data array with the extracted information.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | The session to extract from. |
query | string | Yes | Natural language description of the data to extract (e.g., "all product names and prices", "the main article text"). |
Example call:
{
"name": "babelwrap_extract",
"arguments": {
"session_id": "ses_a1b2c3d4e5",
"query": "all story titles and their point counts"
}
}
Example response:
{
"data": [
{ "title": "Show HN: A new open-source tool for...", "points": 342 },
{ "title": "Why SQLite is so great for edge computing", "points": 287 },
{ "title": "The future of browser automation", "points": 198 }
],
"action_id": "act_e1f2g3h4i5"
}
babelwrap_screenshot
Capture a PNG screenshot of the current page. Returns a base64-encoded image. Useful for debugging or visual verification.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | The session to screenshot. |
Example call:
{
"name": "babelwrap_screenshot",
"arguments": {
"session_id": "ses_a1b2c3d4e5"
}
}
Example response:
{
"image": "iVBORw0KGgoAAAANSUhEUgAA...",
"format": "png",
"width": 1280,
"height": 720,
"action_id": "act_j6k7l8m9n0"
}
babelwrap_snapshot for structured data and reserve babelwrap_screenshot for visual debugging.babelwrap_press
Press a keyboard key in the current page. Useful for submitting forms with Enter, dismissing dialogs with Escape, navigating dropdowns with arrow keys, or tabbing between fields.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | The session to act on. |
key | string | Yes | The key to press (e.g., "Enter", "Tab", "Escape", "ArrowDown", "ArrowUp", "Backspace"). |
Example call:
{
"name": "babelwrap_press",
"arguments": {
"session_id": "ses_a1b2c3d4e5",
"key": "Enter"
}
}
Example response:
{
"snapshot": {
"url": "https://example.com/search?q=babelwrap",
"title": "Search Results",
"content": "Showing results for babelwrap...",
"actions": [/* ... */],
"inputs": [/* ... */]
},
"action_id": "act_pr1e2s3s4k5"
}
babelwrap_scroll
Scroll the page up or down to reveal more content. Use this to access content below the fold, load lazy-loaded elements, or navigate long pages.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | The session to act on. |
direction | string | No | Scroll direction: "up" or "down". Defaults to "down". |
amount | string | No | How far to scroll: "page", "half", or a pixel count (e.g., "500"). Defaults to "page". |
Example call:
{
"name": "babelwrap_scroll",
"arguments": {
"session_id": "ses_a1b2c3d4e5",
"direction": "down",
"amount": "page"
}
}
Example response:
{
"snapshot": {
"url": "https://news.ycombinator.com",
"title": "Hacker News",
"content": "21. More stories below the fold...",
"actions": [/* ... */],
"inputs": []
},
"action_id": "act_sc1r2o3l4l5"
}
babelwrap_hover
Hover over an element to reveal dropdown menus, tooltips, or trigger hover states. The target is a natural language description of the element to hover over.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | The session to act on. |
target | string | Yes | Natural language description of the element to hover over (e.g., "the Products menu item", "the user avatar"). |
Example call:
{
"name": "babelwrap_hover",
"arguments": {
"session_id": "ses_a1b2c3d4e5",
"target": "the Products menu item in the navigation bar"
}
}
Example response:
{
"snapshot": {
"url": "https://example.com",
"title": "Example Store",
"content": "Products: Widgets, Gadgets, Tools...",
"actions": [
{ "id": "widgets-link", "label": "Widgets", "type": "link" },
{ "id": "gadgets-link", "label": "Gadgets", "type": "link" },
{ "id": "tools-link", "label": "Tools", "type": "link" }
],
"inputs": []
},
"action_id": "act_ho1v2e3r4h5"
}
babelwrap_upload
Upload a file to a file input field. The file content must be provided as a base64-encoded string along with a filename.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | The session to act on. |
target | string | Yes | Natural language description of the file input field (e.g., "the profile picture upload", "the resume upload field"). |
file_base64 | string | Yes | The file content encoded as a base64 string. |
filename | string | Yes | The filename to use for the upload (e.g., "report.pdf", "photo.png"). |
Example call:
{
"name": "babelwrap_upload",
"arguments": {
"session_id": "ses_a1b2c3d4e5",
"target": "the resume upload field",
"file_base64": "JVBERi0xLjQKMSAwIG9iago...",
"filename": "resume.pdf"
}
}
Example response:
{
"snapshot": {
"url": "https://example.com/apply",
"title": "Job Application",
"content": "Application Form... File uploaded: resume.pdf",
"inputs": [
{ "id": "resume-field", "label": "Resume", "type": "file", "value": "resume.pdf" }
],
"actions": [/* ... */],
"forms": [/* ... */]
},
"action_id": "act_up1l2o3a4d5"
}
babelwrap_wait_for
Wait for a condition to be met before proceeding. Useful for waiting on dynamic content, page transitions, or AJAX-loaded elements. At least one of text, selector, or url_contains must be provided.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | The session to wait on. |
text | string | No | Wait until this text appears on the page. |
selector | string | No | Wait until an element matching this CSS selector appears. |
url_contains | string | No | Wait until the page URL contains this substring. |
timeout_ms | int | No | Maximum time to wait in milliseconds. Defaults to 10000 (10 seconds). |
Example call:
{
"name": "babelwrap_wait_for",
"arguments": {
"session_id": "ses_a1b2c3d4e5",
"text": "Results loaded",
"timeout_ms": 5000
}
}
Example response:
{
"snapshot": {
"url": "https://example.com/search?q=babelwrap",
"title": "Search Results",
"content": "Results loaded. Showing 42 matches...",
"actions": [/* ... */],
"inputs": [/* ... */]
},
"action_id": "act_wa1i2t3f4r5"
}
babelwrap_back
Navigate back in browser history. Returns a snapshot of the previous page. Equivalent to clicking the browser's back button.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | The session to navigate back. |
Example call:
{
"name": "babelwrap_back",
"arguments": {
"session_id": "ses_a1b2c3d4e5"
}
}
Example response:
{
"snapshot": {
"url": "https://example.com/articles",
"title": "Articles",
"content": "Latest Articles: 1. How to automate...",
"actions": [/* ... */],
"inputs": []
},
"action_id": "act_ba1c2k3n4v5"
}
babelwrap_forward
Navigate forward in browser history. Returns a snapshot of the next page. Equivalent to clicking the browser's forward button.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | The session to navigate forward. |
Example call:
{
"name": "babelwrap_forward",
"arguments": {
"session_id": "ses_a1b2c3d4e5"
}
}
Example response:
{
"snapshot": {
"url": "https://example.com/articles/42",
"title": "How to Automate Browser Tasks",
"content": "How to Automate Browser Tasks. Published on...",
"actions": [/* ... */],
"inputs": []
},
"action_id": "act_fw1r2d3n4v5"
}
Common Patterns
These are the most common tool-call sequences your agent will use.
Browse and Extract
Navigate to a page and extract structured data. This is the most common pattern.
// 1. Create a session
babelwrap_new_session({})
// -> { "session_id": "ses_abc123" }
// 2. Navigate to the target page
babelwrap_navigate({
"session_id": "ses_abc123",
"url": "https://example.com/products"
})
// 3. Extract what you need
babelwrap_extract({
"session_id": "ses_abc123",
"query": "all product names, prices, and ratings"
})
// -> { "data": [{ "name": "...", "price": "...", "rating": "..." }, ...] }
// 4. Clean up
babelwrap_close_session({ "session_id": "ses_abc123" })
Login and Interact
Log into a site and perform authenticated actions. The session maintains cookies across all calls.
// 1. Create a session
babelwrap_new_session({})
// 2. Navigate to the login page
babelwrap_navigate({
"session_id": "ses_abc123",
"url": "https://app.example.com/login"
})
// 3. Fill in credentials
babelwrap_fill({
"session_id": "ses_abc123",
"target": "email address field",
"value": "user@example.com"
})
babelwrap_fill({
"session_id": "ses_abc123",
"target": "password field",
"value": "my_password"
})
// 4. Submit the login form
babelwrap_submit({
"session_id": "ses_abc123",
"target": "the login form"
})
// 5. Now interact with the authenticated app
babelwrap_click({
"session_id": "ses_abc123",
"target": "Settings link in the navigation"
})
// 6. Clean up
babelwrap_close_session({ "session_id": "ses_abc123" })
Multi-page Navigation
Navigate across multiple pages, collecting data or performing actions on each one.
// 1. Create a session
babelwrap_new_session({})
// 2. Start at a listing page
babelwrap_navigate({
"session_id": "ses_abc123",
"url": "https://example.com/articles"
})
// 3. Extract the list of articles
babelwrap_extract({
"session_id": "ses_abc123",
"query": "all article titles and their links"
})
// 4. Click into the first article
babelwrap_click({
"session_id": "ses_abc123",
"target": "the first article title"
})
// 5. Extract the article content
babelwrap_extract({
"session_id": "ses_abc123",
"query": "the full article text, author, and publication date"
})
// 6. Go back and visit the next article
babelwrap_navigate({
"session_id": "ses_abc123",
"url": "https://example.com/articles"
})
babelwrap_click({
"session_id": "ses_abc123",
"target": "the second article title"
})
// 7. Clean up when done
babelwrap_close_session({ "session_id": "ses_abc123" })
Troubleshooting
Tools not showing in Claude Desktop
- Verify that
claude_desktop_config.jsonis valid JSON. A trailing comma or missing quote will silently break it. - Make sure you fully quit and reopened Claude Desktop (not just closed the window).
- Check that
uvxorbabelwrap-mcpis available on your system PATH. Try runninguvx babelwrap-mcp --helpin your terminal. - On macOS, if you installed
uvxvia Homebrew, Claude Desktop may not see it. Use the full path:/opt/homebrew/bin/uvx.
Authentication errors
- Ensure
BABELWRAP_API_KEYis set in theenvblock of your config, not as a system environment variable (Claude Desktop does not inherit shell env vars). - Confirm your API key starts with
bw_and is still active in the dashboard. - If you rotated your key, update the config file and restart Claude Desktop.
Session timeouts
- Sessions automatically expire after 5 minutes of inactivity. If a session times out, create a new one.
- Long-running extractions on complex pages may take up to 30 seconds. If you see a timeout, try simplifying your extraction query.
- If you consistently hit timeouts, check the API status page.
Incorrect element targeted
- Be more specific in your
targetdescription. Instead of "the button", try "the blue Submit Order button at the bottom of the form". - Use
babelwrap_snapshotfirst to see what elements are available, then reference them by their labels. - If a page has multiple similar elements, include positional hints like "the first", "the one in the header", or "the one next to the price".
babelwrap_new_session and babelwrap_close_session) counts as one action against your plan's quota. Use babelwrap_snapshot to read the page before acting to minimize wasted actions.Custom MCP Client
If you are building your own MCP client (not using Claude Desktop), you can connect to the BabelWrap MCP server programmatically using the mcp Python SDK.
import asyncio
import os
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def main():
server_params = StdioServerParameters(
command="uvx",
args=["babelwrap-mcp"],
env={
"BABELWRAP_API_KEY": os.environ["BABELWRAP_API_KEY"],
},
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
# List available tools
tools = await session.list_tools()
print("Available tools:", [t.name for t in tools.tools])
# Create a new browser session
result = await session.call_tool(
"babelwrap_new_session", arguments={}
)
print("Session created:", result)
# Navigate to a page
result = await session.call_tool(
"babelwrap_navigate",
arguments={
"session_id": "ses_abc123",
"url": "https://news.ycombinator.com",
},
)
print("Page title:", result)
# Extract data
result = await session.call_tool(
"babelwrap_extract",
arguments={
"session_id": "ses_abc123",
"query": "top 5 story titles",
},
)
print("Extracted:", result)
# Clean up
await session.call_tool(
"babelwrap_close_session",
arguments={"session_id": "ses_abc123"},
)
asyncio.run(main())
pip install mcp. The SDK handles the stdio transport and JSON-RPC protocol automatically.