diff --git a/browser-tools-mcp/mcp-server.ts b/browser-tools-mcp/mcp-server.ts index a7a1272..b841a7e 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", + { + respKeywords: z.array(z.string()).describe("The keywords contained in the log message").optional(), + }, + async ({ respKeywords }) => { + 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 (respKeywords) { + result = result.filter(log => respKeywords.some(keyword => log.message.includes(keyword))); + } + + return { + content: [ + { + type: "text", + text: JSON.stringify(result, null, 2), + }, + ], + }; + }); + }, +); server.tool( "getConsoleErrors", "Check our browsers console errors", - async () => { + { + respKeywords: z.array(z.string()).describe("The keywords contained in the log message").optional(), + }, + async ({ respKeywords }) => { return await withServerConnection(async () => { const response = await fetch( `http://${discoveredHost}:${discoveredPort}/console-errors` ); const json = await response.json(); + + let result: Array = json; + if (respKeywords) { + result = result.filter(log => respKeywords.some(keyword => log.message.includes(keyword))); + } + 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", + { + 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 ({ 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 (urlKeywords) { + result = result.filter(log => log.url.includes(urlKeywords)); + } + if (respKeywords) { + result = result.filter(log => respKeywords.some(keyword => log.responseBody.includes(keyword))); + } -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", + { + 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 ({ respKeywords, urlKeywords }) => { + 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 (urlKeywords) { + result = result.filter(log => log.url.includes(urlKeywords)); + } + if (respKeywords) { + result = result.filter(log => respKeywords.some(keyword => log.responseBody.includes(keyword))); + } + + 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",