@pokutuna/mcp-chrome-tabs 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -4
- package/dist/browser/arc.js +10 -2
- package/dist/browser/browser.d.ts +1 -1
- package/dist/browser/chrome.js +9 -3
- package/dist/browser/safari.js +11 -3
- package/dist/mcp.js +3 -2
- package/package.json +13 -6
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
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.
|
|
6
6
|
|
|
7
|
+
<img src="./demo/demo.webp" width="600px" />
|
|
8
|
+
|
|
7
9
|
## Key Features
|
|
8
10
|
|
|
9
11
|
- **Direct browser tab access** - No web scraping needed, reads content from already open tabs
|
|
@@ -55,17 +57,18 @@ The server accepts optional command line arguments for configuration:
|
|
|
55
57
|
- `--check-interval` - Interval in milliseconds to check for tab changes and notify clients (default: 3000, set to 0 to disable)
|
|
56
58
|
- `--max-content-chars` - Truncates tab content to a maximum number of characters (default: 20000)
|
|
57
59
|
|
|
58
|
-
|
|
60
|
+
## Other Browser Support (Experimental)
|
|
61
|
+
|
|
62
|
+
### Safari
|
|
59
63
|
|
|
60
|
-
|
|
64
|
+
Note that Safari lacks unique tab IDs, making it sensitive to tab order changes during execution:
|
|
61
65
|
|
|
62
66
|
```bash
|
|
63
67
|
npx @pokutuna/mcp-chrome-tabs --application-name=Safari --experimental-browser=safari
|
|
64
68
|
```
|
|
65
69
|
|
|
66
|
-
#### Experimental Arc Browser Support
|
|
67
70
|
|
|
68
|
-
|
|
71
|
+
### Arc
|
|
69
72
|
|
|
70
73
|
```bash
|
|
71
74
|
npx @pokutuna/mcp-chrome-tabs --application-name=Arc --experimental-browser=arc
|
|
@@ -101,6 +104,7 @@ Get readable content from a tab in the user's browser.
|
|
|
101
104
|
Open a URL in a new tab to present content or enable user interaction with webpages.
|
|
102
105
|
|
|
103
106
|
- `url` (required): URL to open in the browser
|
|
107
|
+
- Returns: Tab ID in format `ID:windowId:tabId` for immediate access to the new tab
|
|
104
108
|
|
|
105
109
|
</details>
|
|
106
110
|
|
package/dist/browser/arc.js
CHANGED
|
@@ -111,12 +111,20 @@ async function getPageContent(applicationName, tab) {
|
|
|
111
111
|
}
|
|
112
112
|
async function openURL(applicationName, url) {
|
|
113
113
|
const escapedUrl = escapeAppleScript(url);
|
|
114
|
+
const sep = separator();
|
|
114
115
|
const appleScript = `
|
|
115
116
|
tell application "${applicationName}"
|
|
116
|
-
|
|
117
|
+
tell front window
|
|
118
|
+
set newTab to (make new tab with properties {URL:"${escapedUrl}"})
|
|
119
|
+
set windowId to id
|
|
120
|
+
set tabId to id of (active tab) -- cannot retrieve id of newTab
|
|
121
|
+
return windowId & "${sep}" & tabId
|
|
122
|
+
end tell
|
|
117
123
|
end tell
|
|
118
124
|
`;
|
|
119
|
-
await executeAppleScript(appleScript);
|
|
125
|
+
const result = await executeAppleScript(appleScript);
|
|
126
|
+
const [windowId, tabId] = result.trim().split(sep);
|
|
127
|
+
return { windowId, tabId };
|
|
120
128
|
}
|
|
121
129
|
export const arcBrowser = {
|
|
122
130
|
getTabList: getArcTabList,
|
|
@@ -15,6 +15,6 @@ export type TabContent = {
|
|
|
15
15
|
export type BrowserInterface = {
|
|
16
16
|
getTabList(applicationName: string): Promise<Tab[]>;
|
|
17
17
|
getPageContent(applicationName: string, tab?: TabRef | null): Promise<TabContent>;
|
|
18
|
-
openURL(applicationName: string, url: string): Promise<
|
|
18
|
+
openURL(applicationName: string, url: string): Promise<TabRef>;
|
|
19
19
|
};
|
|
20
20
|
export declare function getInterface(browser: Browser): BrowserInterface;
|
package/dist/browser/chrome.js
CHANGED
|
@@ -90,17 +90,23 @@ async function getPageContent(applicationName, tab) {
|
|
|
90
90
|
return {
|
|
91
91
|
title,
|
|
92
92
|
url,
|
|
93
|
-
content,
|
|
93
|
+
content,
|
|
94
94
|
};
|
|
95
95
|
}
|
|
96
96
|
async function openURL(applicationName, url) {
|
|
97
97
|
const escapedUrl = escapeAppleScript(url);
|
|
98
|
+
const sep = separator();
|
|
98
99
|
const appleScript = `
|
|
99
100
|
tell application "${applicationName}"
|
|
100
|
-
|
|
101
|
+
set newTab to (make new tab at end of tabs of front window with properties {URL:"${escapedUrl}"})
|
|
102
|
+
set windowId to id of front window
|
|
103
|
+
set tabId to id of newTab
|
|
104
|
+
return windowId & "${sep}" & tabId
|
|
101
105
|
end tell
|
|
102
106
|
`;
|
|
103
|
-
await executeAppleScript(appleScript);
|
|
107
|
+
const result = await executeAppleScript(appleScript);
|
|
108
|
+
const [windowId, tabId] = result.trim().split(sep);
|
|
109
|
+
return { windowId, tabId };
|
|
104
110
|
}
|
|
105
111
|
export const chromeBrowser = {
|
|
106
112
|
getTabList: getChromeTabList,
|
package/dist/browser/safari.js
CHANGED
|
@@ -90,17 +90,25 @@ async function getPageContent(applicationName, tab) {
|
|
|
90
90
|
return {
|
|
91
91
|
title,
|
|
92
92
|
url,
|
|
93
|
-
content,
|
|
93
|
+
content,
|
|
94
94
|
};
|
|
95
95
|
}
|
|
96
96
|
async function openURL(applicationName, url) {
|
|
97
97
|
const escapedUrl = escapeAppleScript(url);
|
|
98
|
+
const sep = separator();
|
|
98
99
|
const appleScript = `
|
|
99
100
|
tell application "${applicationName}"
|
|
100
|
-
|
|
101
|
+
tell front window
|
|
102
|
+
set newTab to (make new tab with properties {URL:"${escapedUrl}"})
|
|
103
|
+
set windowId to id
|
|
104
|
+
set tabIndex to index of newTab
|
|
105
|
+
return (windowId as string) & "${sep}" & (tabIndex as string)
|
|
106
|
+
end tell
|
|
101
107
|
end tell
|
|
102
108
|
`;
|
|
103
|
-
await executeAppleScript(appleScript);
|
|
109
|
+
const result = await executeAppleScript(appleScript);
|
|
110
|
+
const [windowId, tabId] = result.trim().split(sep);
|
|
111
|
+
return { windowId, tabId };
|
|
104
112
|
}
|
|
105
113
|
export const safariBrowser = {
|
|
106
114
|
getTabList: getSafariTabList,
|
package/dist/mcp.js
CHANGED
|
@@ -122,12 +122,13 @@ export async function createMcpServer(options) {
|
|
|
122
122
|
}, async (args) => {
|
|
123
123
|
const { url } = args;
|
|
124
124
|
const browser = getInterface(options.browser);
|
|
125
|
-
await browser.openURL(options.applicationName, url);
|
|
125
|
+
const tabRef = await browser.openURL(options.applicationName, url);
|
|
126
|
+
const tabId = `ID:${tabRef.windowId}:${tabRef.tabId}`;
|
|
126
127
|
return {
|
|
127
128
|
content: [
|
|
128
129
|
{
|
|
129
130
|
type: "text",
|
|
130
|
-
text: `Successfully opened
|
|
131
|
+
text: `Successfully opened URL in new tab. Tab: \`${tabId}\``,
|
|
131
132
|
},
|
|
132
133
|
],
|
|
133
134
|
};
|
package/package.json
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pokutuna/mcp-chrome-tabs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/pokutuna/mcp-chrome-tabs"
|
|
7
7
|
},
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"type": "module",
|
|
10
|
+
"keywords": [
|
|
11
|
+
"mcp",
|
|
12
|
+
"model-context-protocol",
|
|
13
|
+
"chrome",
|
|
14
|
+
"ai",
|
|
15
|
+
"macos"
|
|
16
|
+
],
|
|
10
17
|
"bin": {
|
|
11
18
|
"mcp-chrome-tabs": "./dist/cli.js"
|
|
12
19
|
},
|
|
@@ -28,18 +35,18 @@
|
|
|
28
35
|
"test:e2e": "playwright test"
|
|
29
36
|
},
|
|
30
37
|
"dependencies": {
|
|
31
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
32
|
-
"defuddle": "^0.6.
|
|
38
|
+
"@modelcontextprotocol/sdk": "^1.17.3",
|
|
39
|
+
"defuddle": "^0.6.6",
|
|
33
40
|
"jsdom": "^24.0.0",
|
|
34
41
|
"zod": "^3.25.76"
|
|
35
42
|
},
|
|
36
43
|
"devDependencies": {
|
|
37
|
-
"@playwright/test": "^1.
|
|
44
|
+
"@playwright/test": "^1.55.0",
|
|
38
45
|
"@types/node": "^20.11.17",
|
|
39
46
|
"playwright": "^1.54.1",
|
|
40
47
|
"prettier": "^3.6.2",
|
|
41
|
-
"tsx": "^4.
|
|
42
|
-
"typescript": "~5.
|
|
48
|
+
"tsx": "^4.20.4",
|
|
49
|
+
"typescript": "~5.9.2",
|
|
43
50
|
"vitest": "^3.2.4"
|
|
44
51
|
}
|
|
45
52
|
}
|