@pokutuna/mcp-chrome-tabs
An MCP server that lets you inspect and read content from already-open browser tabs, and open new tabs, on macOS.
List all open browser tabs with titles, hostnames/URLs, and tab references (ID:windowId:tabId).
Read clean, AI-friendly markdown content from the active tab or a specific tab by ID, with optional startIndex for truncated content.
Open a URL in a new browser tab and get its tab ID.
Access the active tab via the
tab://currentresource; with--check-interval, accesstab://{windowId}/{tabId}resources and receive MCPlistChangednotifications.Use read-only CLI commands to list tabs and read content by active tab, index, or ID outside MCP.
Configure host exclusions, content size/timeout limits, browser app name, and experimental Safari/Arc support.
Provides direct access to open tabs in Google Chrome, allowing reading tab content, listing all open tabs, and opening new tabs, with content optimized for AI consumption through readability processing and markdown conversion.
Offers experimental support for accessing open tabs in Safari, enabling reading tab content and listing open tabs, though with limitations due to Safari's lack of unique tab IDs.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@pokutuna/mcp-chrome-tabsread the content from my current tab"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@pokutuna/mcp-chrome-tabs
Model Context Protocol (MCP) server that provides direct access to your browser's open tabs content. No additional fetching or authentication required - simply access what you're already viewing.
Key Features
Direct browser tab access - No web scraping needed, reads content from already open tabs
Content optimized for AI - Automatic content extraction and markdown conversion to reduce token usage
Active tab shortcut - Instant access to currently focused tab without specifying IDs
MCP listChanged notifications - Follows MCP protocol to notify tab changes (set
--check-intervalto enable)
Related MCP server: chromectx
Requirements
macOS only - This MCP server uses Apple Events (JXA) and only works on macOS.
Node.js 22 or newer
MCP Client such as Claude Desktop, Claude Code, or any MCP-compatible client
macOS only (uses Apple Events via JXA for browser automation)
Getting Started
First, enable "Allow JavaScript from Apple Events" in Chrome:
(en) View > Developer > Allow JavaScript from Apple Events
(ja) 表示 > 開発 / 管理 > Apple Events からの JavaScript を許可
When you first use the MCP server, macOS will prompt you to grant Automation permission to your MCP client (e.g., Claude Desktop, Claude Code). Click OK to allow access to Chrome. If you accidentally dismissed the dialog, you can enable it in System Settings > Privacy & Security > Automation.
When multiple Google Chrome processes exist, JXA generally selects the oldest process, but this is not a guaranteed process-selection API. Start your normal Chrome before starting other Chrome instances when process identity matters.
Standard config works in most MCP clients (e.g., .claude.json, .mcp.json):
{
"mcpServers": {
"chrome-tabs": {
"command": "npx",
"args": ["-y", "@pokutuna/mcp-chrome-tabs@latest"]
}
}
}Or for Claude Code:
claude mcp add -s user chrome-tabs -- npx -y @pokutuna/mcp-chrome-tabs@latestClaude Code Plugin
You can also install this as a Claude Code plugin:
# Add the marketplace
/plugin marketplace add pokutuna/mcp-chrome-tabs
# Install the plugin
/plugin install mcp-chrome-tabs@mcp-chrome-tabsCommand Line Options
The package also provides read-only commands for accessing the same tab data as the MCP tools:
# List open tabs as: [INDEX] ID TITLE DOMAIN (* marks the active tab)
npx @pokutuna/mcp-chrome-tabs list
# Show the full URL in place of the domain
npx @pokutuna/mcp-chrome-tabs list --include-url
# Read the active tab
npx @pokutuna/mcp-chrome-tabs read --active
# Read a specific tab from an ID returned by list
npx @pokutuna/mcp-chrome-tabs read ID:12345:67890
# Read by INDEX from the list instead
npx @pokutuna/mcp-chrome-tabs read 2
# Continue reading truncated content
npx @pokutuna/mcp-chrome-tabs read ID:12345:67890 --offset=20000list prints an INDEX column for reading the listing at a glance, but it
numbers that one listing only -- it shifts when tabs open or close. Windows
are ordered by ID (creation order) rather than front to back, so switching
windows does not renumber the list. read <INDEX> re-resolves the index when
it runs, so it can land on a different tab than you saw; pass the ID when that
matters. An argument starting with ID: is taken as an ID, and a bare number
as an INDEX.
Reading refuses a browser that is not running rather than launching it;
open_in_new_tab still launches it.
Running the command without a subcommand starts the MCP server. Options apply to the commands shown below; passing one to a command it does not apply to is an error.
List Options
--include-url- Show the full URL instead of the domain
Read Options
--active- Read the tab you are looking at now.readneeds one of an ID, an INDEX, or--active--offset- Start reading content at this character offset (default: 0)
Content Options (read and the MCP server)
--max-content-chars- Maximum content characters per single read (default: 20000)--extraction-timeout- Timeout for content extraction worker in milliseconds (default: 20000)
MCP Server Options
--check-interval- Interval in milliseconds to check for tab changes and send listChanged notifications (default: 0 disabled, set to 3000 for 3 seconds)
Common Options (all commands)
--exclude-hosts- Comma-separated list of domains to exclude from tab listing and content access. Hosts in theMCP_CHROME_TABS_EXCLUDE_HOSTSenvironment variable are excluded as well--application-name- Application name to control (default: "Google Chrome")--experimental-browser- Browser implementation to use: "chrome", "safari", or "arc" (default: "chrome")--help- Show help message with all available options--version- Show the package version
Who Can Read Your Tabs
Anything that runs as your user and has Automation permission for the browser can read your tabs, with or without this package. Keep the following in mind when using the commands above:
listandreaddo not go through your MCP client's tool approval. Any process or agent that can run shell commands can call them.macOS grants Automation permission to the app that starts the process, such as your terminal. If you allowed it once for the MCP server, commands run from the same app get it too.
--exclude-hostsapplies only to the process it is passed to. Hosts excluded in your MCP client config are not excluded for command line runs. To exclude hosts everywhere, setMCP_CHROME_TABS_EXCLUDE_HOSTSin your shell profile (e.g.export MCP_CHROME_TABS_EXCLUDE_HOSTS="mail.google.com"). Either way, it filters what this package returns; it does not control access.
To block access entirely, turn off the browser under System Settings > Privacy & Security > Automation for the app in question.
Asking before a coding agent reads a tab
A coding agent with shell access can run list and read, or osascript
directly, without the MCP tool approval. Its permission rules can require a
confirmation for these commands, even in an auto-approve mode. The rules match
the command text, so an agent that reaches the same program another way (for
example /usr/bin/osascript) is not caught; they are a checkpoint, not access
control.
Claude Code (~/.claude/settings.json; use deny instead of ask to block):
{
"permissions": {
"ask": [
"Bash(mcp-chrome-tabs *)",
"Bash(npx *mcp-chrome-tabs*)",
"Bash(osascript *)"
]
}
}Codex CLI (~/.codex/rules/default.rules; use "forbidden" to block):
prefix_rule(pattern = ["mcp-chrome-tabs"], decision = "prompt")
prefix_rule(pattern = ["npx", "@pokutuna/mcp-chrome-tabs"], decision = "prompt")
prefix_rule(pattern = ["npx", "-y", "@pokutuna/mcp-chrome-tabs"], decision = "prompt")
prefix_rule(pattern = ["osascript"], decision = "prompt")Resource Subscription (Optional)
Setting --check-interval to a value greater than 0 enables resource subscription. When enabled, the server monitors tab list changes and sends MCP listChanged notifications to prompt clients to refresh their resource lists. This also makes tab://{windowId}/{tabId} resources available for all open tabs.
In 2025-10, few MCP clients support resource subscriptions. Resource subscription is disabled by default (--check-interval=0). Most users only need the tab://current resource, which is always available.
To enable resource subscription:
{
"mcpServers": {
"chrome-tabs": {
"command": "npx",
"args": [
"-y",
"@pokutuna/mcp-chrome-tabs@latest",
"--check-interval=3000"
]
}
}
}Other Browser Support (Experimental)
Safari
Reading page content requires Develop > Allow JavaScript from Apple Events in Safari. Note that Safari lacks unique tab IDs, making it sensitive to tab order changes during execution:
npx @pokutuna/mcp-chrome-tabs --application-name=Safari --experimental-browser=safariArc
npx @pokutuna/mcp-chrome-tabs --application-name=Arc --experimental-browser=arcMCP Features
Tools
List all open tabs in the user's browser with their titles, URLs, and tab references.
Returns: Markdown formatted list of tabs with tab IDs for reference
Get readable content from a tab in the user's browser.
id(optional): Tab reference fromlist_tabsoutput (e.g.,ID:12345:67890)If
idis omitted, uses the currently active tabReturns: Clean, readable content extracted using Mozilla Readability
Open a URL in a new tab to present content or enable user interaction with webpages.
url(required): URL to open in the browserReturns: Tab ID in format
ID:windowId:tabIdfor immediate access to the new tab
Resources
Resource representing the content of the currently active tab.
URI:
tab://currentMIME type:
text/markdownContent: Real-time content of the active browser tab
Always available regardless of
--check-intervalsetting
Resource template for accessing specific tabs.
URI pattern:
tab://{windowId}/{tabId}MIME type:
text/markdownContent: Content of the specified tab
Availability: Only when
--check-intervalis set to a value greater than 0Resources are dynamically generated based on currently open tabs
When enabled, the server monitors tab changes and sends MCP listChanged notifications
Troubleshooting
Current Tabs (0 tabs exists) is displayed
Ensure "Allow JavaScript from Apple Events" is enabled in Chrome (see Getting Started).
If it was working before, try restarting your browser.
Available Tools
3 toolslist_tabsList TabsA
List all open tabs in the user's browser with their titles and tab references.
| Name | Required | Description | Default |
|---|---|---|---|
| includeUrl | No | Include URLs in the output. Enable only when you need to reference specific URLs. (default: false, hostnames always included) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses the basic read-only nature and output format (titles/references), but omits behavioral details like permission requirements, privacy considerations, or whether tab references are persistent IDs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, front-loaded with the action verb, and zero wasted words. Every component earns its place by defining scope ('all open tabs'), location ('user's browser'), and output ('titles and tab references').
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple single-parameter tool without output schema, the description adequately explains what the tool returns. It could be improved by mentioning the URL inclusion option described in the schema, but it covers the core functionality sufficiently.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, establishing a baseline of 3. The description does not mention the includeUrl parameter or its default behavior (URLs excluded), leaving all parameter semantics to the schema itself.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') and resource ('open tabs'), and distinguishes from siblings by specifying it returns 'titles and tab references' (metadata) rather than content, clearly differentiating it from read_tab_content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
While the description implies usage by stating it returns tab references (suggesting it's for discovery before reading), it lacks explicit guidance on when to use this versus read_tab_content or workflows like 'use this first to get tab IDs'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
open_in_new_tabOpen in New TabA
Open a URL in a new tab to present content or enable user interaction with webpages
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | URL to open in the browser |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It clearly indicates a side effect (creating a new tab) and implies user-facing presentation, but omits execution details such as whether the call blocks until the page loads, error handling for invalid URLs, or whether the tab persists after the session.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence of 13 words with the action front-loaded. Every word earns its place—'present content' and 'enable user interaction' efficiently convey the dual use cases without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (single required parameter, no output schema, no nested objects), the description adequately covers the essential information needed for invocation. It appropriately omits unnecessary details while capturing the core user-facing purpose.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, providing complete documentation for the 'url' parameter. The description references the URL but does not add semantic meaning beyond the schema (e.g., no mention of supported protocols, relative vs absolute URLs, or validation rules), meriting the baseline score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action (Open), resource (URL), and location (new tab), and clearly distinguishes from siblings list_tabs (which lists existing tabs) and read_tab_content (which reads from tabs) by emphasizing the creation of a new browsing context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear context for when to use the tool ('to present content or enable user interaction with webpages'), giving the agent criteria for selection. However, it does not explicitly contrast with sibling tools or state when NOT to use it (e.g., when extraction without opening is needed).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_tab_contentRead Tab ContentA
Get readable content from a tab in the user's browser. Provide ID (from list_tabs output) to read a specific tab, or omit for the active tab.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Tab reference from list_tabs output (e.g: ID:12345:67890). If omitted, uses the currently active tab. | |
| startIndex | No | Starting character position for content extraction (default: 0) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It establishes this is a read operation targeting browser content and specifies the tab selection logic. However, it omits details about the return format (plain text vs. HTML vs. structured data), content size limits, or whether the operation affects browser state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two well-structured sentences with zero waste. The first sentence front-loads the core purpose; the second provides essential parameter guidance. Every word earns its place—no filler, no redundancy, and no unnecessary verbosity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 100% schema coverage for the 2 parameters, the description adequately covers inputs. However, with no output schema provided, the description could be improved by briefly indicating the return format (e.g., extracted text content) to complete the picture for the agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, establishing a baseline of 3. The description adds valuable semantic context by specifying that the ID comes from 'list_tabs output,' which helps the agent understand the tool relationship. It does not add significant detail beyond the schema for startIndex or ID format syntax.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the specific action ('Get readable content') and resource ('tab in the user's browser'). It effectively distinguishes from sibling tools by explicitly referencing 'list_tabs output' for the ID parameter, clarifying this reads existing content rather than opening new tabs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear guidance on when to provide the ID parameter (to read a specific tab) versus when to omit it (for the active tab). Mentions the dependency on list_tabs for obtaining valid IDs. Lacks explicit 'when not to use' guidance contrasting with open_in_new_tab, though this distinction is relatively clear from the verb choices.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.7.2- First observed
list_tabs - First observed
open_in_new_tab - First observed
read_tab_content
TDQS
Scored across 3 tools
Each tool has a clearly distinct purpose: list_tabs enumerates tabs, open_in_new_tab creates a new tab, and read_tab_content extracts content from an existing tab. There is no overlap in functionality, making it easy for an agent to select the correct tool for each task without confusion.
All tool names follow a consistent verb_noun pattern with snake_case (list_tabs, open_in_new_tab, read_tab_content). The naming is predictable and readable, with no deviations in style or convention across the set.
Three tools are well-scoped for a browser tabs management server, covering listing, opening, and reading tabs. While slightly minimal, it is reasonable and each tool earns its place, though additional operations like closing tabs might be expected but are not essential.
The toolset provides core CRUD-like operations for browser tabs: list (read), open (create), and read content. Minor gaps exist, such as no update or delete tools (e.g., close_tab or update_tab), but agents can work around this, and the surface covers the essential workflows for the domain.
Maintenance
Related MCP Connectors
Hosted browser for AI agents: screenshots, post-JS DOM, console, WCAG. No install, no API key.
Browser MCP for logged-in tasks. Uses your Chrome — credentials stay local. Zero-token replay.
Undetectable cloud browser sessions for AI agents and scrapers. Navigate, extract, click, captcha.
AI-powered browser automation — navigate, click, fill forms, and extract data from any website.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceEnables AI assistants to control and automate your Chrome browser directly, leveraging existing login states and configurations for tasks like content analysis, semantic search across tabs, screenshots, network monitoring, and interactive operations.12MIT
- AlicenseNot gradedqualityDmaintenanceSearch and retrieve content from all open Chrome tabs, and provide them as context for AI tools via MCP.8 npm4MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to interact with a user's real Chrome browser tabs, executing JavaScript, reading cookies, and making fetch requests within authenticated sessions.-
- AlicenseNot gradedqualityBmaintenanceA read-only bridge that lets ChatGPT inspect open Chrome tabs, exposing tools to list, read, and search tabs without accessing sensitive data.15 npmMIT