Production MCP server for data annotation workflow
Server has 6 tools with mixed quality. Strengths: all tools have descriptions (10-50 chars each); input schemas present with types and constraints (minLength, enums, defaults); clear naming (verb_noun pattern: s3_upload, dynamo_read, etc.); rate limiting and auth middleware. Weaknesses: descriptions are terse (avg 35 chars, below 72-char baseline); s3_upload and slack_notify lack visible descriptions in source; no output schemas documented; error handling returns only error codes + requestId, not recovery guidance; no tool annotations (readOnlyHint/destructiveHint); composition risk: annotation_status combines read+write+notify in one tool.
Read or update an annotation task's status, optionally notifying Slack.
Read a single record from DynamoDB by primary key 'id'.
Write a record to DynamoDB keyed by 'id'.
Download an object from S3 (scoped to the caller) base64-encoded.
s3_upload and slack_notify have no visible descriptions or input schemas in source code. Cannot verify parameter definitions.
No output schemas documented for any tool. LLMs cannot predict response structure or plan downstream calls. Violates pattern:tool baseline (100% of A+ tools have documented return types).
Error responses return only {error: code, requestId}, no recovery guidance. Pattern:recovery-guide requires 'what to do next' hints. E.g., 'User not found. Try search_users() with a partial name.'
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 50 | <=2025-11-25 | v2 |
annotation_status combines read, write, and side-effect (Slack notify) in one tool. Violates pattern:tool (each tool should do exactly one thing). Should split into annotation_status_read, annotation_status_update, and optionally annotation_notify_slack.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) present. Agents cannot distinguish safe reads from destructive writes without explicit hints. s3_upload, dynamo_write, slack_notify, annotation_status (write path) should be marked destructive.