Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
mcpd exposes 12 shell/Python scripts as MCP tools via HTTP. Tool definitions are inferred from script metadata (--help flag parsing) rather than explicitly registered in code, which caps per-tool scores at 50 per HARD SCORING RULE #5. Naming is verb-noun consistent (greet, add-numbers, calculator), but many descriptions are extremely brief (10-20 chars). Parameter schemas are present and mostly well-formed with types and descriptions, but descriptions often lack guidance on format, constraints, or when to use each tool. Error handling is not evident in the tool definitions. No tool annotations (readOnlyHint, destructiveHint, idempotentHint) are declared. Output schemas are not documented.
Tool definitions are inferred from script --help output rather than explicitly registered in code. This violates the assumption that tool schemas are declaratively specified and discoverable. Per HARD SCORING RULE #5, this caps per-tool scores at 50.
Many tool descriptions are extremely brief (10-35 chars): 'A simple hello world greeting', 'Get the current date and time', 'A simple calculator', 'A simple key-value store'. Per HARD SCORING RULE #3, descriptions under 20 chars cannot exceed 40/100. These lack context on WHEN to call the tool, WHAT it returns, and any prerequisites.
hello-worldcurrent-timecalculatorkey-value-store
HIGH
Recommendations
Register tools explicitly in code with full JSON Schema definitions, not inferred from script --help. This allows the MCP server to declare schemas statically and publish them at discovery time.
Expand tool descriptions to 50-200 chars. Include WHAT the tool does, WHEN an LLM should call it, and WHAT it returns. Example: 'Increment, decrement, reset, or set a global counter. Maintains state across calls. Use to track session counts, generate unique IDs, or manage rate limits. Returns {action, count, timestamp}.'
Document output schemas for every tool. Specify return type (object/array/string), required fields, and examples. Example for counter: '{"action": string, "count": number, "timestamp": string}'.
Add tool annotations to the response. Declare readOnlyHint for all READ_ONLY tools and destructiveHint for all WRITE tools. This guides agent safety reasoning.
For parameters with constraints, move constraints into JSON Schema (minValue, maxValue, enum, pattern) and repeat in descriptions. Example for task-queue priority: schema {"type": "integer", "minimum": 1, "maximum": 5}, description: 'Priority 1-5 (1=highest). Lower values execute first.'
Add parameter relationship documentation. E.g., for key-value-store: 'The "value" parameter is only used when action="set". For action="get" or "delete", key is required; value is ignored.'
Include recovery guidance in tool descriptions for potentially failing operations. E.g., for deployment-manager: 'If approval is required, the call returns a pending status. Call with action="approve" to proceed, or call with action="rollback" to undo.'
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
No output schemas are documented. Tool descriptions do not specify what fields or structure will be returned. This forces LLMs to infer output shape and blocks downstream tool chaining.
'key-value-store' violates naming pattern: contains a hyphen and uses underscore in params (action, key, value). Inconsistent naming makes it harder for LLMs to predict parameter names. Should be 'manage_key_value_store' or 'kv_store_*' prefix for clarity.
Parameter descriptions lack format guidance. E.g., 'task-queue' accepts 'priority 1-5' but description says '1=highest' without stating what happens if you pass 6 or 0. Many descriptions omit constraints like min/max, regex patterns, enum values, or required dependencies.
No error handling guidance. Tool descriptions do not explain what happens on failure, whether errors are retryable, or what the LLM should do if a call fails. Agents lack recovery context.
Specify the default behavior of each action parameter clearly. E.g., 'Default action is "list". Omit to retrieve all items.' This prevents LLMs from guessing.
For stateful tools (counter, key-value-store, task-queue), document persistence scope: 'State is process-local and lost on server restart. Use a durable backend for production.' This manages expectations.
Consider splitting generic 'action' enums into separate, focused tools. E.g., instead of key-value-store with {action: [get, set, delete, list, clear]}, offer get_kv, set_kv, delete_kv, list_kv, clear_kv. This enables better tool selection and composition.