@ebowwa/mcp-browser 0.1.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 ADDED
@@ -0,0 +1,147 @@
1
+ # @ebowwa/mcp-browser
2
+
3
+ MCP server for browser automation via [dev-browser](https://github.com/sawyerhood/dev-browser).
4
+
5
+ **This is an optional extension** - Coder works without it. Install only if you need browser automation.
6
+
7
+ ## Features
8
+
9
+ - **Optional dependency** - dev-browser is a peer dependency, not required
10
+ - **Graceful degradation** - Coder continues if dev-browser isn't installed
11
+ - **Full Playwright API** - Navigate, click, fill, screenshot, evaluate
12
+ - **AI-friendly snapshots** - `page.snapshotForAI()` for structured page state
13
+ - **Persistent pages** - Browser tabs persist across tool calls
14
+
15
+ ## Installation
16
+
17
+ ### 1. Install dev-browser (required for browser automation)
18
+
19
+ ```bash
20
+ npm install -g dev-browser
21
+ dev-browser install # Installs Playwright + Chromium
22
+ ```
23
+
24
+ ### 2. Add to Coder's MCP config
25
+
26
+ Add to `~/.claude.json`:
27
+
28
+ ```json
29
+ {
30
+ "mcpServers": {
31
+ "browser": {
32
+ "command": "mcp-browser",
33
+ "type": "stdio"
34
+ }
35
+ }
36
+ }
37
+ ```
38
+
39
+ ## Tools
40
+
41
+ | Tool | Description |
42
+ |------|-------------|
43
+ | `browser_status` | Check if dev-browser is available |
44
+ | `browser_help` | Get dev-browser CLI help |
45
+ | `browser_navigate` | Navigate to URL |
46
+ | `browser_get_url` | Get current URL |
47
+ | `browser_get_title` | Get page title |
48
+ | `browser_list_pages` | List all browser tabs |
49
+ | `browser_close_page` | Close a named page |
50
+ | `browser_click` | Click element by selector |
51
+ | `browser_fill` | Fill form field |
52
+ | `browser_type` | Type text (appends) |
53
+ | `browser_press` | Press keyboard key |
54
+ | `browser_wait_for_selector` | Wait for element |
55
+ | `browser_snapshot` | Get AI-friendly page state |
56
+ | `browser_screenshot` | Take screenshot |
57
+ | `browser_evaluate` | Run JavaScript in page |
58
+ | `browser_execute_script` | Run raw dev-browser script |
59
+
60
+ ## Usage Examples
61
+
62
+ ### Navigate and interact
63
+
64
+ ```
65
+ User: "Go to github.com and search for 'mcp'"
66
+
67
+ → browser_navigate({ url: "https://github.com" })
68
+ → browser_fill({ selector: "[name='q']", value: "mcp" })
69
+ → browser_press({ key: "Enter" })
70
+ → browser_snapshot({})
71
+ ```
72
+
73
+ ### Get AI-friendly page state
74
+
75
+ ```
76
+ → browser_snapshot({ pageName: "main", depth: 10 })
77
+
78
+ Returns:
79
+ {
80
+ "full": "# GitHub\n\n## Search Results\n\n- mcp (Model Context Protocol)\n- ...",
81
+ "incremental": "..."
82
+ }
83
+ ```
84
+
85
+ ### Take screenshot
86
+
87
+ ```
88
+ → browser_screenshot({ filename: "search-results.png" })
89
+
90
+ Returns:
91
+ {
92
+ "success": true,
93
+ "data": { "path": "~/.dev-browser/tmp/search-results.png" }
94
+ }
95
+ ```
96
+
97
+ ### Execute custom script
98
+
99
+ ```
100
+ → browser_execute_script({
101
+ script: `
102
+ const page = await browser.getPage("main");
103
+ await page.goto("https://example.com");
104
+ const links = await page.$$eval('a', els => els.map(e => e.href));
105
+ console.log(JSON.stringify(links));
106
+ `
107
+ })
108
+ ```
109
+
110
+ ## When dev-browser is NOT installed
111
+
112
+ Coder gracefully handles the missing dependency:
113
+
114
+ ```
115
+ → browser_navigate({ url: "https://example.com" })
116
+
117
+ Returns:
118
+ {
119
+ "success": false,
120
+ "error": "dev-browser is not installed",
121
+ "hint": "Install with: npm install -g dev-browser && dev-browser install"
122
+ }
123
+ ```
124
+
125
+ Coder continues to work with all other tools - browser automation is simply unavailable.
126
+
127
+ ## Architecture
128
+
129
+ ```
130
+ Coder
131
+ ├── MCP Client
132
+ │ └── connects to → mcp-browser (optional)
133
+ │ └── wraps → dev-browser CLI
134
+ │ └── QuickJS WASM sandbox
135
+ │ └── Playwright API
136
+ ```
137
+
138
+ ## Why Optional?
139
+
140
+ - **Not all tasks need browsers** - Most coding tasks are file/code operations
141
+ - **Smaller footprint** - No browser dependencies in core Coder
142
+ - **User choice** - Install only what you need
143
+ - **CI/CD friendly** - Headless environments may not want browser overhead
144
+
145
+ ## License
146
+
147
+ MIT
@@ -0,0 +1,104 @@
1
+ /**
2
+ * dev-browser CLI client wrapper
3
+ *
4
+ * Provides a TypeScript interface to the dev-browser CLI.
5
+ * Falls back gracefully if dev-browser is not installed.
6
+ */
7
+ export interface BrowserPage {
8
+ id: string;
9
+ url: string;
10
+ title: string;
11
+ name?: string;
12
+ }
13
+ export interface BrowserResult {
14
+ success: boolean;
15
+ output?: string;
16
+ error?: string;
17
+ data?: unknown;
18
+ }
19
+ export interface SnapshotResult {
20
+ full: string;
21
+ incremental?: string;
22
+ }
23
+ export interface ScreenshotResult {
24
+ path: string;
25
+ base64?: string;
26
+ }
27
+ /**
28
+ * Check if dev-browser CLI is available
29
+ */
30
+ export declare function isDevBrowserAvailable(): Promise<boolean>;
31
+ /**
32
+ * Get dev-browser CLI help text (useful for LLM context)
33
+ */
34
+ export declare function getDevBrowserHelp(): Promise<string>;
35
+ interface CommandOptions {
36
+ timeout?: number;
37
+ headless?: boolean;
38
+ connect?: boolean;
39
+ }
40
+ /**
41
+ * Execute a dev-browser script
42
+ */
43
+ export declare function executeScript(script: string, options?: CommandOptions): Promise<BrowserResult>;
44
+ /**
45
+ * Navigate to a URL
46
+ */
47
+ export declare function navigate(url: string, pageName?: string): Promise<BrowserResult>;
48
+ /**
49
+ * Click an element
50
+ */
51
+ export declare function click(selector: string, pageName?: string): Promise<BrowserResult>;
52
+ /**
53
+ * Fill a form field
54
+ */
55
+ export declare function fill(selector: string, value: string, pageName?: string): Promise<BrowserResult>;
56
+ /**
57
+ * Get page snapshot for AI analysis
58
+ */
59
+ export declare function snapshot(options?: {
60
+ pageName?: string;
61
+ depth?: number;
62
+ track?: string[];
63
+ }): Promise<BrowserResult>;
64
+ /**
65
+ * Take a screenshot
66
+ */
67
+ export declare function screenshot(filename: string, pageName?: string): Promise<BrowserResult>;
68
+ /**
69
+ * List all browser pages/tabs
70
+ */
71
+ export declare function listPages(): Promise<BrowserResult>;
72
+ /**
73
+ * Evaluate JavaScript in the page context
74
+ */
75
+ export declare function evaluate(jsCode: string, pageName?: string): Promise<BrowserResult>;
76
+ /**
77
+ * Wait for a selector to appear
78
+ */
79
+ export declare function waitForSelector(selector: string, options?: {
80
+ pageName?: string;
81
+ timeout?: number;
82
+ }): Promise<BrowserResult>;
83
+ /**
84
+ * Get page title
85
+ */
86
+ export declare function getTitle(pageName?: string): Promise<BrowserResult>;
87
+ /**
88
+ * Get current URL
89
+ */
90
+ export declare function getUrl(pageName?: string): Promise<BrowserResult>;
91
+ /**
92
+ * Close a named page
93
+ */
94
+ export declare function closePage(pageName: string): Promise<BrowserResult>;
95
+ /**
96
+ * Type text (for inputs that don't respond to fill)
97
+ */
98
+ export declare function type(selector: string, text: string, pageName?: string): Promise<BrowserResult>;
99
+ /**
100
+ * Press a key
101
+ */
102
+ export declare function press(key: string, pageName?: string): Promise<BrowserResult>;
103
+ export {};
104
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js ADDED
@@ -0,0 +1,275 @@
1
+ /**
2
+ * dev-browser CLI client wrapper
3
+ *
4
+ * Provides a TypeScript interface to the dev-browser CLI.
5
+ * Falls back gracefully if dev-browser is not installed.
6
+ */
7
+ import { spawn } from "child_process";
8
+ /**
9
+ * Check if dev-browser CLI is available
10
+ */
11
+ export async function isDevBrowserAvailable() {
12
+ try {
13
+ const result = await runDevBrowserCommand(["--version"], { timeout: 5000 });
14
+ return result.success;
15
+ }
16
+ catch {
17
+ return false;
18
+ }
19
+ }
20
+ /**
21
+ * Get dev-browser CLI help text (useful for LLM context)
22
+ */
23
+ export async function getDevBrowserHelp() {
24
+ const result = await runDevBrowserCommand(["--help"], { timeout: 10000 });
25
+ return result.output || "";
26
+ }
27
+ /**
28
+ * Execute a dev-browser script
29
+ */
30
+ export async function executeScript(script, options = {}) {
31
+ const args = [];
32
+ if (options.headless !== false) {
33
+ args.push("--headless");
34
+ }
35
+ if (options.connect) {
36
+ args.push("--connect");
37
+ }
38
+ return runDevBrowserCommand(args, {
39
+ ...options,
40
+ stdin: script,
41
+ });
42
+ }
43
+ /**
44
+ * Run a raw dev-browser command
45
+ */
46
+ async function runDevBrowserCommand(args, options = {}) {
47
+ return new Promise((resolve) => {
48
+ const proc = spawn("dev-browser", args, {
49
+ stdio: ["pipe", "pipe", "pipe"],
50
+ });
51
+ let stdout = "";
52
+ let stderr = "";
53
+ proc.stdout.on("data", (data) => {
54
+ stdout += data.toString();
55
+ });
56
+ proc.stderr.on("data", (data) => {
57
+ stderr += data.toString();
58
+ });
59
+ // Send stdin if provided
60
+ if (options.stdin) {
61
+ proc.stdin.write(options.stdin);
62
+ proc.stdin.end();
63
+ }
64
+ // Timeout handling
65
+ const timeout = options.timeout || 60000;
66
+ const timer = setTimeout(() => {
67
+ proc.kill();
68
+ resolve({
69
+ success: false,
70
+ error: `Command timed out after ${timeout}ms`,
71
+ });
72
+ }, timeout);
73
+ proc.on("close", (code) => {
74
+ clearTimeout(timer);
75
+ if (code === 0) {
76
+ resolve({
77
+ success: true,
78
+ output: stdout,
79
+ });
80
+ }
81
+ else {
82
+ resolve({
83
+ success: false,
84
+ output: stdout,
85
+ error: stderr || `Exit code: ${code}`,
86
+ });
87
+ }
88
+ });
89
+ proc.on("error", (err) => {
90
+ clearTimeout(timer);
91
+ resolve({
92
+ success: false,
93
+ error: err.message,
94
+ });
95
+ });
96
+ });
97
+ }
98
+ // ============================================================================
99
+ // High-level Browser Operations
100
+ // ============================================================================
101
+ /**
102
+ * Navigate to a URL
103
+ */
104
+ export async function navigate(url, pageName = "main") {
105
+ const script = `
106
+ const page = await browser.getPage("${pageName}");
107
+ await page.goto("${url}");
108
+ console.log(JSON.stringify({ url: page.url(), title: await page.title() }));
109
+ `;
110
+ return executeScript(script);
111
+ }
112
+ /**
113
+ * Click an element
114
+ */
115
+ export async function click(selector, pageName = "main") {
116
+ const script = `
117
+ const page = await browser.getPage("${pageName}");
118
+ await page.click("${selector}");
119
+ console.log("Clicked: ${selector}");
120
+ `;
121
+ return executeScript(script);
122
+ }
123
+ /**
124
+ * Fill a form field
125
+ */
126
+ export async function fill(selector, value, pageName = "main") {
127
+ const script = `
128
+ const page = await browser.getPage("${pageName}");
129
+ await page.fill("${selector}", "${value.replace(/"/g, '\\"')}");
130
+ console.log("Filled: ${selector}");
131
+ `;
132
+ return executeScript(script);
133
+ }
134
+ /**
135
+ * Get page snapshot for AI analysis
136
+ */
137
+ export async function snapshot(options = {}) {
138
+ const pageName = options.pageName || "main";
139
+ const depth = options.depth || 10;
140
+ const track = options.track?.join(",") || "";
141
+ const script = `
142
+ const page = await browser.getPage("${pageName}");
143
+ const result = await page.snapshotForAI({ depth: ${depth}, track: "${track}" });
144
+ console.log(JSON.stringify(result));
145
+ `;
146
+ const result = await executeScript(script);
147
+ if (result.success && result.output) {
148
+ try {
149
+ result.data = JSON.parse(result.output);
150
+ }
151
+ catch {
152
+ // Output might not be JSON
153
+ }
154
+ }
155
+ return result;
156
+ }
157
+ /**
158
+ * Take a screenshot
159
+ */
160
+ export async function screenshot(filename, pageName = "main") {
161
+ const script = `
162
+ const page = await browser.getPage("${pageName}");
163
+ const buf = await page.screenshot();
164
+ const path = await saveScreenshot(buf, "${filename}");
165
+ console.log(JSON.stringify({ path }));
166
+ `;
167
+ const result = await executeScript(script);
168
+ if (result.success && result.output) {
169
+ try {
170
+ result.data = JSON.parse(result.output);
171
+ }
172
+ catch {
173
+ // Output might not be JSON
174
+ }
175
+ }
176
+ return result;
177
+ }
178
+ /**
179
+ * List all browser pages/tabs
180
+ */
181
+ export async function listPages() {
182
+ const script = `
183
+ const tabs = await browser.listPages();
184
+ console.log(JSON.stringify(tabs, null, 2));
185
+ `;
186
+ const result = await executeScript(script);
187
+ if (result.success && result.output) {
188
+ try {
189
+ result.data = JSON.parse(result.output);
190
+ }
191
+ catch {
192
+ // Output might not be JSON
193
+ }
194
+ }
195
+ return result;
196
+ }
197
+ /**
198
+ * Evaluate JavaScript in the page context
199
+ */
200
+ export async function evaluate(jsCode, pageName = "main") {
201
+ const script = `
202
+ const page = await browser.getPage("${pageName}");
203
+ const result = await page.evaluate(() => {
204
+ ${jsCode}
205
+ });
206
+ console.log(JSON.stringify(result));
207
+ `;
208
+ return executeScript(script);
209
+ }
210
+ /**
211
+ * Wait for a selector to appear
212
+ */
213
+ export async function waitForSelector(selector, options = {}) {
214
+ const pageName = options.pageName || "main";
215
+ const timeout = options.timeout || 30000;
216
+ const script = `
217
+ const page = await browser.getPage("${pageName}");
218
+ await page.waitForSelector("${selector}", { timeout: ${timeout} });
219
+ console.log("Found: ${selector}");
220
+ `;
221
+ return executeScript(script, { timeout: timeout + 10000 });
222
+ }
223
+ /**
224
+ * Get page title
225
+ */
226
+ export async function getTitle(pageName = "main") {
227
+ const script = `
228
+ const page = await browser.getPage("${pageName}");
229
+ console.log(await page.title());
230
+ `;
231
+ return executeScript(script);
232
+ }
233
+ /**
234
+ * Get current URL
235
+ */
236
+ export async function getUrl(pageName = "main") {
237
+ const script = `
238
+ const page = await browser.getPage("${pageName}");
239
+ console.log(page.url());
240
+ `;
241
+ return executeScript(script);
242
+ }
243
+ /**
244
+ * Close a named page
245
+ */
246
+ export async function closePage(pageName) {
247
+ const script = `
248
+ await browser.closePage("${pageName}");
249
+ console.log("Closed: ${pageName}");
250
+ `;
251
+ return executeScript(script);
252
+ }
253
+ /**
254
+ * Type text (for inputs that don't respond to fill)
255
+ */
256
+ export async function type(selector, text, pageName = "main") {
257
+ const script = `
258
+ const page = await browser.getPage("${pageName}");
259
+ await page.type("${selector}", "${text.replace(/"/g, '\\"')}");
260
+ console.log("Typed into: ${selector}");
261
+ `;
262
+ return executeScript(script);
263
+ }
264
+ /**
265
+ * Press a key
266
+ */
267
+ export async function press(key, pageName = "main") {
268
+ const script = `
269
+ const page = await browser.getPage("${pageName}");
270
+ await page.keyboard.press("${key}");
271
+ console.log("Pressed: ${key}");
272
+ `;
273
+ return executeScript(script);
274
+ }
275
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @ebowwa/mcp-browser
4
+ *
5
+ * MCP server for browser automation via dev-browser.
6
+ * Optional extension - gracefully handles when dev-browser is not installed.
7
+ *
8
+ * Usage:
9
+ * Add to ~/.claude.json:
10
+ * {
11
+ * "mcpServers": {
12
+ * "browser": {
13
+ * "command": "mcp-browser",
14
+ * "type": "stdio"
15
+ * }
16
+ * }
17
+ * }
18
+ */
19
+ export {};
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;GAgBG"}
package/dist/index.js ADDED
@@ -0,0 +1,634 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @ebowwa/mcp-browser
4
+ *
5
+ * MCP server for browser automation via dev-browser.
6
+ * Optional extension - gracefully handles when dev-browser is not installed.
7
+ *
8
+ * Usage:
9
+ * Add to ~/.claude.json:
10
+ * {
11
+ * "mcpServers": {
12
+ * "browser": {
13
+ * "command": "mcp-browser",
14
+ * "type": "stdio"
15
+ * }
16
+ * }
17
+ * }
18
+ */
19
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
20
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
21
+ import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
22
+ import { isDevBrowserAvailable, getDevBrowserHelp, navigate, click, fill, snapshot, screenshot, listPages, evaluate, waitForSelector, getTitle, getUrl, closePage, type, press, executeScript, } from "./client.js";
23
+ // ============================================================================
24
+ // Server State
25
+ // ============================================================================
26
+ let browserStatus = {
27
+ available: false,
28
+ lastChecked: new Date(),
29
+ };
30
+ // ============================================================================
31
+ // Tool Definitions
32
+ // ============================================================================
33
+ const TOOLS = [
34
+ // Status & Info
35
+ {
36
+ name: "browser_status",
37
+ description: "Check if dev-browser is available and get status info",
38
+ inputSchema: {
39
+ type: "object",
40
+ properties: {},
41
+ },
42
+ },
43
+ {
44
+ name: "browser_help",
45
+ description: "Get dev-browser CLI help text with examples (useful for understanding capabilities)",
46
+ inputSchema: {
47
+ type: "object",
48
+ properties: {},
49
+ },
50
+ },
51
+ // Navigation
52
+ {
53
+ name: "browser_navigate",
54
+ description: "Navigate to a URL in a named page (creates page if doesn't exist)",
55
+ inputSchema: {
56
+ type: "object",
57
+ properties: {
58
+ url: {
59
+ type: "string",
60
+ description: "URL to navigate to",
61
+ },
62
+ pageName: {
63
+ type: "string",
64
+ description: "Page name (default: 'main')",
65
+ default: "main",
66
+ },
67
+ },
68
+ required: ["url"],
69
+ },
70
+ },
71
+ {
72
+ name: "browser_get_url",
73
+ description: "Get the current URL of a page",
74
+ inputSchema: {
75
+ type: "object",
76
+ properties: {
77
+ pageName: {
78
+ type: "string",
79
+ description: "Page name (default: 'main')",
80
+ default: "main",
81
+ },
82
+ },
83
+ },
84
+ },
85
+ {
86
+ name: "browser_get_title",
87
+ description: "Get the page title",
88
+ inputSchema: {
89
+ type: "object",
90
+ properties: {
91
+ pageName: {
92
+ type: "string",
93
+ description: "Page name (default: 'main')",
94
+ default: "main",
95
+ },
96
+ },
97
+ },
98
+ },
99
+ // Page Management
100
+ {
101
+ name: "browser_list_pages",
102
+ description: "List all browser pages/tabs",
103
+ inputSchema: {
104
+ type: "object",
105
+ properties: {},
106
+ },
107
+ },
108
+ {
109
+ name: "browser_close_page",
110
+ description: "Close a named page",
111
+ inputSchema: {
112
+ type: "object",
113
+ properties: {
114
+ pageName: {
115
+ type: "string",
116
+ description: "Page name to close",
117
+ },
118
+ },
119
+ required: ["pageName"],
120
+ },
121
+ },
122
+ // Interactions
123
+ {
124
+ name: "browser_click",
125
+ description: "Click an element by selector",
126
+ inputSchema: {
127
+ type: "object",
128
+ properties: {
129
+ selector: {
130
+ type: "string",
131
+ description: "CSS selector for element to click",
132
+ },
133
+ pageName: {
134
+ type: "string",
135
+ description: "Page name (default: 'main')",
136
+ default: "main",
137
+ },
138
+ },
139
+ required: ["selector"],
140
+ },
141
+ },
142
+ {
143
+ name: "browser_fill",
144
+ description: "Fill a form field with text (clears existing content first)",
145
+ inputSchema: {
146
+ type: "object",
147
+ properties: {
148
+ selector: {
149
+ type: "string",
150
+ description: "CSS selector for input field",
151
+ },
152
+ value: {
153
+ type: "string",
154
+ description: "Value to fill",
155
+ },
156
+ pageName: {
157
+ type: "string",
158
+ description: "Page name (default: 'main')",
159
+ default: "main",
160
+ },
161
+ },
162
+ required: ["selector", "value"],
163
+ },
164
+ },
165
+ {
166
+ name: "browser_type",
167
+ description: "Type text into an element (appends, doesn't clear)",
168
+ inputSchema: {
169
+ type: "object",
170
+ properties: {
171
+ selector: {
172
+ type: "string",
173
+ description: "CSS selector for element",
174
+ },
175
+ text: {
176
+ type: "string",
177
+ description: "Text to type",
178
+ },
179
+ pageName: {
180
+ type: "string",
181
+ description: "Page name (default: 'main')",
182
+ default: "main",
183
+ },
184
+ },
185
+ required: ["selector", "text"],
186
+ },
187
+ },
188
+ {
189
+ name: "browser_press",
190
+ description: "Press a keyboard key (e.g., 'Enter', 'Tab', 'Escape')",
191
+ inputSchema: {
192
+ type: "object",
193
+ properties: {
194
+ key: {
195
+ type: "string",
196
+ description: "Key to press (e.g., 'Enter', 'Tab', 'Escape', 'ArrowDown')",
197
+ },
198
+ pageName: {
199
+ type: "string",
200
+ description: "Page name (default: 'main')",
201
+ default: "main",
202
+ },
203
+ },
204
+ required: ["key"],
205
+ },
206
+ },
207
+ // Waiting
208
+ {
209
+ name: "browser_wait_for_selector",
210
+ description: "Wait for an element to appear on the page",
211
+ inputSchema: {
212
+ type: "object",
213
+ properties: {
214
+ selector: {
215
+ type: "string",
216
+ description: "CSS selector to wait for",
217
+ },
218
+ timeout: {
219
+ type: "number",
220
+ description: "Timeout in ms (default: 30000)",
221
+ default: 30000,
222
+ },
223
+ pageName: {
224
+ type: "string",
225
+ description: "Page name (default: 'main')",
226
+ default: "main",
227
+ },
228
+ },
229
+ required: ["selector"],
230
+ },
231
+ },
232
+ // Inspection
233
+ {
234
+ name: "browser_snapshot",
235
+ description: "Get AI-friendly page snapshot (DOM structure, text content, interactive elements)",
236
+ inputSchema: {
237
+ type: "object",
238
+ properties: {
239
+ pageName: {
240
+ type: "string",
241
+ description: "Page name (default: 'main')",
242
+ default: "main",
243
+ },
244
+ depth: {
245
+ type: "number",
246
+ description: "DOM traversal depth (default: 10)",
247
+ default: 10,
248
+ },
249
+ },
250
+ },
251
+ },
252
+ {
253
+ name: "browser_screenshot",
254
+ description: "Take a screenshot of the page",
255
+ inputSchema: {
256
+ type: "object",
257
+ properties: {
258
+ filename: {
259
+ type: "string",
260
+ description: "Filename for screenshot (saved to ~/.dev-browser/tmp/)",
261
+ },
262
+ pageName: {
263
+ type: "string",
264
+ description: "Page name (default: 'main')",
265
+ default: "main",
266
+ },
267
+ },
268
+ required: ["filename"],
269
+ },
270
+ },
271
+ // Advanced
272
+ {
273
+ name: "browser_evaluate",
274
+ description: "Evaluate JavaScript in the page context",
275
+ inputSchema: {
276
+ type: "object",
277
+ properties: {
278
+ code: {
279
+ type: "string",
280
+ description: "JavaScript code to execute",
281
+ },
282
+ pageName: {
283
+ type: "string",
284
+ description: "Page name (default: 'main')",
285
+ default: "main",
286
+ },
287
+ },
288
+ required: ["code"],
289
+ },
290
+ },
291
+ {
292
+ name: "browser_execute_script",
293
+ description: "Execute a raw dev-browser script (full Playwright API access)",
294
+ inputSchema: {
295
+ type: "object",
296
+ properties: {
297
+ script: {
298
+ type: "string",
299
+ description: "JavaScript code using browser, page, and Playwright API",
300
+ },
301
+ headless: {
302
+ type: "boolean",
303
+ description: "Run in headless mode (default: true)",
304
+ default: true,
305
+ },
306
+ connect: {
307
+ type: "boolean",
308
+ description: "Connect to existing Chrome (requires remote debugging enabled)",
309
+ default: false,
310
+ },
311
+ },
312
+ required: ["script"],
313
+ },
314
+ },
315
+ ];
316
+ // ============================================================================
317
+ // Tool Handlers
318
+ // ============================================================================
319
+ async function handleToolCall(name, args) {
320
+ try {
321
+ // Check availability first (except for status/help tools)
322
+ if (name !== "browser_status" && name !== "browser_help") {
323
+ if (!browserStatus.available) {
324
+ // Re-check in case it was installed
325
+ browserStatus.available = await isDevBrowserAvailable();
326
+ browserStatus.lastChecked = new Date();
327
+ if (!browserStatus.available) {
328
+ return {
329
+ content: [{
330
+ type: "text",
331
+ text: JSON.stringify({
332
+ success: false,
333
+ error: "dev-browser is not installed",
334
+ hint: "Install with: npm install -g dev-browser && dev-browser install",
335
+ tool: name,
336
+ }, null, 2),
337
+ }],
338
+ };
339
+ }
340
+ }
341
+ }
342
+ switch (name) {
343
+ case "browser_status": {
344
+ browserStatus.available = await isDevBrowserAvailable();
345
+ browserStatus.lastChecked = new Date();
346
+ return {
347
+ content: [{
348
+ type: "text",
349
+ text: JSON.stringify({
350
+ available: browserStatus.available,
351
+ lastChecked: browserStatus.lastChecked.toISOString(),
352
+ message: browserStatus.available
353
+ ? "dev-browser is available"
354
+ : "dev-browser is NOT installed. Install with: npm install -g dev-browser",
355
+ }, null, 2),
356
+ }],
357
+ };
358
+ }
359
+ case "browser_help": {
360
+ const helpText = await getDevBrowserHelp();
361
+ return {
362
+ content: [{
363
+ type: "text",
364
+ text: helpText || "Could not retrieve help text",
365
+ }],
366
+ };
367
+ }
368
+ case "browser_navigate": {
369
+ const url = args.url;
370
+ const pageName = args.pageName || "main";
371
+ const result = await navigate(url, pageName);
372
+ return {
373
+ content: [{
374
+ type: "text",
375
+ text: JSON.stringify(result, null, 2),
376
+ }],
377
+ };
378
+ }
379
+ case "browser_get_url": {
380
+ const pageName = args.pageName || "main";
381
+ const result = await getUrl(pageName);
382
+ return {
383
+ content: [{
384
+ type: "text",
385
+ text: JSON.stringify(result, null, 2),
386
+ }],
387
+ };
388
+ }
389
+ case "browser_get_title": {
390
+ const pageName = args.pageName || "main";
391
+ const result = await getTitle(pageName);
392
+ return {
393
+ content: [{
394
+ type: "text",
395
+ text: JSON.stringify(result, null, 2),
396
+ }],
397
+ };
398
+ }
399
+ case "browser_list_pages": {
400
+ const result = await listPages();
401
+ return {
402
+ content: [{
403
+ type: "text",
404
+ text: JSON.stringify(result, null, 2),
405
+ }],
406
+ };
407
+ }
408
+ case "browser_close_page": {
409
+ const pageName = args.pageName;
410
+ const result = await closePage(pageName);
411
+ return {
412
+ content: [{
413
+ type: "text",
414
+ text: JSON.stringify(result, null, 2),
415
+ }],
416
+ };
417
+ }
418
+ case "browser_click": {
419
+ const selector = args.selector;
420
+ const pageName = args.pageName || "main";
421
+ const result = await click(selector, pageName);
422
+ return {
423
+ content: [{
424
+ type: "text",
425
+ text: JSON.stringify(result, null, 2),
426
+ }],
427
+ };
428
+ }
429
+ case "browser_fill": {
430
+ const selector = args.selector;
431
+ const value = args.value;
432
+ const pageName = args.pageName || "main";
433
+ const result = await fill(selector, value, pageName);
434
+ return {
435
+ content: [{
436
+ type: "text",
437
+ text: JSON.stringify(result, null, 2),
438
+ }],
439
+ };
440
+ }
441
+ case "browser_type": {
442
+ const selector = args.selector;
443
+ const text = args.text;
444
+ const pageName = args.pageName || "main";
445
+ const result = await type(selector, text, pageName);
446
+ return {
447
+ content: [{
448
+ type: "text",
449
+ text: JSON.stringify(result, null, 2),
450
+ }],
451
+ };
452
+ }
453
+ case "browser_press": {
454
+ const key = args.key;
455
+ const pageName = args.pageName || "main";
456
+ const result = await press(key, pageName);
457
+ return {
458
+ content: [{
459
+ type: "text",
460
+ text: JSON.stringify(result, null, 2),
461
+ }],
462
+ };
463
+ }
464
+ case "browser_wait_for_selector": {
465
+ const selector = args.selector;
466
+ const timeout = args.timeout || 30000;
467
+ const pageName = args.pageName || "main";
468
+ const result = await waitForSelector(selector, { pageName, timeout });
469
+ return {
470
+ content: [{
471
+ type: "text",
472
+ text: JSON.stringify(result, null, 2),
473
+ }],
474
+ };
475
+ }
476
+ case "browser_snapshot": {
477
+ const pageName = args.pageName || "main";
478
+ const depth = args.depth || 10;
479
+ const result = await snapshot({ pageName, depth });
480
+ return {
481
+ content: [{
482
+ type: "text",
483
+ text: JSON.stringify(result, null, 2),
484
+ }],
485
+ };
486
+ }
487
+ case "browser_screenshot": {
488
+ const filename = args.filename;
489
+ const pageName = args.pageName || "main";
490
+ const result = await screenshot(filename, pageName);
491
+ return {
492
+ content: [{
493
+ type: "text",
494
+ text: JSON.stringify(result, null, 2),
495
+ }],
496
+ };
497
+ }
498
+ case "browser_evaluate": {
499
+ const code = args.code;
500
+ const pageName = args.pageName || "main";
501
+ const result = await evaluate(code, pageName);
502
+ return {
503
+ content: [{
504
+ type: "text",
505
+ text: JSON.stringify(result, null, 2),
506
+ }],
507
+ };
508
+ }
509
+ case "browser_execute_script": {
510
+ const script = args.script;
511
+ const headless = args.headless !== false;
512
+ const connect = args.connect === true;
513
+ const result = await executeScript(script, { headless, connect });
514
+ return {
515
+ content: [{
516
+ type: "text",
517
+ text: JSON.stringify(result, null, 2),
518
+ }],
519
+ };
520
+ }
521
+ default:
522
+ return {
523
+ content: [{
524
+ type: "text",
525
+ text: JSON.stringify({ error: `Unknown tool: ${name}` }),
526
+ }],
527
+ };
528
+ }
529
+ }
530
+ catch (error) {
531
+ return {
532
+ content: [{
533
+ type: "text",
534
+ text: JSON.stringify({
535
+ success: false,
536
+ error: error instanceof Error ? error.message : String(error),
537
+ }, null, 2),
538
+ }],
539
+ };
540
+ }
541
+ }
542
+ // ============================================================================
543
+ // Server Setup
544
+ // ============================================================================
545
+ const server = new Server({
546
+ name: "@ebowwa/mcp-browser",
547
+ version: "0.1.0",
548
+ }, {
549
+ capabilities: {
550
+ tools: {},
551
+ resources: {},
552
+ },
553
+ });
554
+ // List tools
555
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
556
+ tools: TOOLS,
557
+ }));
558
+ // Handle tool calls
559
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
560
+ const { name, arguments: args } = request.params;
561
+ return handleToolCall(name, args || {});
562
+ });
563
+ // List resources
564
+ server.setRequestHandler(ListResourcesRequestSchema, async () => ({
565
+ resources: [
566
+ {
567
+ uri: "browser://status",
568
+ name: "Browser Status",
569
+ description: "Current status of dev-browser integration",
570
+ mimeType: "application/json",
571
+ },
572
+ {
573
+ uri: "browser://help",
574
+ name: "Browser Help",
575
+ description: "dev-browser CLI help and examples",
576
+ mimeType: "text/plain",
577
+ },
578
+ ],
579
+ }));
580
+ // Read resources
581
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
582
+ const { uri } = request.params;
583
+ switch (uri) {
584
+ case "browser://status": {
585
+ const available = await isDevBrowserAvailable();
586
+ return {
587
+ contents: [{
588
+ uri,
589
+ mimeType: "application/json",
590
+ text: JSON.stringify({
591
+ available,
592
+ package: "@ebowwa/mcp-browser",
593
+ version: "0.1.0",
594
+ dependency: "dev-browser (optional)",
595
+ installHint: available
596
+ ? null
597
+ : "npm install -g dev-browser && dev-browser install",
598
+ }, null, 2),
599
+ }],
600
+ };
601
+ }
602
+ case "browser://help": {
603
+ const help = await getDevBrowserHelp();
604
+ return {
605
+ contents: [{
606
+ uri,
607
+ mimeType: "text/plain",
608
+ text: help || "Help not available - dev-browser may not be installed",
609
+ }],
610
+ };
611
+ }
612
+ default:
613
+ throw new Error(`Unknown resource: ${uri}`);
614
+ }
615
+ });
616
+ // Start server
617
+ async function main() {
618
+ // Check availability at startup (non-blocking)
619
+ isDevBrowserAvailable().then((available) => {
620
+ browserStatus.available = available;
621
+ browserStatus.lastChecked = new Date();
622
+ if (!available) {
623
+ console.error("[mcp-browser] dev-browser not found. Install with: npm install -g dev-browser");
624
+ }
625
+ });
626
+ const transport = new StdioServerTransport();
627
+ await server.connect(transport);
628
+ console.error("@ebowwa/mcp-browser started (optional extension)");
629
+ }
630
+ main().catch((error) => {
631
+ console.error("Server error:", error);
632
+ process.exit(1);
633
+ });
634
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@ebowwa/mcp-browser",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for browser automation via dev-browser (optional extension)",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "mcp-browser": "dist/index.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "README.md"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsc",
23
+ "dev": "bun run --watch src/index.ts",
24
+ "start": "node dist/index.js",
25
+ "test": "bun test",
26
+ "typecheck": "tsc --noEmit"
27
+ },
28
+ "keywords": [
29
+ "mcp",
30
+ "browser",
31
+ "automation",
32
+ "playwright",
33
+ "dev-browser",
34
+ "coder"
35
+ ],
36
+ "author": "ebowwa",
37
+ "license": "MIT",
38
+ "dependencies": {
39
+ "@modelcontextprotocol/sdk": "^1.10.2"
40
+ },
41
+ "peerDependencies": {
42
+ "dev-browser": ">=1.0.0"
43
+ },
44
+ "peerDependenciesMeta": {
45
+ "dev-browser": {
46
+ "optional": true
47
+ }
48
+ },
49
+ "devDependencies": {
50
+ "@types/bun": "^1.2.5",
51
+ "@types/node": "^22.13.10",
52
+ "typescript": "^5.8.2"
53
+ }
54
+ }