No output schemas documented. LLMs cannot plan multi-step workflows or extract required fields from responses (e.g., what fields does list-components return? Is there pagination?). The rubric mandates: 'Document the output schema. LLMs need to know what fields to expect so they can plan downstream tool calls and extract the right data.' [Source: pattern:tool]. None of the 4 tools declare their return structure.
Tool descriptions are generic and lack context for LLM selection. 'Lists all available Taroify components' (5 words) and 'Gets detailed documentation for a specific component' (8 words) fall below the minimum clarity threshold. State WHAT the tool does, WHEN to use it, and any prerequisites.' None of the 4 tools answer WHEN to call them instead of similar tools or any dependencies.
Document output schemas for all 4 tools. Create a response type for each tool describing fields, types, and examples. E.g., list-components returns [{name: string, dirName: string}, ...]; get-component-docs returns {name: string, documentation: string, apiSection: string, examples: Record<string, string>}. Without this, LLMs cannot validate responses or plan follow-up calls.
Expand tool descriptions to 50-150 characters with WHEN/WHY guidance. Example: 'Lists all available Taroify components. Call this first to discover available components, then use get-component-docs or get-component-props to retrieve detailed docs or API specs for a specific component.' This clarifies dependency ordering and helps LLMs choose the right tool.
Add constraint and discovery hints to the 'componentName' parameter. Change description from 'The name of the component to get documentation for' to 'The name of a Taroify component (e.g., button, checkbox, switch). Call list-components first to see all available names. Names are case-sensitive.' This reduces invalid LLM calls.
Add pagination to list-components and list-component-example. Include limit (default 20, max 100) and offset parameters. Return {components: [...], total: number, offset: number, limit: number} to signal pagination support. If Taroify has 100+ components, defaulting to all would blow context windows.
Implement structured error handling with actionable recovery hints. If a component name is not found, return: {error: 'Component not found', invalid_name: 'invalid-component', suggestion: 'Did you mean: button, checkbox, input?', call_list_components: true}. This guides LLMs to self-correct without extra turns.
Parameter descriptions lack constraints and usage guidance. The 'componentName' param appears in 3 tools with description 'The name of the component to [get/list] [documentation/examples/API] for', but LLMs cannot infer valid component names without knowing the enumeration or discovery mechanism. "The project key (2-10 uppercase letters, e.g. PROJ)" is actionable; "The project key" alone invites invalid input from LLMs.' No guidance on how to discover valid component names or whether partial matches are accepted.
No pagination or result-limiting strategy visible. Without pagination, large results blow the context window.' list-components and list-component-example offer no limit, offset, or pagination parameters. If Taroify has 100+ components, returning all would exhaust context. The tool description should state: 'Returns up to N results; use pagination to retrieve additional components.'
No error handling guidance or recovery paths. If a component name does not exist, LLMs receive no direction on how to recover (e.g., 'Try list-components() to see available names' or 'Did you mean: button, checkbox, switch?'). A raw error code or stack trace gives the agent nothing to act on.' [Source: pattern:recovery-guide]. No visible error handling in src/tools/components.ts source provided.
No documented return types or field structure. The rubric baseline states '100% of A+ tools have documented return types.' The source code provided does not include the tool implementation details (src/tools/components.ts is referenced but not shown). Without seeing the response structures, LLMs cannot be confident in downstream data extraction. Example: Does get-component-props return {props: {...}, examples: []}? Or {api: string, props: string}? This ambiguity forces LLMs to hallucinate response shapes.
Tool composition lacks idempotency guarantees and chaining hints. Agents retry on ambiguous failures, non-idempotent tools risk duplicate side effects.' All 4 tools are read-only (Risk=READ_ONLY), so idempotency is inherently satisfied. However, composition is weak: list-components → get-component-docs is a natural two-step flow, but there is no guidance in descriptions like 'Call list-components first to see available components, then pass a component name to this tool.' [Source: pattern:tool-description, dependency-hints].
Naming ambiguity in 'list-component-example' vs 'list-component-examples'. The singular 'example' is grammatically inconsistent with the plural intent ('Lists all example available for...'). This minor inconsistency could cause LLM confusion when auto-completing or filtering tool lists.
list-component-example
Rename 'list-component-example' to 'list-component-examples' (plural) for grammatical consistency and clarity. This avoids potential LLM confusion when parsing tool names.
Add composition hints to descriptions. E.g., 'get-component-docs: Gets detailed documentation for a specific component. Prerequisite: Call list-components() first if you do not know the component name.' This enables multi-step agent workflows.
Include example component names in the documentation (separate from tool descriptions). Create a discovery endpoint or static reference that LLMs can reason about without calling list-components every time (e.g., 'Taroify includes 50+ components including Button, Checkbox, Input, Dialog, Toast...').
Add rate limiting and timeout guidance. Document limits like 'Max 100 components per call' and 'Timeout: 5 seconds per request' in tool descriptions so agents can plan for failures.
Create a discovery/diagnostic tool (optional) like 'describe-taroify' that returns server metadata: {component_count: number, version: string, supported_locales: [...], rate_limits: {...}}. This helps agents understand the tool scope upfront.