Critical deficiencies across all 13 tools. No visible input schemas in source code, cannot verify parameter type definitions, constraints, or structure. Tool descriptions are extremely brief (6-12 words), lacking context for LLM selection, prerequisites, or WHEN to use each tool. No documented output schemas. No error handling guidance. Tools exhibit composition problems (fork_thread, get_thread suggest stateful operation patterns inconsistent with MCP's stateless design). Parameter descriptions are entirely absent from visible code. High-risk tools like send_to_target, flag_lead, record_finding, register_invention, and submit_report lack permission gates, dry-run modes, or confirmation mechanisms. The server exposes tools for an adversarial red-teaming domain (recon_probe, register_invention) without documented safety guardrails, audit trails, or scope declarations.
No input schemas visible in source code. Cannot verify parameter types, constraints, enums, ranges, or descriptions for any of the 13 tools. Per HARD SCORING RULE, schema score must be 0 for all tools.
Add full input schemas to all 13 tools. Every parameter must have a 'type' (string, number, boolean, object, array), 'description' (50 - 150 chars), and constraints (enum, minLength, pattern, minimum, maximum). Use JSON Schema format and register schemas in the tool definition.
Each description must answer: (1) What does the tool do? (2) When should the LLM call it instead of a similar tool? (3) What does it return? Example: 'List all flagged security findings (leads) discovered during reconnaissance. Returns finding ID, type, severity, and recommendation. Call this after running flag_lead or at the end to summarize detections.'
Document output schemas for all tools. Specify the JSON structure and field types returned by each tool. Example: list_leads returns [{id: string, type: enum[privilege_escalation, injection, etc], severity: enum[critical, high, medium, low], description: string}]. Include any pagination fields (total_count, next_cursor).
Add permission gates and scope declarations to all WRITE tools (send_to_target, fork_thread, flag_lead, record_finding, register_invention, submit_report). Require 'write:opfor' scope and verify calling user/agent has authorization before executing.
Implement confirmation/dry-run patterns for send_to_target and register_invention. These tools have irreversible consequences (attacking targets, registering attack techniques). Add a 'dry_run' boolean parameter and require explicit confirmation before execution.
Refactor fork_thread and get_thread to use stateless, request-scoped thread identifiers. Instead of storing thread state server-side, accept a 'thread_id' parameter (UUID generated by client) and return it in responses so subsequent calls can reference the same thread. This aligns with MCP's stateless protocol design.
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Dynamic Client Registration (deprecated) - use Client ID Metadata Documents (CIMD)
Score history
Overall score trend
First recorded score · v2 rubric
38/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-23
F
38
<=2025-11-25
v2
Reconnaissance probe tool for gathering target information
No documented output schemas for any tool. LLMs cannot determine what fields to expect, what data types are returned, or how to chain results into downstream tool calls. This violates the requirement that tools return structured objects with typed fields and document the output schema.
High-risk tools (send_to_target, flag_lead, record_finding, register_invention, submit_report) marked as WRITE lack permission gates, dry-run modes, confirmation requests, and audit trails. These are destructive/consequential operations that need safety guardrails.
Stateful operation patterns (fork_thread, get_thread) suggest the server maintains thread execution state across requests. MCP protocol is stateless per 2026-07-28 spec. Each request must be self-contained. If threads are needed, they should be identified by client-provided IDs passed in request parameters, not stored server-side.
No error handling guidance documented. Tools provide no recovery hints (e.g., 'If recon_probe fails, try with different target parameters'). Error responses lack categorization (retryable vs. user-fixable vs. fatal). LLMs cannot determine next steps on failure.
Red-teaming tools (recon_probe, register_invention, send_to_target) lack explicit scope declarations and audit trail specifications. No visible enforcement of 'read:recon' vs 'write:recon' permissions. No documented logging of who called what, when, and what happened.
Tools operating on same resources lack naming clarity. Example: list_knowledge vs get_knowledge, unclear if one returns summaries and the other full entries, or if they return the same structure.
No parameter descriptions visible in source code. Even if parameters exist in schema, LLMs cannot understand their meaning, constraints, or valid values without descriptions in the tool definition.
Add error handling guidance to all tools. Document retryable errors (e.g., 'Target temporarily unavailable, retry with exponential backoff'), user-fixable errors (e.g., 'Invalid target format, expected IP:port or domain'), and fatal errors (e.g., 'Access denied, check permissions'). Include recovery hints in error responses.
Add audit trail logging to all WRITE tools. Log: caller identity, tool name, parameters (sanitized), timestamp, result (success/failure), and error details (if any). This enables security reviews and incident response.
Clarify tool relationships. Rename list_knowledge → describe_knowledge_entries and get_knowledge → retrieve_knowledge_entry to disambiguate. Similarly, rename list_leads → summarize_findings and flag_lead → create_finding. Distinct names prevent LLM confusion.
Add parameter descriptions for common inputs. If send_to_target accepts a 'target' parameter, describe it as: 'IP address or domain of the target system. Format: IP:port (e.g., 192.168.1.1:8080) or domain (e.g., example.com:443). Required.'
For list_* tools, add pagination support. Accept 'limit' (1 - 100, default 20) and 'offset' or 'cursor' parameters. Return 'total_count' and 'next_cursor' in responses. This prevents context window exhaustion when returning large result sets.
Implement input validation with actionable error messages. Example: Instead of 'Invalid input', return 'Invalid severity level: got "medium-high", must be one of: critical, high, medium, low, info'. This guides LLM self-correction.