mcpbrowser 0.3.56 → 0.3.58
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 +25 -0
- package/package.json +1 -1
- package/src/actions/click-element.js +4 -4
- package/src/actions/detect-forms.js +1 -1
- package/src/actions/execute-javascript.js +8 -3
- package/src/actions/fetch-page.js +3 -2
- package/src/actions/navigate-history.js +1 -1
- package/src/actions/scroll-page.js +2 -1
- package/src/actions/type-text.js +1 -1
- package/src/mcp-browser.js +21 -1
package/README.md
CHANGED
|
@@ -498,6 +498,31 @@ Logs go to `stderr` so they don't interfere with MCP protocol on `stdout`.
|
|
|
498
498
|
- Keep the browser tab open (default behavior)
|
|
499
499
|
- Use the same domain for related requests
|
|
500
500
|
|
|
501
|
+
**E401 error with `npx` / private npm registry?**
|
|
502
|
+
|
|
503
|
+
If your project has a `.npmrc` that points to a private registry (e.g., Azure Artifacts, GitHub Packages, Artifactory), `npx` will try to fetch `mcpbrowser` from that registry instead of npmjs.org and fail with `E401`.
|
|
504
|
+
|
|
505
|
+
**Fix:** Add `npm_config_registry` to the `env` block in your MCP config:
|
|
506
|
+
```json
|
|
507
|
+
{
|
|
508
|
+
"mcpServers": {
|
|
509
|
+
"mcpbrowser": {
|
|
510
|
+
"command": "npx",
|
|
511
|
+
"args": ["-y", "mcpbrowser@latest"],
|
|
512
|
+
"env": {
|
|
513
|
+
"npm_config_registry": "https://registry.npmjs.org"
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
**Alternative:** Install globally to skip `npx` entirely:
|
|
521
|
+
```bash
|
|
522
|
+
npm install -g mcpbrowser
|
|
523
|
+
```
|
|
524
|
+
Then use `"command": "mcpbrowser"` with no `args` in your MCP config.
|
|
525
|
+
|
|
501
526
|
## Links
|
|
502
527
|
|
|
503
528
|
- [GitHub](https://github.com/cherchyk/MCPBrowser)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcpbrowser",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.58",
|
|
4
4
|
"mcpName": "io.github.cherchyk/mcpbrowser",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "MCP browser server — loads and interacts with web pages using the user's Chromium-based browser with full JavaScript execution. Handles authentication, SSO, and anti-bot protection automatically via the user's existing browser session.",
|
|
@@ -114,16 +114,16 @@ export const CLICK_ELEMENT_TOOL = {
|
|
|
114
114
|
properties: {
|
|
115
115
|
status: { type: "string", enum: ["success", "timeout", "error"] },
|
|
116
116
|
durationMs: { type: "number" },
|
|
117
|
-
error: { type:
|
|
117
|
+
error: { type: "string" }
|
|
118
118
|
},
|
|
119
119
|
required: ["status", "durationMs"]
|
|
120
120
|
},
|
|
121
121
|
fallbackAttempt: {
|
|
122
|
-
type:
|
|
122
|
+
type: "object",
|
|
123
123
|
properties: {
|
|
124
124
|
status: { type: "string", enum: ["success", "timeout", "error"] },
|
|
125
125
|
durationMs: { type: "number" },
|
|
126
|
-
error: { type:
|
|
126
|
+
error: { type: "string" }
|
|
127
127
|
},
|
|
128
128
|
required: ["status", "durationMs"],
|
|
129
129
|
description: "Present when fallbackUsed is true"
|
|
@@ -140,7 +140,7 @@ export const CLICK_ELEMENT_TOOL = {
|
|
|
140
140
|
currentUrl: { type: "string", description: "URL after click" },
|
|
141
141
|
message: { type: "string", description: "Status message" },
|
|
142
142
|
html: {
|
|
143
|
-
type:
|
|
143
|
+
type: "string",
|
|
144
144
|
description: "Page HTML if returnHtml was true, null otherwise"
|
|
145
145
|
},
|
|
146
146
|
forms: { type: "array", items: { type: "object" }, description: "Detected forms with fields, selectors, and metadata (when returnHtml is true)" },
|
|
@@ -36,8 +36,13 @@ export class ExecuteJavascriptResponse extends MCPResponse {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
_getAdditionalFields() {
|
|
39
|
+
// outputSchema declares result as type: 'string' (serialized).
|
|
40
|
+
// Ensure non-string values (numbers, objects, arrays) are stringified.
|
|
41
|
+
const serializedResult = this.result == null ? null
|
|
42
|
+
: typeof this.result === 'string' ? this.result
|
|
43
|
+
: JSON.stringify(this.result);
|
|
39
44
|
return {
|
|
40
|
-
result:
|
|
45
|
+
result: serializedResult,
|
|
41
46
|
type: this.type,
|
|
42
47
|
executionTimeMs: this.executionTimeMs,
|
|
43
48
|
truncated: this.truncated,
|
|
@@ -74,14 +79,14 @@ export const EXECUTE_JAVASCRIPT_TOOL = {
|
|
|
74
79
|
outputSchema: {
|
|
75
80
|
type: 'object',
|
|
76
81
|
properties: {
|
|
77
|
-
result: { description: 'Serialized result of the script', nullable: true },
|
|
82
|
+
result: { type: 'string', description: 'Serialized result of the script', nullable: true },
|
|
78
83
|
type: { type: 'string', description: 'Type of the returned result' },
|
|
79
84
|
executionTimeMs: { type: 'number', description: 'Script execution duration' },
|
|
80
85
|
truncated: { type: 'boolean', description: 'True if result was capped to size limit' },
|
|
81
86
|
urlChanged: { type: 'boolean', description: 'True if page URL changed during execution' },
|
|
82
87
|
currentUrl: { type: 'string', description: 'URL after execution' },
|
|
83
88
|
nextSteps: { type: 'array', items: { type: 'string' } },
|
|
84
|
-
error: { type:
|
|
89
|
+
error: { type: 'object', description: 'Error object when script throws or times out' },
|
|
85
90
|
recommendedPlugins: {
|
|
86
91
|
type: 'array',
|
|
87
92
|
items: { type: 'object' },
|
|
@@ -81,8 +81,9 @@ export const FETCH_WEBPAGE_TOOL = {
|
|
|
81
81
|
url: { type: "string", description: "The URL to fetch" },
|
|
82
82
|
browser: {
|
|
83
83
|
type: "string",
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
enum: ["chrome", "edge", "brave"],
|
|
85
|
+
description: "Browser to use. Uses CDP to connect to the user's existing browser session.",
|
|
86
|
+
default: "chrome"
|
|
86
87
|
},
|
|
87
88
|
removeUnnecessaryHTML: { type: "boolean", description: "Remove Unnecessary HTML for size reduction by 90%.", default: true },
|
|
88
89
|
selector: { type: "string", description: "CSS selector to extract a specific DOM subtree instead of the full page. Use to scope extraction and reduce response size (e.g., 'main', '[role=\"main\"]', 'body > div:first-child'). If no elements match, falls back to full page with a note." },
|
|
@@ -94,7 +94,7 @@ export const NAVIGATE_HISTORY_TOOL = {
|
|
|
94
94
|
direction: { type: "string", enum: ["back", "forward"], description: "Navigation direction used" },
|
|
95
95
|
previousUrl: { type: "string", description: "URL before navigation" },
|
|
96
96
|
currentUrl: { type: "string", description: "URL after navigation" },
|
|
97
|
-
html: { type:
|
|
97
|
+
html: { type: "string", description: "Page HTML content after navigation (null if returnHtml=false)" },
|
|
98
98
|
nextSteps: {
|
|
99
99
|
type: "array",
|
|
100
100
|
items: { type: "string" },
|
|
@@ -105,7 +105,8 @@ export const SCROLL_PAGE_TOOL = {
|
|
|
105
105
|
direction: {
|
|
106
106
|
type: "string",
|
|
107
107
|
enum: ["up", "down", "left", "right"],
|
|
108
|
-
description: "Direction to scroll. Use with 'amount' parameter."
|
|
108
|
+
description: "Direction to scroll. Use with 'amount' parameter.",
|
|
109
|
+
default: "down"
|
|
109
110
|
},
|
|
110
111
|
amount: {
|
|
111
112
|
type: "number",
|
package/src/actions/type-text.js
CHANGED
|
@@ -100,7 +100,7 @@ export const TYPE_TEXT_TOOL = {
|
|
|
100
100
|
currentUrl: { type: "string", description: "URL after typing" },
|
|
101
101
|
message: { type: "string", description: "Success message" },
|
|
102
102
|
html: {
|
|
103
|
-
type:
|
|
103
|
+
type: "string",
|
|
104
104
|
description: "Page HTML if returnHtml was true, null otherwise"
|
|
105
105
|
},
|
|
106
106
|
nextSteps: {
|
package/src/mcp-browser.js
CHANGED
|
@@ -71,6 +71,17 @@ async function main() {
|
|
|
71
71
|
}
|
|
72
72
|
);
|
|
73
73
|
|
|
74
|
+
// Capture the negotiated MCP protocol version so the ListTools handler can
|
|
75
|
+
// strip fields that older clients cannot parse (outputSchema, annotations,
|
|
76
|
+
// title were added in MCP protocol 2025-03-26).
|
|
77
|
+
let negotiatedProtocolVersion = null;
|
|
78
|
+
const _origOnInitialize = server._oninitialize.bind(server);
|
|
79
|
+
server._oninitialize = async function(request) {
|
|
80
|
+
const result = await _origOnInitialize(request);
|
|
81
|
+
negotiatedProtocolVersion = result.protocolVersion;
|
|
82
|
+
return result;
|
|
83
|
+
};
|
|
84
|
+
|
|
74
85
|
// Wire server to logger so logs flow to agent via notifications/message.
|
|
75
86
|
attachLoggerServer(server);
|
|
76
87
|
|
|
@@ -106,7 +117,16 @@ async function main() {
|
|
|
106
117
|
...pluginTools
|
|
107
118
|
];
|
|
108
119
|
|
|
109
|
-
server.setRequestHandler(ListToolsRequestSchema, async () =>
|
|
120
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
121
|
+
// outputSchema, annotations, and title require MCP protocol 2025-03-26+.
|
|
122
|
+
// Strip them for clients that negotiated an older version (e.g. Antigravity/Gemini).
|
|
123
|
+
if (!negotiatedProtocolVersion || negotiatedProtocolVersion < '2025-03-26') {
|
|
124
|
+
return {
|
|
125
|
+
tools: tools.map(({ outputSchema, annotations, title, ...core }) => core)
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
return { tools };
|
|
129
|
+
});
|
|
110
130
|
|
|
111
131
|
// --- Prompts handlers ---
|
|
112
132
|
server.setRequestHandler(ListPromptsRequestSchema, async () => ({ prompts: PROMPTS }));
|