💬 Commit message: Update 2026-02-11 18:40:23, 20 files, 434 lines
📁 Files changed: 20 📝 Lines changed: 434 • .mcp.json • plugin.json • settings.json • CLAUDE.md • analyze.md • compare.md • end.md • extract.md • fill.md • goto.md • restore.md • save.md • scrape.md • screenshot.md • start.md • mcp.js • mcp.js.map • package-lock.json • package.json • mcp.ts
This commit is contained in:
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"mcpServers": {
|
|
||||||
"context": {
|
|
||||||
"command": "node",
|
|
||||||
"args": ["${CLAUDE_PLUGIN_ROOT}/dist/mcp.js"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "browse",
|
|
||||||
"description": "Browser automation and image processing tools for Claude Code using Playwright WebKit",
|
|
||||||
"version": "0.2.13-pre.0",
|
|
||||||
"author": {
|
|
||||||
"name": "aladac",
|
|
||||||
"url": "https://github.com/aladac"
|
|
||||||
},
|
|
||||||
"repository": "https://github.com/saiden-dev/browse",
|
|
||||||
"license": "MIT",
|
|
||||||
"keywords": [
|
|
||||||
"browser",
|
|
||||||
"automation",
|
|
||||||
"playwright",
|
|
||||||
"webkit",
|
|
||||||
"screenshot",
|
|
||||||
"scraping",
|
|
||||||
"image-processing"
|
|
||||||
],
|
|
||||||
"mcpServers": "./.mcp.json",
|
|
||||||
"commands": "./commands"
|
|
||||||
}
|
|
||||||
+2
-12
@@ -1,18 +1,8 @@
|
|||||||
{
|
{
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"allow": [
|
"allow": [
|
||||||
"mcp__browse__goto",
|
"mcp__browse__*",
|
||||||
"mcp__browse__back",
|
"mcp__browse-dev__*"
|
||||||
"mcp__browse__forward",
|
|
||||||
"mcp__browse__reload",
|
|
||||||
"mcp__browse__click",
|
|
||||||
"mcp__browse__type",
|
|
||||||
"mcp__browse__query",
|
|
||||||
"mcp__browse__url",
|
|
||||||
"mcp__browse__html",
|
|
||||||
"mcp__browse__screenshot",
|
|
||||||
"mcp__browse__eval",
|
|
||||||
"mcp__browse__wait"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"enableAllProjectMcpServers": true
|
"enableAllProjectMcpServers": true
|
||||||
|
|||||||
@@ -96,25 +96,46 @@ curl localhost:13373 -d '{"cmd":"screenshot","path":"screenshots/page.png"}'
|
|||||||
|
|
||||||
## MCP Server
|
## MCP Server
|
||||||
|
|
||||||
Run as MCP server for Claude Code integration:
|
|
||||||
```bash
|
|
||||||
browse-mcp
|
|
||||||
```
|
|
||||||
|
|
||||||
The MCP server (`src/mcp.ts`) exposes all browser commands as tools. It uses stdio transport and auto-launches the browser on first command.
|
The MCP server (`src/mcp.ts`) exposes all browser commands as tools. It uses stdio transport and auto-launches the browser on first command.
|
||||||
|
|
||||||
### Plugin Integration
|
### Production Setup
|
||||||
|
|
||||||
When installed as a Claude Code plugin (`browse@saiden`), the MCP server is named `context`. Tools are accessed as:
|
Add to your project's `.mcp.json`:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"browse": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": ["browse-mcp"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
- `mcp__context__goto` - Navigate to URL
|
Tools are then accessible as `mcp__browse__*` (e.g., `mcp__browse__goto`, `mcp__browse__screenshot`).
|
||||||
- `mcp__context__query` - Query elements by CSS selector
|
|
||||||
- `mcp__context__click` - Click an element
|
|
||||||
- `mcp__context__type` - Type into an input field
|
|
||||||
- `mcp__context__screenshot` - Take a screenshot
|
|
||||||
- `mcp__context__close` - Close the browser
|
|
||||||
|
|
||||||
The plugin also provides slash commands: `/browse:start`, `/browse:goto`, `/browse:end`, etc.
|
### Development (this project only)
|
||||||
|
|
||||||
|
This project uses a local `.mcp.json` pointing to `dist/mcp.js` for development. Use `npm run dev` for hot-reload during development.
|
||||||
|
|
||||||
|
### Launch Options
|
||||||
|
|
||||||
|
Use the `launch` tool to configure browser mode before navigating:
|
||||||
|
|
||||||
|
| Option | Default | Description |
|
||||||
|
|--------|---------|-------------|
|
||||||
|
| `headed` | `false` | Show browser window |
|
||||||
|
| `fullscreen` | `false` | Native fullscreen mode (macOS, implies headed) |
|
||||||
|
| `preview` | `false` | Highlight elements before actions with visual overlay |
|
||||||
|
| `previewDelay` | `2000` | Duration of preview highlight in ms |
|
||||||
|
| `width` | `1280` | Viewport width |
|
||||||
|
| `height` | `800` | Viewport height |
|
||||||
|
|
||||||
|
Example: Launch in fullscreen with preview mode:
|
||||||
|
```
|
||||||
|
mcp__browse__launch({ fullscreen: true, preview: true })
|
||||||
|
mcp__browse__goto({ url: "https://example.com" })
|
||||||
|
```
|
||||||
|
|
||||||
### Debugging Tools
|
### Debugging Tools
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
description: Analyze the current page content and structure
|
|
||||||
---
|
|
||||||
|
|
||||||
Use the analyze_page MCP prompt to analyze the current browser page.
|
|
||||||
|
|
||||||
If the browser is not launched, first navigate to a URL using the goto tool, then analyze the page structure, content, and interactive elements.
|
|
||||||
|
|
||||||
Provide:
|
|
||||||
1. A summary of the page purpose
|
|
||||||
2. Key interactive elements (forms, buttons, links)
|
|
||||||
3. Notable structure or patterns
|
|
||||||
4. Suggestions for useful actions
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
description: Compare page states with screenshots before and after an action
|
|
||||||
---
|
|
||||||
|
|
||||||
Compare page states:
|
|
||||||
|
|
||||||
1. Take an initial screenshot of the current page
|
|
||||||
2. Ask what action to perform (click, navigate, submit, etc.)
|
|
||||||
3. Perform the requested action
|
|
||||||
4. Take another screenshot
|
|
||||||
5. Describe the visual and structural differences
|
|
||||||
|
|
||||||
What action would you like to perform between screenshots? $ARGUMENTS
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
description: End the current browsing session and close the browser
|
|
||||||
---
|
|
||||||
|
|
||||||
End the current browsing session.
|
|
||||||
|
|
||||||
Use the `close` tool to close the browser. This will:
|
|
||||||
1. Close all browser pages
|
|
||||||
2. Clear the browser state
|
|
||||||
3. Free up system resources
|
|
||||||
|
|
||||||
The browser can be relaunched with any navigation command (goto, start, etc.)
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
description: Extract structured data from the current page
|
|
||||||
---
|
|
||||||
|
|
||||||
Extract structured data from the current browser page.
|
|
||||||
|
|
||||||
Selector (optional): $ARGUMENTS
|
|
||||||
|
|
||||||
Steps:
|
|
||||||
1. If a selector is provided, use the query tool to find matching elements
|
|
||||||
2. Analyze the page structure to identify data patterns
|
|
||||||
3. Extract and structure the data in a useful format (JSON, table, etc.)
|
|
||||||
4. Identify patterns that could help with similar pages
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
description: Help fill out a form on the current page
|
|
||||||
---
|
|
||||||
|
|
||||||
Fill form with data: $ARGUMENTS
|
|
||||||
|
|
||||||
Steps:
|
|
||||||
1. Use the query tool to find form inputs (input, textarea, select)
|
|
||||||
2. Identify required fields and their types
|
|
||||||
3. If data is provided, parse it and fill the matching fields using the type tool
|
|
||||||
4. Report what was filled and any issues encountered
|
|
||||||
|
|
||||||
If no data provided, describe the form fields found and ask what to fill in.
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
description: Navigate to a URL and describe what you find
|
|
||||||
---
|
|
||||||
|
|
||||||
Navigate to: $ARGUMENTS
|
|
||||||
|
|
||||||
Steps:
|
|
||||||
1. Use the goto tool to navigate to the URL
|
|
||||||
2. Take a screenshot to see the page
|
|
||||||
3. Describe what you see
|
|
||||||
4. Identify the main interactive elements
|
|
||||||
5. Suggest what actions might be useful
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
description: Restore a previously saved browsing session
|
|
||||||
---
|
|
||||||
|
|
||||||
Restore session from: $ARGUMENTS
|
|
||||||
|
|
||||||
Use the `session_restore` tool to restore a previously saved session:
|
|
||||||
- Navigate to the saved URL
|
|
||||||
- Restore all cookies
|
|
||||||
- Restore localStorage data
|
|
||||||
- Restore sessionStorage data
|
|
||||||
|
|
||||||
If no path is specified, restore from `session.json` in the current directory.
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
---
|
|
||||||
description: Save the current browsing session state to a file
|
|
||||||
---
|
|
||||||
|
|
||||||
Save the current session state to: $ARGUMENTS
|
|
||||||
|
|
||||||
Use the `session_save` tool to save:
|
|
||||||
- Current URL and page title
|
|
||||||
- All cookies
|
|
||||||
- localStorage data
|
|
||||||
- sessionStorage data
|
|
||||||
|
|
||||||
If no path is specified, save to `session.json` in the current directory.
|
|
||||||
|
|
||||||
This allows you to restore the session later with `/browse:restore`.
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
---
|
|
||||||
description: Scrape content from a webpage
|
|
||||||
---
|
|
||||||
|
|
||||||
Scrape and extract content from: $ARGUMENTS
|
|
||||||
|
|
||||||
Steps:
|
|
||||||
1. Navigate to the URL using `goto`
|
|
||||||
2. Wait for the page to load
|
|
||||||
3. Query the page structure to understand the layout
|
|
||||||
4. Extract the relevant content using `query` and `eval` tools
|
|
||||||
5. Return the structured data
|
|
||||||
|
|
||||||
Focus on extracting meaningful content (text, links, data) rather than raw HTML.
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
---
|
|
||||||
description: Take a screenshot of the current page
|
|
||||||
---
|
|
||||||
|
|
||||||
Take a screenshot of the current browser page and analyze its contents.
|
|
||||||
|
|
||||||
If the browser hasn't been started yet, ask for a URL first, navigate there, then take the screenshot.
|
|
||||||
|
|
||||||
Use the `screenshot` tool with fullPage=$ARGUMENTS if specified (true/false), otherwise use default viewport.
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
description: Start an interactive browsing session
|
|
||||||
---
|
|
||||||
|
|
||||||
Start an interactive browser session. Use the browser tools to:
|
|
||||||
1. Navigate to URLs with `goto`
|
|
||||||
2. Take screenshots to see page content
|
|
||||||
3. Query elements with CSS selectors
|
|
||||||
4. Click and type to interact with pages
|
|
||||||
|
|
||||||
The browser is headless WebKit (Safari engine). Start by asking what URL to visit.
|
|
||||||
Vendored
+65
-1
@@ -10,7 +10,16 @@ import * as image from './image.js';
|
|||||||
import { stderrLogger as log } from './logger.js';
|
import { stderrLogger as log } from './logger.js';
|
||||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
const pkg = JSON.parse(readFileSync(resolve(__dirname, '../package.json'), 'utf-8'));
|
const pkg = JSON.parse(readFileSync(resolve(__dirname, '../package.json'), 'utf-8'));
|
||||||
const browser = new ClaudeBrowser({ headless: true, width: 1280, height: 800 });
|
// Browser options configurable via launch tool
|
||||||
|
let browserOptions = {
|
||||||
|
headless: true,
|
||||||
|
width: 1280,
|
||||||
|
height: 800,
|
||||||
|
fullscreen: false,
|
||||||
|
preview: false,
|
||||||
|
previewDelay: 2000,
|
||||||
|
};
|
||||||
|
let browser = new ClaudeBrowser(browserOptions);
|
||||||
let launched = false;
|
let launched = false;
|
||||||
let currentScreenshotBuffer = null;
|
let currentScreenshotBuffer = null;
|
||||||
async function ensureLaunched() {
|
async function ensureLaunched() {
|
||||||
@@ -43,6 +52,61 @@ const server = new McpServer({
|
|||||||
name: 'browse',
|
name: 'browse',
|
||||||
version: pkg.version,
|
version: pkg.version,
|
||||||
});
|
});
|
||||||
|
// Launch configuration
|
||||||
|
server.tool('launch', 'Launch the browser with specific options. Call before goto to configure headed/fullscreen/preview modes.', {
|
||||||
|
headed: z
|
||||||
|
.boolean()
|
||||||
|
.optional()
|
||||||
|
.default(false)
|
||||||
|
.describe('Show browser window (default: false, headless)'),
|
||||||
|
fullscreen: z
|
||||||
|
.boolean()
|
||||||
|
.optional()
|
||||||
|
.default(false)
|
||||||
|
.describe('Launch in native fullscreen mode (macOS only, implies headed)'),
|
||||||
|
preview: z
|
||||||
|
.boolean()
|
||||||
|
.optional()
|
||||||
|
.default(false)
|
||||||
|
.describe('Highlight elements before actions with visual overlay'),
|
||||||
|
previewDelay: z
|
||||||
|
.number()
|
||||||
|
.optional()
|
||||||
|
.default(2000)
|
||||||
|
.describe('Preview highlight duration in ms'),
|
||||||
|
width: z.number().optional().default(1280).describe('Viewport width'),
|
||||||
|
height: z.number().optional().default(800).describe('Viewport height'),
|
||||||
|
}, withLogging('launch', async ({ headed, fullscreen, preview, previewDelay, width, height }) => {
|
||||||
|
// Close existing browser if launched
|
||||||
|
if (launched) {
|
||||||
|
await browser.close();
|
||||||
|
launched = false;
|
||||||
|
}
|
||||||
|
// Update options - fullscreen/preview imply headed
|
||||||
|
browserOptions = {
|
||||||
|
headless: fullscreen || preview ? false : !headed,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
fullscreen,
|
||||||
|
preview,
|
||||||
|
previewDelay,
|
||||||
|
};
|
||||||
|
// Create new browser with updated options
|
||||||
|
browser = new ClaudeBrowser(browserOptions);
|
||||||
|
await browser.launch();
|
||||||
|
launched = true;
|
||||||
|
return textResult(JSON.stringify({
|
||||||
|
ok: true,
|
||||||
|
message: 'Browser launched',
|
||||||
|
options: {
|
||||||
|
headed: !browserOptions.headless,
|
||||||
|
fullscreen,
|
||||||
|
preview,
|
||||||
|
previewDelay,
|
||||||
|
viewport: { width, height },
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}));
|
||||||
// Navigation
|
// Navigation
|
||||||
server.tool('goto', 'Navigate to a URL', { url: z.string().url() }, withLogging('goto', async ({ url }) => {
|
server.tool('goto', 'Navigate to a URL', { url: z.string().url() }, withLogging('goto', async ({ url }) => {
|
||||||
await ensureLaunched();
|
await ensureLaunched();
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Generated
+59
@@ -24,6 +24,7 @@
|
|||||||
"@types/node": "^20.11.0",
|
"@types/node": "^20.11.0",
|
||||||
"@types/sharp": "^0.31.1",
|
"@types/sharp": "^0.31.1",
|
||||||
"@vitest/coverage-v8": "^4.0.18",
|
"@vitest/coverage-v8": "^4.0.18",
|
||||||
|
"tsx": "^4.21.0",
|
||||||
"typescript": "^5.3.0",
|
"typescript": "^5.3.0",
|
||||||
"vitest": "^4.0.18"
|
"vitest": "^4.0.18"
|
||||||
},
|
},
|
||||||
@@ -2418,6 +2419,19 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/get-tsconfig": {
|
||||||
|
"version": "4.13.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz",
|
||||||
|
"integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"resolve-pkg-maps": "^1.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/gopd": {
|
"node_modules/gopd": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||||
@@ -3011,6 +3025,16 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/resolve-pkg-maps": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/rollup": {
|
"node_modules/rollup": {
|
||||||
"version": "4.57.1",
|
"version": "4.57.1",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.57.1.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.57.1.tgz",
|
||||||
@@ -3391,6 +3415,41 @@
|
|||||||
"license": "0BSD",
|
"license": "0BSD",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"node_modules/tsx": {
|
||||||
|
"version": "4.21.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz",
|
||||||
|
"integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"esbuild": "~0.27.0",
|
||||||
|
"get-tsconfig": "^4.7.5"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"tsx": "dist/cli.mjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"fsevents": "~2.3.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tsx/node_modules/fsevents": {
|
||||||
|
"version": "2.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||||
|
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/type-is": {
|
"node_modules/type-is": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
|
||||||
|
|||||||
@@ -59,6 +59,7 @@
|
|||||||
"@types/node": "^20.11.0",
|
"@types/node": "^20.11.0",
|
||||||
"@types/sharp": "^0.31.1",
|
"@types/sharp": "^0.31.1",
|
||||||
"@vitest/coverage-v8": "^4.0.18",
|
"@vitest/coverage-v8": "^4.0.18",
|
||||||
|
"tsx": "^4.21.0",
|
||||||
"typescript": "^5.3.0",
|
"typescript": "^5.3.0",
|
||||||
"vitest": "^4.0.18"
|
"vitest": "^4.0.18"
|
||||||
},
|
},
|
||||||
|
|||||||
+76
-1
@@ -12,7 +12,16 @@ import { type CommandLike, type ResultLike, stderrLogger as log } from './logger
|
|||||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
const pkg = JSON.parse(readFileSync(resolve(__dirname, '../package.json'), 'utf-8'));
|
const pkg = JSON.parse(readFileSync(resolve(__dirname, '../package.json'), 'utf-8'));
|
||||||
|
|
||||||
const browser = new ClaudeBrowser({ headless: true, width: 1280, height: 800 });
|
// Browser options configurable via launch tool
|
||||||
|
let browserOptions = {
|
||||||
|
headless: true,
|
||||||
|
width: 1280,
|
||||||
|
height: 800,
|
||||||
|
fullscreen: false,
|
||||||
|
preview: false,
|
||||||
|
previewDelay: 2000,
|
||||||
|
};
|
||||||
|
let browser = new ClaudeBrowser(browserOptions);
|
||||||
let launched = false;
|
let launched = false;
|
||||||
let currentScreenshotBuffer: Buffer | null = null;
|
let currentScreenshotBuffer: Buffer | null = null;
|
||||||
|
|
||||||
@@ -54,6 +63,72 @@ const server = new McpServer({
|
|||||||
version: pkg.version,
|
version: pkg.version,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Launch configuration
|
||||||
|
server.tool(
|
||||||
|
'launch',
|
||||||
|
'Launch the browser with specific options. Call before goto to configure headed/fullscreen/preview modes.',
|
||||||
|
{
|
||||||
|
headed: z
|
||||||
|
.boolean()
|
||||||
|
.optional()
|
||||||
|
.default(false)
|
||||||
|
.describe('Show browser window (default: false, headless)'),
|
||||||
|
fullscreen: z
|
||||||
|
.boolean()
|
||||||
|
.optional()
|
||||||
|
.default(false)
|
||||||
|
.describe('Launch in native fullscreen mode (macOS only, implies headed)'),
|
||||||
|
preview: z
|
||||||
|
.boolean()
|
||||||
|
.optional()
|
||||||
|
.default(false)
|
||||||
|
.describe('Highlight elements before actions with visual overlay'),
|
||||||
|
previewDelay: z
|
||||||
|
.number()
|
||||||
|
.optional()
|
||||||
|
.default(2000)
|
||||||
|
.describe('Preview highlight duration in ms'),
|
||||||
|
width: z.number().optional().default(1280).describe('Viewport width'),
|
||||||
|
height: z.number().optional().default(800).describe('Viewport height'),
|
||||||
|
},
|
||||||
|
withLogging('launch', async ({ headed, fullscreen, preview, previewDelay, width, height }) => {
|
||||||
|
// Close existing browser if launched
|
||||||
|
if (launched) {
|
||||||
|
await browser.close();
|
||||||
|
launched = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update options - fullscreen/preview imply headed
|
||||||
|
browserOptions = {
|
||||||
|
headless: fullscreen || preview ? false : !headed,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
fullscreen,
|
||||||
|
preview,
|
||||||
|
previewDelay,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create new browser with updated options
|
||||||
|
browser = new ClaudeBrowser(browserOptions);
|
||||||
|
await browser.launch();
|
||||||
|
launched = true;
|
||||||
|
|
||||||
|
return textResult(
|
||||||
|
JSON.stringify({
|
||||||
|
ok: true,
|
||||||
|
message: 'Browser launched',
|
||||||
|
options: {
|
||||||
|
headed: !browserOptions.headless,
|
||||||
|
fullscreen,
|
||||||
|
preview,
|
||||||
|
previewDelay,
|
||||||
|
viewport: { width, height },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
server.tool(
|
server.tool(
|
||||||
'goto',
|
'goto',
|
||||||
|
|||||||
Reference in New Issue
Block a user