plasmate mcp exposes Plasmate as an MCP (Model Context Protocol) tool server over stdio. Any MCP-compatible client (Claude Desktop, Cursor, Windsurf, OpenClaw, Continue, etc.) can discover and use Plasmate for web browsing, scraping, and interaction.
{
"mcpServers": {
"plasmate": {
"command": "plasmate",
"args": ["mcp"]
}
}
}Docker:
{
"mcpServers": {
"plasmate": {
"command": "docker",
"args": ["run", "--rm", "-i", "ghcr.io/plasmate-labs/plasmate:latest", "mcp"]
}
}
}- Protocol: MCP over stdio (JSON-RPC 2.0)
- Input: stdin (newline-delimited JSON)
- Output: stdout (newline-delimited JSON)
- Lifecycle: long-running process, one instance per client session
{
"name": "plasmate",
"version": "0.1.0",
"capabilities": {
"tools": {}
}
}Fetch a URL and return its Semantic Object Model.
When to use: Getting structured content from a supported web page. Best for reading articles, documentation, product pages, and search results. Output size depends on the page, configuration, serialization, selector, and tokenizer.
{
"name": "fetch_page",
"description": "Fetch a web page and return its Semantic Object Model (SOM), a structured representation whose size depends on the page, configuration, serialization, and selector.",
"inputSchema": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "URL to fetch"
},
"budget": {
"type": "integer",
"description": "Maximum output tokens. SOM will be truncated to fit. Default: no limit."
},
"javascript": {
"type": "boolean",
"description": "Enable JavaScript execution for dynamic/SPA pages. Default: true."
}
},
"required": ["url"]
}
}Response: SOM JSON with title, url, regions array, and meta stats.
Fetch a URL and return clean text only (no structure).
When to use: When you just need the readable text content, not the page structure. Good for summarization, search, Q&A over page content.
{
"name": "extract_text",
"description": "Fetch a web page and return only the clean, readable text content. No HTML, no structure - just the text a human would read.",
"inputSchema": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "URL to fetch"
},
"max_chars": {
"type": "integer",
"description": "Maximum characters to return. Default: no limit."
}
},
"required": ["url"]
}
}Response: Plain text string.
Open a page in a persistent browser session for multi-step interaction.
When to use: When you need to interact with a page (click buttons, fill forms, navigate). Creates a session that persists across calls.
{
"name": "open_page",
"description": "Open a web page in a persistent browser session. Returns a session ID and the initial SOM. Use with click, type, and evaluate for multi-step interactions.",
"inputSchema": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "URL to open"
}
},
"required": ["url"]
}
}Response:
{
"session_id": "abc123",
"title": "Page Title",
"url": "https://resolved.url",
"regions": [...]
}Click an interactive element in an open session.
{
"name": "click",
"description": "Click an element on the page by its SOM element ID. Returns the updated page SOM after the click.",
"inputSchema": {
"type": "object",
"properties": {
"session_id": {
"type": "string",
"description": "Session ID from open_page"
},
"element_id": {
"type": "string",
"description": "Element ID from SOM (e.g. 'e5')"
}
},
"required": ["session_id", "element_id"]
}
}Response: Updated SOM after click.
Type text into an input field.
{
"name": "type_text",
"description": "Type text into an input element on the page. Returns the updated page SOM.",
"inputSchema": {
"type": "object",
"properties": {
"session_id": {
"type": "string",
"description": "Session ID from open_page"
},
"element_id": {
"type": "string",
"description": "Element ID of the input field from SOM"
},
"text": {
"type": "string",
"description": "Text to type"
},
"submit": {
"type": "boolean",
"description": "Press Enter after typing. Default: false."
}
},
"required": ["session_id", "element_id", "text"]
}
}Run JavaScript on the page and return the result.
When to use: When SOM doesn't capture what you need, or you need to run custom extraction logic.
{
"name": "evaluate",
"description": "Execute JavaScript in the page context and return the result. Use for custom data extraction or page manipulation.",
"inputSchema": {
"type": "object",
"properties": {
"session_id": {
"type": "string",
"description": "Session ID from open_page"
},
"expression": {
"type": "string",
"description": "JavaScript expression to evaluate. Return value is serialized to JSON."
}
},
"required": ["session_id", "expression"]
}
}Capture a screenshot of the current page.
{
"name": "screenshot",
"description": "Take a screenshot of the page. Returns a base64-encoded PNG image.",
"inputSchema": {
"type": "object",
"properties": {
"session_id": {
"type": "string",
"description": "Session ID from open_page"
},
"full_page": {
"type": "boolean",
"description": "Capture full scrollable page. Default: false (viewport only)."
}
},
"required": ["session_id"]
}
}Response: Base64-encoded PNG as an MCP image content block.
Close a browser session.
{
"name": "close_page",
"description": "Close a browser session and free resources.",
"inputSchema": {
"type": "object",
"properties": {
"session_id": {
"type": "string",
"description": "Session ID to close"
}
},
"required": ["session_id"]
}
}Agent (Claude, etc.)
|
| MCP JSON-RPC over stdio
v
plasmate mcp (long-running process)
|
|-- fetch_page / extract_text: direct pipeline (HTML -> JS -> SOM)
|-- open_page / click / type / evaluate: CDP session pool
| |
| v
| Internal CDP server (127.0.0.1:random_port)
| |
| v
| Page sessions (V8 + DOM per tab)
|
v
Network (reqwest)
- Run the standard Plasmate pipeline: fetch HTML, execute JS, compile SOM
- No session state, no CDP overhead
- Fastest path for one-shot reads
- Spin up internal CDP server on first
open_pagecall - Each
open_pagecreates a CDP target (browser tab) clickandtypedispatch CDP Input eventsevaluateruns Runtime.evaluate via CDP- After each mutation, re-fetch page.content() and recompile SOM
- Sessions auto-close after 5 minutes of inactivity
- Sessions stored in a HashMap<String, CdpSession>
- Session IDs are random UUIDs
- Max 10 concurrent sessions (configurable via --max-sessions)
- Idle timeout: 5 minutes (configurable via --session-timeout)
plasmate mcp [options]
Options:
--max-sessions <n> Max concurrent browser sessions (default: 10)
--session-timeout <s> Idle session timeout in seconds (default: 300)
--no-javascript Disable JS execution globally
--budget <tokens> Default token budget for fetch_page
All errors return MCP error responses:
{
"isError": true,
"content": [
{
"type": "text",
"text": "Failed to fetch https://example.com: connection timed out"
}
]
}Error categories:
- Network errors (timeout, DNS, TLS)
- Session errors (invalid session_id, session expired)
- JavaScript errors (syntax error, runtime exception)
- Resource errors (max sessions reached)
page://{session_id}- current page SOM as a resourcepage://{session_id}/text- current page text
scrape- guided multi-page scraping workflowresearch- open multiple pages, extract and compare
page_loaded- when a page finishes loadingsession_expired- when a session times out
For Anthropic MCP Registry and Smithery:
name: plasmate
description: Agent-native headless browser. Fetch supported web pages as structured Semantic Object Models, browse, interact, and extract data.
category: web-browsing
tags:
- browser
- web-scraping
- headless
- semantic
- dom
install:
- curl -fsSL https://plasmate.app/install.sh | sh
- cargo install plasmate
- npm install -g plasmate
- pip install plasmate- fetch_page and extract_text - stateless, uses existing pipeline directly
- open_page and close_page - session management scaffolding
- evaluate - already works via CDP Runtime.evaluate
- click and type_text - CDP Input dispatch (already implemented)
- screenshot - requires layout/paint (not yet implemented; could return SOM as fallback)