From e37dc225f84294832b5fcef43dc3b3bbf260e486 Mon Sep 17 00:00:00 2001 From: yj1438 Date: Thu, 6 Nov 2025 17:58:36 +0800 Subject: [PATCH 1/2] feat: network\console add keywords --- browser-tools-mcp/mcp-server.ts | 182 ++++++++++++++++++++-------- browser-tools-mcp/package-lock.json | 4 +- 2 files changed, 133 insertions(+), 53 deletions(-) diff --git a/browser-tools-mcp/mcp-server.ts b/browser-tools-mcp/mcp-server.ts index a7a1272..f2cc331 100644 --- a/browser-tools-mcp/mcp-server.ts +++ b/browser-tools-mcp/mcp-server.ts @@ -4,6 +4,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import path from "path"; import fs from "fs"; +import { z } from "zod"; // Create the MCP server const server = new McpServer({ @@ -175,37 +176,70 @@ async function withServerConnection( } // We'll define our tools that retrieve data from the browser connector -server.tool("getConsoleLogs", "Check our browser logs", async () => { - return await withServerConnection(async () => { - const response = await fetch( - `http://${discoveredHost}:${discoveredPort}/console-logs` - ); - const json = await response.json(); - return { - content: [ - { - type: "text", - text: JSON.stringify(json, null, 2), - }, - ], - }; - }); -}); +server.tool( + "getConsoleLogs", + "Check our browser logs", + { + keywords: z.string().describe("The keywords contained in the log").optional(), + }, + async ({ keywords }) => { + return await withServerConnection(async () => { + const response = await fetch( + `http://${discoveredHost}:${discoveredPort}/console-logs` + ); + const json = await response.json(); + /** + * json eg: + [ + { + "type": "console-log", + "level": "log", + "message": "content script loaded", + "timestamp": 1762399170098 + }, + ] + */ + + let result: Array = json; + if (keywords) { + result = result.filter(log => log.message.includes(keywords)); + } + + return { + content: [ + { + type: "text", + text: JSON.stringify(result, null, 2), + }, + ], + }; + }); + }, +); server.tool( "getConsoleErrors", "Check our browsers console errors", - async () => { + { + keywords: z.string().describe("The keywords contained in the log").optional(), + }, + async (keywords) => { return await withServerConnection(async () => { const response = await fetch( `http://${discoveredHost}:${discoveredPort}/console-errors` ); const json = await response.json(); + + let result: Array = json; + if (keywords) { + result = result.filter(log => log.message.includes(keywords)); + } + return { content: [ { type: "text", - text: JSON.stringify(json, null, 2), + text: JSON.stringify(result, null, 2), }, ], }; @@ -213,40 +247,86 @@ server.tool( } ); -server.tool("getNetworkErrors", "Check our network ERROR logs", async () => { - return await withServerConnection(async () => { - const response = await fetch( - `http://${discoveredHost}:${discoveredPort}/network-errors` - ); - const json = await response.json(); - return { - content: [ - { - type: "text", - text: JSON.stringify(json, null, 2), - }, - ], - isError: true, - }; - }); -}); +server.tool( + "getNetworkErrors", + "Check our network ERROR logs", + { + domain: z.string().describe("The domain to filter the network logs by").optional(), + keywords: z.string().describe("The keywords contained in the log").optional(), + }, + async ({ keywords, domain }) => { + return await withServerConnection(async () => { + const response = await fetch( + `http://${discoveredHost}:${discoveredPort}/network-errors` + ); + const json = await response.json(); + let result: Array = json; + if (domain) { + result = result.filter(log => log.url.includes(domain)); + } + if (keywords) { + result = result.filter(log => log.responseBody.includes(keywords)); + } -server.tool("getNetworkLogs", "Check ALL our network logs", async () => { - return await withServerConnection(async () => { - const response = await fetch( - `http://${discoveredHost}:${discoveredPort}/network-success` - ); - const json = await response.json(); - return { - content: [ - { - type: "text", - text: JSON.stringify(json, null, 2), - }, - ], - }; - }); -}); + return { + content: [ + { + type: "text", + text: JSON.stringify(result, null, 2), + }, + ], + isError: true, + }; + }); + }, +); + +server.tool( + "getNetworkLogs", + "Check ALL our network logs", + { + domain: z.string().describe("The domain to filter the network logs by").optional(), + keywords: z.string().describe("The keywords contained in the log").optional(), + }, + async ({ keywords, domain }) => { + return await withServerConnection(async () => { + const response = await fetch( + `http://${discoveredHost}:${discoveredPort}/network-success` + ); + const json = await response.json(); + /** + * json eg: + * [ + { + "type": "network-request", + "url": "https://xxx", + "method": "GET", + "status": 200, + "requestBody": "", + "responseBody": "{}", + "timestamp": 1762344730925 + } + * ] + */ + let result: Array = json; + if (domain) { + result = result.filter(log => log.url.includes(domain)); + } + if (keywords) { + result = result.filter(log => log.responseBody.includes(keywords)); + } + + return { + content: [ + { + type: "text", + text: JSON.stringify(result, null, 2), + }, + ], + }; + }); + }, +); server.tool( "takeScreenshot", diff --git a/browser-tools-mcp/package-lock.json b/browser-tools-mcp/package-lock.json index 0784e8f..be0a7a1 100644 --- a/browser-tools-mcp/package-lock.json +++ b/browser-tools-mcp/package-lock.json @@ -1,12 +1,12 @@ { "name": "@agentdeskai/browser-tools-mcp", - "version": "1.1.0", + "version": "1.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@agentdeskai/browser-tools-mcp", - "version": "1.1.0", + "version": "1.2.0", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.4.1", From 6c89b06b99007311acb7da3801eacf5921340be6 Mon Sep 17 00:00:00 2001 From: yj1438 Date: Mon, 10 Nov 2025 13:49:34 +0800 Subject: [PATCH 2/2] change keywords param type to array --- browser-tools-mcp/mcp-server.ts | 44 ++++++++++++++++----------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/browser-tools-mcp/mcp-server.ts b/browser-tools-mcp/mcp-server.ts index f2cc331..b841a7e 100644 --- a/browser-tools-mcp/mcp-server.ts +++ b/browser-tools-mcp/mcp-server.ts @@ -180,9 +180,9 @@ server.tool( "getConsoleLogs", "Check our browser logs", { - keywords: z.string().describe("The keywords contained in the log").optional(), + respKeywords: z.array(z.string()).describe("The keywords contained in the log message").optional(), }, - async ({ keywords }) => { + async ({ respKeywords }) => { return await withServerConnection(async () => { const response = await fetch( `http://${discoveredHost}:${discoveredPort}/console-logs` @@ -201,8 +201,8 @@ server.tool( */ let result: Array = json; - if (keywords) { - result = result.filter(log => log.message.includes(keywords)); + if (respKeywords) { + result = result.filter(log => respKeywords.some(keyword => log.message.includes(keyword))); } return { @@ -221,9 +221,9 @@ server.tool( "getConsoleErrors", "Check our browsers console errors", { - keywords: z.string().describe("The keywords contained in the log").optional(), + respKeywords: z.array(z.string()).describe("The keywords contained in the log message").optional(), }, - async (keywords) => { + async ({ respKeywords }) => { return await withServerConnection(async () => { const response = await fetch( `http://${discoveredHost}:${discoveredPort}/console-errors` @@ -231,8 +231,8 @@ server.tool( const json = await response.json(); let result: Array = json; - if (keywords) { - result = result.filter(log => log.message.includes(keywords)); + if (respKeywords) { + result = result.filter(log => respKeywords.some(keyword => log.message.includes(keyword))); } return { @@ -251,21 +251,21 @@ server.tool( "getNetworkErrors", "Check our network ERROR logs", { - domain: z.string().describe("The domain to filter the network logs by").optional(), - keywords: z.string().describe("The keywords contained in the log").optional(), + urlKeywords: z.string().describe("The keywords contained in the request URL").optional(), + respKeywords: z.array(z.string()).describe("The keywords contained in the response body").optional(), }, - async ({ keywords, domain }) => { + async ({ respKeywords, urlKeywords }) => { return await withServerConnection(async () => { const response = await fetch( `http://${discoveredHost}:${discoveredPort}/network-errors` ); const json = await response.json(); let result: Array = json; - if (domain) { - result = result.filter(log => log.url.includes(domain)); + if (urlKeywords) { + result = result.filter(log => log.url.includes(urlKeywords)); } - if (keywords) { - result = result.filter(log => log.responseBody.includes(keywords)); + if (respKeywords) { + result = result.filter(log => respKeywords.some(keyword => log.responseBody.includes(keyword))); } return { @@ -285,10 +285,10 @@ server.tool( "getNetworkLogs", "Check ALL our network logs", { - domain: z.string().describe("The domain to filter the network logs by").optional(), - keywords: z.string().describe("The keywords contained in the log").optional(), + urlKeywords: z.string().describe("The keywords contained in the request URL").optional(), + respKeywords: z.array(z.string()).describe("The keywords contained in the response body").optional(), }, - async ({ keywords, domain }) => { + async ({ respKeywords, urlKeywords }) => { return await withServerConnection(async () => { const response = await fetch( `http://${discoveredHost}:${discoveredPort}/network-success` @@ -309,11 +309,11 @@ server.tool( * ] */ let result: Array = json; - if (domain) { - result = result.filter(log => log.url.includes(domain)); + if (urlKeywords) { + result = result.filter(log => log.url.includes(urlKeywords)); } - if (keywords) { - result = result.filter(log => log.responseBody.includes(keywords)); + if (respKeywords) { + result = result.filter(log => respKeywords.some(keyword => log.responseBody.includes(keyword))); } return {