Single tool server with basic functionality. Tool name is action-oriented (u301_shortening_urls_in_bulk) and the description is present and reasonably detailed. However, the description is verbose (290+ characters, exceeds p90 baseline of 392 but includes inline parameter documentation which is suboptimal placement). Input schema is visible with proper type definitions and descriptions for all parameters. The tool accepts an array of URL objects with proper JSON Schema structure. Critical gaps: (1) No output schema documented, the tool returns formatted text results, but the LLM has no way to know what fields will be present in the response. (2) No error handling guidance, errors are caught and returned as text but don't guide the LLM on recovery steps. (3) Tool description conflates what-it-does with parameter documentation (should separate into schema descriptions only). (4) No pagination or result limiting guidance despite accepting up to 200 URLs, which could produce very large responses. (5) Response format is unstructured text (formatResults function produces plaintext) rather than structured JSON, making downstream parsing error-prone.
Use U301's short link service API to batch shorten long URLs. Custom domains are supported, with up to 200 URLs per request. You should provide as "{ urls: <URLItem>[]" Current ShortLink domain is u301.co URLItem Supported Parameters are url: required, the URL to be shortened slug: optional, a custom slug for the shortened URL, the final shortened URL will be https://u301.co/<slug> if you leave it empty, random slug will create expiredAt: optional, the expiration date for the shortened URL, e.g. 2023-01-01T00:00:00Z password: optional, a password for the shortened URL comment: optional, a comment, displayed on the dashboard
No output schema documented. Tool returns formatted text results via formatResults() but LLM cannot determine what fields or structure to expect. This violates pattern:tool which requires output schema documentation.
Error handling does not guide recovery. Errors are caught generically and returned as plain text strings (e.g. 'Error: Too many URLs provided'). Per pattern:recovery-guide, errors should tell the LLM what to do next, classify errors as retryable/user-fixable/fatal, and include the invalid value and constraint violated.
Response format is unstructured plaintext rather than structured JSON. formatResults() produces multi-line text like '[0]: Failed to shorten ...' which forces LLMs to parse unstructured output. Per pattern:response-shaper, tools should return structured objects with typed fields.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 57 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 45 | - | v1 |
Tool description includes parameter documentation inline ('URLItem Supported Parameters are url: required...') rather than relying on schema descriptions. This violates separation of concerns, parameter details should live in the input schema, not the tool description. Tool description should focus on WHAT it does, WHEN to use it, and any prerequisites.
No guidance on result limits or pagination. Tool accepts up to 200 URLs and could return 200 result objects, producing large response text that bloats context and degrades LLM reasoning. Per pattern:paginated-result and mxe:enforce-result-limits, even bulk operations should document limits and offer pagination if results are unbounded.
Input parameter descriptions include example values (e.g. 'e.g. https://example.com/very/long/url' for url parameter). Per pattern:tool-description, example values in descriptions are anti-patterns, LLMs tend to reuse them literally rather than adapting to context. Use format constraints instead.