A tool's description is the only text an AI reads when deciding whether to call it, and when to choose it over a similar tool. A description that just repeats the name ("Deletes a file" for a tool named delete_file) adds zero signal. Missing side-effect disclosures are especially dangerous: OWASP LLM09 surfaces here when the model cannot distinguish a read-only inspection tool from one that permanently deletes records, potentially auto-approving destructive calls without user confirmation.
High because poor descriptions cause the AI to invoke the wrong tool or fail to warn users about destructive side effects, leading to unrecoverable operations without confirmation.
Rewrite every description to answer three questions in one sentence: what it does, when to prefer it over similar tools, and whether it has side effects.
// src/tools/files.ts
server.tool(
'delete_file',
'Permanently delete a file from disk — irreversible, not sent to trash. ' +
'Call read_file first to verify content. Use only when the user explicitly confirms deletion.',
{ path: z.string().describe('Absolute path to the file to delete') },
async ({ path }) => { /* handler */ }
)
For tools that overlap (e.g., query_db and run_sql), add a disambiguation clause: "Use this for read-only SELECT queries; use run_sql for mutations."
ID: mcp-server.tool-definitions.tool-descriptions
Severity: high
What to look for: Count all tool definitions. Enumerate which have descriptions of at least 20 characters vs. which have short or missing descriptions. Check the description string for every registered tool. Good descriptions answer three questions: (1) What does this tool do? (2) When should the AI use it vs. other tools? (3) Does it have side effects (writes, deletes, sends)? Check for missing descriptions, single-word descriptions, or descriptions that just repeat the tool name. Before evaluating, extract and quote the first 3 tool description strings found in the codebase.
Pass criteria: Every tool has a description that explains its purpose, distinguishes it from similar tools, and notes any side effects (file writes, API calls, destructive operations). Descriptions are useful to an AI selecting from a list of tools. 100% of tools must have descriptions of at least 20 characters that explain what the tool does and when to use it.
Fail criteria: Any tool has no description, or the description just repeats the name, or side effects are not mentioned for tools that write/delete/send.
Skip (N/A) when: The server registers no tools. All checks skip when no MCP server is detected.
Cross-reference: For tool naming conventions, see tool-naming.
Detail on fail: "Tool 'delete_file' has description 'Deletes a file' — does not mention that this is a destructive, irreversible operation. Tool 'search' has no description at all" or "Tools 'query_db' and 'run_sql' have identical descriptions — AI cannot determine which to use"
Remediation: Descriptions are how the AI decides whether to call your tool. Be specific about what it does and when:
// src/tools/search.ts — descriptive tool definition
{ name: "search_documents", description: "Search indexed documents by keyword query. Returns top 10 results with title and snippet." }
server.tool(
'delete_file',
'Permanently delete a file from disk. This is irreversible — the file is not moved to trash. Use read_file first to verify the content before deleting.',
{ path: z.string().describe('Absolute path to the file to delete') },
async ({ path }) => { /* handler */ }
)