lint_tool_definition
Sanity-check a tool definition for common mistakes that hurt LLM tool-use accuracy: missing or vague descriptions, omitted required fields, schema fields without descriptions, and non-snake_case names.
Instructions
Sanity-check a tool definition for common mistakes that hurt LLM tool-use accuracy: missing description, vague description, no required fields, schema fields without descriptions, non-snake_case names.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| tool | Yes | A tool definition: { name, description, inputSchema }. |
Implementation Reference
- src/server.ts:168-216 (handler)The 'lintToolDefinitionTool' function that executes the linting logic: checks tool definition for missing name, non-snake_case name, missing/short/vague description, missing inputSchema, missing properties, fields without descriptions, and missing required fields.
function lintToolDefinitionTool(input: { tool: any }) { const t = input.tool ?? {}; const warnings: string[] = []; if (!t.name) { warnings.push('missing name'); } else if (!/^[a-z][a-z0-9_]*$/.test(t.name)) { warnings.push(`name "${t.name}" should be snake_case (lowercase, digits, underscores; starts with a letter)`); } if (!t.description) { warnings.push('missing description — LLMs rely on this to pick the right tool'); } else if (t.description.length < 20) { warnings.push('description is very short — consider expanding what the tool does, when to use it, and any preconditions'); } else if (/^(does stuff|misc|util|helper)$/i.test(t.description.trim())) { warnings.push('description is too vague to be useful'); } const schema = t.inputSchema; if (!schema) { warnings.push('missing inputSchema — tool calls will not be validated'); } else { if (schema.type !== 'object') { warnings.push('inputSchema.type should be "object" for MCP tool inputs'); } if (!schema.properties || Object.keys(schema.properties).length === 0) { warnings.push('inputSchema has no properties — accepts arbitrary input'); } else { for (const [field, spec] of Object.entries(schema.properties as Record<string, any>)) { if (!spec || typeof spec !== 'object') continue; if (!spec.description) { warnings.push(`schema.${field}: missing field description (LLMs use this to pick correct values)`); } } } if (!schema.required || (Array.isArray(schema.required) && schema.required.length === 0)) { warnings.push('inputSchema has no required fields — every call is "valid" and validation cannot help'); } } return { content: [ { type: 'text', text: JSON.stringify({ ok: warnings.length === 0, warnings }, null, 2), }, ], }; } - src/server.ts:74-93 (schema)Input schema for 'lint_tool_definition' tool: expects a 'tool' object with name, description, inputSchema fields, where only name is required.
{ name: 'lint_tool_definition', description: 'Sanity-check a tool definition for common mistakes that hurt LLM tool-use accuracy: missing description, vague description, no required fields, schema fields without descriptions, non-snake_case names.', inputSchema: { type: 'object', properties: { tool: { type: 'object', description: 'A tool definition: { name, description, inputSchema }.', properties: { name: { type: 'string' }, description: { type: 'string' }, inputSchema: { type: 'object' }, }, required: ['name'], }, }, required: ['tool'], }, - src/server.ts:53-109 (registration)Tool catalog array (TOOLS) that registers 'lint_tool_definition' along with other tools, used by ListToolsRequestSchema handler.
const TOOLS = [ { name: 'validate_tool_args', description: 'Validate a tool-call args object against a small shape spec. Returns { valid, error?, retry_hint? } where retry_hint is a ready-to-send LLM feedback message describing exactly what was wrong.', inputSchema: { type: 'object', properties: { tool_name: { type: 'string', description: 'Name of the tool being called (surfaces in retry_hint).', }, args: { type: 'object', description: 'The args object the LLM wants to pass.', }, shape: SHAPE_SCHEMA, }, required: ['tool_name', 'args', 'shape'], }, }, { name: 'lint_tool_definition', description: 'Sanity-check a tool definition for common mistakes that hurt LLM tool-use accuracy: missing description, vague description, no required fields, schema fields without descriptions, non-snake_case names.', inputSchema: { type: 'object', properties: { tool: { type: 'object', description: 'A tool definition: { name, description, inputSchema }.', properties: { name: { type: 'string' }, description: { type: 'string' }, inputSchema: { type: 'object' }, }, required: ['name'], }, }, required: ['tool'], }, }, { name: 'generate_retry_message', description: 'Given a tool name, validation error, and attempted args, build the canonical LLM-facing retry feedback message. Uses agentvet\'s ToolArgError.toLLMFeedback() formatting so the wording matches what runtime callers see.', inputSchema: { type: 'object', properties: { tool_name: { type: 'string' }, validation_error: { type: 'string' }, attempted_args: { type: 'object' }, }, required: ['tool_name', 'validation_error', 'attempted_args'], }, }, ] as const; - src/server.ts:123-124 (registration)Dispatch in CallToolRequestSchema handler: case matching 'lint_tool_definition' calling lintToolDefinitionTool.
case 'lint_tool_definition': return lintToolDefinitionTool(args as { tool: any });