This server has 8 tools with basic schemas and descriptions, but significant quality gaps across naming, parameter documentation, output schemas, and error handling. All tools are explicitly registered in src/core/ToolManager.ts with name, description, and inputSchema. However, descriptions are minimal (10-50 chars), most parameter descriptions are present but generic, and output schemas are completely undocumented. No error handling guidance, no parameter constraints (enums), and no recovery paths. The naming follows verb_noun convention (good), but lacks domain-specific clarity. Tool descriptions do not explain WHEN to use them or what the downstream agent should do with results. Output is always wrapped in {'content': [{'type': 'text', 'text': '...'}], 'isError': false}, but the schema of that structure is not declared anywhere. The server would benefit from richer descriptions, documented output schemas, enum constraints on free-form string parameters (especially CDP command names), and actionable error messages.
No output schemas documented. All tools return a fixed TextContent wrapper, but the schema of this response structure is not declared. LLMs cannot know what fields to expect or plan downstream tool calls. [Source: DIMENSION 1.D, SCHEMAS & OUTPUT, rule 'Document the output schema']
Tool descriptions are too brief (10 - 30 chars) and lack context. 'Navigate to a URL' does not explain prerequisites (e.g., must have a browser instance), expected return format, or when to call this vs related tools.
Add output schema definitions to every tool. Example for puppeteer_click: {"type": "object", "properties": {"success": {"type": "boolean"}, "message": {"type": "string"}, "timestamp": {"type": "string", "format": "date-time"}}, "required": ["success", "message"]}. This lets LLMs know what to expect.
Expand tool descriptions to 50 - 150 chars and include context. Example: 'puppeteer_click: Click an element matching a CSS selector. Returns success status. Use when you need to trigger UI interactions (button presses, link clicks, checkbox toggles). Fails if selector does not match; returns an error with selector hint.'
Replace free-form string parameters with enums where possible. For 'puppeteer_devtools_evaluate', enumerate valid CDP command domains (Runtime, DOM, Network, etc.) or require 'command' to match pattern '^[A-Z][a-zA-Z]+\.[a-zA-Z]+$'. Add description: 'Full CDP command in Domain.method format (e.g. Runtime.evaluate, DOM.getDocument).'
Add explicit error handling. When a selector is not found, return: {"success": false, "error": "Selector not found: '.my-button'. Tips: Check CSS syntax, verify element is in DOM, try a simpler selector like 'button' to debug."}. This guides LLM recovery.
Document parameter constraints in descriptions. For 'selector', add: 'CSS selector string (e.g. ".btn-primary", "#main-header", "input[type=email]"). XPath and other formats are not supported.' For 'url' in navigate, add: 'Full absolute URL starting with http:// or https://. Relative URLs are not supported.'
puppeteer_devtools_evaluate accepts 'command' as a free-form string with no enum constraint. LLMs will hallucinate invalid CDP command names. Should enumerate valid commands or at least provide a description with format constraints. [Source: DIMENSION 1.C, PARAMETERS, rule 'When a parameter accepts one of a known set of values, declare it as an enum']
puppeteer_devtools_subscribe 'events' parameter lacks validation. Accepts any array of strings, LLMs may pass invalid event names. Should enumerate valid events or provide format constraints. [Source: DIMENSION 1.C, PARAMETERS, rule 'Describe the expected format, range, and allowed values']
No error handling or recovery guidance. All handlers return {'isError': false} on success, but there is no indication of what happens on failure (selector not found, navigation timeout, CDP command invalid). LLMs receive no actionable error messages or retry hints. [Source: DIMENSION 1.E, ERROR HANDLING, rule 'Error responses must tell the LLM what to do next']
No parameter constraints. 'selector' is a free-form string on all DOM tools, LLMs may pass invalid CSS selectors, XPath, or junk text. Description should specify 'CSS selector only' with format constraints or examples. [Source: DIMENSION 1.C, PARAMETERS, rule 'Specify minimum and maximum for numeric parameters; describe format']
Tool naming could be more specific. 'puppeteer_devtools_evaluate' and 'puppeteer_devtools_subscribe' are generic and ambiguous. The first executes arbitrary CDP commands (high power, high risk). The second subscribes to events and buffers them (unclear what happens to buffered events). Names should clarify intent: 'puppeteer_execute_cdp_command' and 'puppeteer_listen_to_cdp_events' would be clearer. [Source: DIMENSION 1.A, NAMING, rule 'The tool name alone should convey what happens when called']
puppeteer_navigate URL parameter has no validation hints. Should specify: 'Full HTTP/HTTPS URL (e.g. https://example.com)' and indicate if relative URLs are supported. [Source: DIMENSION 1.C, PARAMETERS, rule 'Describe the expected format, range, and allowed values']
No idempotency guarantees. If an LLM retries puppeteer_click or puppeteer_fill on transient failure, the tool may double-execute. Descriptions should state idempotency: 'Idempotent: calling twice with the same selector has no additional effect.' [Source: DIMENSION 1.G, COMPOSITION, rule 'Make tools produce the same result on repeated calls with the same input']
Clarify tool naming and purpose. Rename 'puppeteer_devtools_evaluate' to 'puppeteer_execute_cdp_command' and 'puppeteer_devtools_subscribe' to 'puppeteer_subscribe_to_cdp_events'. Add description: 'Subscribe to Chrome DevTools Protocol events. Buffered events are returned as they occur. Use to monitor page activity (network, console, DOM changes).'
Add idempotency documentation. For write tools (click, fill, select), add to description: 'Idempotent: calling this tool twice with the same inputs has the same effect as calling once. Safe to retry on transient failures.'
Document the browser lifecycle. Add a note or resource that explains: 'All tools assume a browser instance is initialized. Ensure the browser is running before calling page interaction tools. Call puppeteer_navigate first to load a page, then interact with it.'
Validate inputs before execution. Catch CSS selector syntax errors, invalid URLs, and invalid CDP commands. Return a clear error message: 'Invalid CSS selector: "#my button". Spaces between selectors indicate descendant combinator. Did you mean: "#my_button" or "#my .button"?'
Add per-tool rate limiting and timeout guidance. For puppeteer_navigate, add: 'Timeout: 30 seconds. If a page takes longer to load, the call fails with a timeout error. Retry with a simpler URL or check network connectivity.'
Document result chaining. If puppeteer_measure returns element bounds, clarify that these can be used in follow-up calls. Example: 'Returns {x, y, width, height, ...}. Use these coordinates for targeted clicks or hover operations.'
Add examples of successful invocations in descriptions (but NOT as parameter defaults). 'Example call: {"selector": ".primary-button"} successfully clicks the button if it exists on the current page.'
Create a capability discovery tool or resource. Add a tool like 'puppeteer_list_cdp_commands' or a resource describing available CDP domains and commands. This helps LLMs avoid hallucinating invalid command names.