Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
MiraiLens has 27 tools with significant structural and semantic issues. While all tools have basic schemas visible in src/types/mcp/tool.ts and descriptions, the quality is poor. Critical problems: (1) Tools 2-4, 12-13 use dummy 'random_string' parameters, a severe anti-pattern that forces LLMs to invent nonsense values instead of making proper no-parameter calls. (2) Parameter descriptions are minimal (often just noun phrases like 'CSS selector or ARIA query string') and do not explain WHEN or WHY to use each tool, they fail the 'prompt engineering' standard. (3) No output schemas are documented anywhere, LLMs cannot predict what fields each tool returns. (4) Tool naming lacks clarity: 'pause_ai' vs 'pause_agent' vs 'stop_agent' are confusing near-duplicates; 'mcp_mirailens_*' prefix is redundant. (5) Control tools (pause/resume/emergency_stop) have no error handling, recovery guidance, or documentation of side effects. (6) No parameter constraints (enums, ranges, patterns) for string/numeric inputs like 'key' in press_key or 'time' in wait. (8) No indication of which tools are idempotent, which require user confirmation, or what permissions each requires.
Dummy 'random_string' parameter anti-pattern on no-parameter tools (go_back, go_forward, snapshot, get_console_logs, screenshot). This forces LLMs to invent meaningless values and indicates poor API design. These should be true zero-parameter tools.
No output schemas documented for any of the 27 tools. LLMs cannot predict what fields are returned, forcing them to reason blindly about downstream tool calls. This violates the schema documentation requirement.
Replace all dummy 'random_string' parameters with true zero-parameter tools. Update schema and request handling to accept no arguments. Example: GoBackTool should have arguments: {}, not arguments: { random_string: ... }.
Document output schemas for every tool. Add a 'returns' section to tool definitions in src/types/mcp/tool.ts listing field names, types, and descriptions. Example: 'mcp_mirailens_screenshot returns { base64_data: string, width: number, height: number, timestamp: ISO8601 }'.
Expand parameter descriptions to 50-150 chars with actionable context. Instead of 'CSS selector or ARIA query string', write 'CSS selector (e.g. #button-id, .class-name) or ARIA query (e.g. role:button[name:Submit]). Use CSS if targeting by structure; ARIA if targeting by accessibility label.' This guides LLM selection and reduces invalid inputs.
Add input validation constraints to Zod schemas. For press_key, define a union of valid key names: z.enum(['Enter', 'Shift', 'Tab', 'Escape', ...]). For wait time, add .max(300) to cap at 5 minutes. For navigate, validate protocol is http/https.
Consolidate control flow tools. Choose ONE naming scheme: either { pause_execution, resume_execution, stop_execution } OR { pause, resume, stop }. Document the distinction if multiple variants exist. Remove near-duplicates like pause_ai vs pause_agent.
Add error handling guidance to tool descriptions. Example for take_control: 'Passes control to the user. If already under user control, returns error 409 CONFLICT with message "User already has control." Retry after user releases control via return_control.'
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
Control flow tools (pause_ai, pause_agent, resume_ai, resume_agent, stop_agent, emergency_stop, take_control, return_control) have no input schemas visible in source code and are referenced only by file location. These should be explicitly registered with full schemas.
Confusing tool naming: 'pause_ai' vs 'pause_agent', 'resume_ai' vs 'resume_agent', 'stop_agent' are near-duplicates that violate the pattern:tool naming requirement. LLMs will waste reasoning cycles disambiguating them. Consolidate to a single naming scheme (e.g. pause_execution, resume_execution, stop_execution) or clearly document when to use each.
Parameter descriptions are minimal noun phrases ('CSS selector or ARIA query string', 'Keyboard key name to press') and do not explain WHEN to use the tool, WHAT it does beyond the name, or WHAT it returns. Descriptions fail the 'prompt engineering' bar of 10-1024 chars with context for selection. Baselines show A+ tools average 194 chars per description.
No input validation or constraints visible. 'press_key' accepts any string with no enum of valid key names (shift, enter, tab, etc.). 'wait' accepts number > 0 but no maximum (could pass 999999 seconds). 'navigate' has no protocol validation beyond .url(). No constraint descriptions guide LLMs toward valid inputs.
No error handling or recovery guidance documented. Tools have no indication of what errors they can throw, whether errors are retryable, or what the LLM should do next. Control tools (emergency_stop, take_control) are especially dangerous without error classification and confirmation patterns.
No indication of which tools are idempotent, which have irreversible side effects, and which require confirmation. Tools like 'emergency_stop', 'delete'-equivalents should declare destructiveHint; read-only tools should declare readOnlyHint. This violates tool-annotations and confirmation-request patterns.
No permissions or scope declarations. Tools like 'set_policy', 'take_control', 'emergency_stop' are sensitive but have no indication of what authority is required to execute them. No audit trail or permission-gate pattern visible.
Redundant tool name prefix 'mcp_mirailens_' on browser automation tools (navigate, click, etc.) adds no semantic value and wastes characters. Simpler names like 'navigate', 'click', 'type' are clearer and follow production baselines. Prefix should be dropped or used only for true protocol-level disambiguation.
Add tool annotations (readOnlyHint, destructiveHint, idempotentHint) to tool schemas. Mark navigate, click, type as destructiveHint=true (they modify state). Mark screenshot, get_console_logs as readOnlyHint=true. Mark emergency_stop as destructiveHint=true with confirmation=required.
Register control/policy/history tools explicitly in src/server.ts with full Zod schema definitions, not just file references. Define input schemas for pause_ai, get_policy, set_policy, etc. in a new file src/types/mcp/control-tools.ts to match the pattern of src/types/mcp/tool.ts.
Document permissions required for each tool. Add a 'scope' or 'permission' field to tool metadata. Example: set_policy requires 'admin:policy', take_control requires 'user:control'. This enables least-privilege agent configuration per pattern:scope-declaration.
Add recovery guides to error responses. When click fails with 'Element not found', return: 'Element matching "button[aria-label=Submit]" not found. Call mcp_mirailens_snapshot first to see available elements, then update your selector.' This guides the LLM to recover instead of retrying blindly.
Simplify tool names: drop the 'mcp_mirailens_' prefix on browser tools. Use 'navigate', 'click', 'screenshot' instead. This aligns with production baselines (avg name length 18 chars) and reduces token waste. Reserve prefixes for true protocol-level conflicts.
Add pagination support to discovery tools (get_action_history, get_agent_status). Include limit, offset, and total_count in responses so LLMs can fetch large datasets without blowing context. Example: get_action_history(limit: 20, offset: 0) returns { actions: [...], total: 342, offset: 0, limit: 20 }.
Create a confirmation pattern for irreversible tools. Before executing emergency_stop or set_policy with dangerous values, require a two-step call: (1) confirm_policy_change(policy_name, reason) returns a confirmation_token, (2) set_policy(policy_name, confirmation_token, value) actually applies it. This prevents accidental destructive actions per pattern:confirmation-request.
Add type hints and descriptions for policy values. Document what valid policies are and what values they accept. Example: 'set_policy(name: "allow_ai_write" | "rate_limit_calls" | "deny_destructive", value: bool | number). allow_ai_write: true/false enables AI write access. rate_limit_calls: 1-1000 calls/min.'
Add audit logging. Log all control/policy/history calls with timestamp, caller identity, parameters, and result. Per pattern:audit-trail, this is essential for compliance and incident response on sensitive tools.