Prompt templates without argument definitions leave clients guessing at what inputs to supply. A prompt named review with no description gives the client no basis for surfacing it to the user at the right moment or pre-filling arguments. Duplicate prompt names cause non-deterministic selection. These failures map directly to MCP Spec noncompliance: the prompts/list response becomes misleading, and clients that rely on argument descriptions to build UI will silently omit required context.
Medium because undescribed or argument-free prompts degrade discoverability and usability without causing immediate security or data failures.
Add a description and a Zod argument schema to every server.prompt() registration.
// src/prompts/index.ts
server.prompt(
'review-code',
'Generate a targeted code review for a specific file. Focuses on bugs, security issues, and style violations.',
{
filePath: z.string().describe('Path to the file to review relative to project root'),
focusArea: z.enum(['bugs', 'security', 'style', 'all']).optional()
.describe('Area to focus on; defaults to all'),
},
async ({ filePath, focusArea }) => ({
messages: [{
role: 'user',
content: { type: 'text', text: `Review ${filePath} for ${focusArea ?? 'all issues'}...` }
}]
})
)
ID: mcp-server.tool-definitions.prompt-templates
Severity: medium
What to look for: Count all prompt templates defined in the server. Enumerate which have complete argument definitions vs. which lack them. Examine all prompt registrations (server.prompt() or prompt handler definitions). Check that each prompt has a name, a description explaining when to use it, and an arguments array with name, description, and required fields for each argument. Check that prompt GetPromptResult returns well-structured messages with appropriate roles.
Pass criteria: Every registered prompt has a descriptive name, a description explaining its purpose, and properly defined arguments with names, descriptions, and required flags. At least 90% of prompt templates must have argument definitions with descriptions.
Fail criteria: Any prompt is missing a description, or arguments lack descriptions, or the prompt name is vague or duplicated.
Skip (N/A) when: The server registers no prompts (tool-only or resource-only server). All checks skip when no MCP server is detected.
Cross-reference: For tool descriptions that complement prompts, see tool-descriptions.
Detail on fail: "Prompt 'review' has no description — clients cannot determine when to suggest it. Argument 'code' has no description — unclear whether to pass a file path, code snippet, or diff" or "Prompt 'summarize' and 'summary' appear to do the same thing — consolidate into one"
Remediation: Prompts are reusable templates that clients can offer to users. Make them discoverable:
// src/prompts/index.ts — prompt with arguments
{ name: "summarize", arguments: [{ name: "text", description: "Text to summarize", required: true }] }
server.prompt(
'review-code',
'Generate a code review for a specific file, focusing on bugs, security issues, and style',
{
filePath: z.string().describe('Path to the file to review'),
focusArea: z.enum(['bugs', 'security', 'style', 'all']).optional()
.describe('Area to focus the review on, defaults to all'),
},
async ({ filePath, focusArea }) => ({
messages: [{
role: 'user',
content: { type: 'text', text: `Review ${filePath} focusing on ${focusArea ?? 'all areas'}...` }
}]
})
)