Skip to main content
Glama

@pokutuna/mcp-chrome-tabs

by pokutuna
chrome.ts3.85 kB
import type { BrowserInterface, TabRef, Tab, TabContent } from "./browser.js"; import { escapeAppleScript, executeAppleScript, separator, } from "./osascript.js"; async function getChromeTabList(applicationName: string): Promise<Tab[]> { const sep = separator(); const appleScript = ` tell application "${applicationName}" set output to "" repeat with aWindow in (every window) set windowId to id of aWindow repeat with aTab in (every tab of aWindow) set tabId to id of aTab set tabTitle to title of aTab set tabURL to URL of aTab set output to output & windowId & "${sep}" & tabId & "${sep}" & tabTitle & "${sep}" & tabURL & "\\n" end repeat end repeat return output end tell `; const result = await executeAppleScript(appleScript); const lines = result.trim().split("\n"); const tabs: Tab[] = []; for (const line of lines) { const [wId, tId, title, url] = line.split(sep); if (!/^https?:\/\//.test(url)) continue; tabs.push({ windowId: wId, tabId: tId, title: title.trim(), url: url.trim(), }); } return tabs; } async function getPageContent( applicationName: string, tab?: TabRef | null ): Promise<TabContent> { const sep = separator(); const inner = ` set tabTitle to title set tabURL to URL set tabContent to execute javascript "document.documentElement.outerHTML" return tabTitle & "${sep}" & tabURL & "${sep}" & tabContent `; const appleScript = tab ? ` try tell application "${applicationName}" tell window id "${tab.windowId}" tell tab id "${tab.tabId}" (* Chrome によって suspend されたタブで js を実行すると動作が停止する タイムアウトにより osascript コマンドの実行を retry したくないので apple script 内で timeout をしてエラーを返すようにする *) with timeout of 3 seconds ${inner} end timeout end tell end tell end tell on error errMsg return "ERROR" & "${sep}" & errMsg end try ` : ` try tell application "${applicationName}" repeat with w in windows tell w set t to tab (active tab index) if URL of t is not "about:blank" then tell t ${inner} end tell end if end tell end repeat error "No active tab found" end tell on error errMsg return "ERROR" & "${sep}" & errMsg end try `; const scriptResult = await executeAppleScript(appleScript); if (scriptResult.startsWith(`ERROR${sep}`)) { throw new Error(scriptResult.split(sep)[1]); } const parts = scriptResult.split(sep).map((part) => part.trim()); if (parts.length < 3) { throw new Error("Failed to read the tab content"); } const [title, url, content] = parts; return { title, url, content, }; } async function openURL(applicationName: string, url: string): Promise<TabRef> { const escapedUrl = escapeAppleScript(url); const sep = separator(); const appleScript = ` tell application "${applicationName}" set newTab to (make new tab at end of tabs of front window with properties {URL:"${escapedUrl}"}) set windowId to id of front window set tabId to id of newTab return windowId & "${sep}" & tabId end tell `; const result = await executeAppleScript(appleScript); const [windowId, tabId] = result.trim().split(sep); return { windowId, tabId }; } export const chromeBrowser: BrowserInterface = { getTabList: getChromeTabList, getPageContent, openURL, };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pokutuna/mcp-chrome-tabs'

If you have feedback or need assistance with the MCP directory API, please join our Discord server