What are Prompts?
Prompts are reusable templates in MCP that help AI models generate consistent, well-structured responses. They provide a way to standardize common tasks like code reviews, documentation generation, or data analysis.
In xmcp, prompts are automatically registered from the src/prompts/ directory using file-system routing.
Prompt Structure
Every prompt consists of three main exports:
The metadata export defines the prompt’s identity:
import { type PromptMetadata } from "xmcp" ;
export const metadata : PromptMetadata = {
name: "review-code" ,
title: "Review Code" ,
description: "Review code for best practices and potential issues" ,
role: "user" ,
};
The PromptMetadata interface from ~/workspace/source/packages/xmcp/src/types/prompt.ts:1-7 includes:
Unique identifier for the prompt
Human-readable title for the prompt
Description of what the prompt does
The role for the prompt message. Common values:
"user" - Prompt will be sent as a user message (default)
"assistant" - Prompt will be sent as an assistant message
"system" - Prompt will be sent as a system message
2. Schema Export
The schema export defines the prompt’s parameters using Zod:
import { z } from "zod" ;
export const schema = {
code: z . string (). describe ( "The code to review" ),
};
3. Default Export (Handler)
The default export is the function that generates the prompt text:
import { type InferSchema } from "xmcp" ;
export default function reviewCode ({ code } : InferSchema < typeof schema >) {
return {
type: "text" ,
text: `Please review this code for best practices...` ,
};
}
Real Examples
Basic Prompt: Code Review
From ~/workspace/source/examples/stdio-transport/src/prompts/review-code.ts:1-33:
import { z } from "zod" ;
import { type InferSchema , type PromptMetadata } from "xmcp" ;
// Define the schema for prompt parameters
export const schema = {
code: z . string (). describe ( "The code to review" ),
};
// Define prompt metadata
export const metadata : PromptMetadata = {
name: "review-code" ,
title: "Review Code" ,
description: "Review code for best practices and potential issues" ,
role: "user" ,
};
// Prompt implementation
export default function reviewCode ({ code } : InferSchema < typeof schema >) {
return {
type: "text" ,
text: `Please review this code for:
- Code quality and best practices
- Potential bugs or security issues
- Performance optimizations
- Readability and maintainability
Code to review:
\`\`\`
${ code }
\`\`\` ` ,
};
}
Advanced Prompt: Team Greeting with Completions
From ~/workspace/source/examples/http-transport/src/prompts/team-greeting.ts:1-39:
import { z } from "zod" ;
import { type InferSchema , type PromptMetadata , completable } from "xmcp" ;
// Define the schema for prompt parameters
export const schema = {
department: completable ( z . string (), ( value ) => {
return [ "engineering" , "sales" , "marketing" , "support" ]. filter (( d ) =>
d . startsWith ( value )
);
}),
name: completable ( z . string (), ( value , context ) => {
const department = context ?. arguments ?.[ "department" ];
if ( department === "engineering" ) {
return [ "Alice" , "Bob" , "Charlie" ]. filter (( n ) => n . startsWith ( value ));
} else if ( department === "sales" ) {
return [ "David" , "Eve" , "Frank" ]. filter (( n ) => n . startsWith ( value ));
} else if ( department === "marketing" ) {
return [ "Grace" , "Henry" , "Iris" ]. filter (( n ) => n . startsWith ( value ));
}
return [ "Guest" ]. filter (( n ) => n . startsWith ( value ));
}),
};
// Define prompt metadata
export const metadata : PromptMetadata = {
name: "team-greeting" ,
title: "Team Greeting" ,
description: "Generate a greeting for team members" ,
role: "assistant" ,
};
// Prompt implementation
export default function teamGreeting ({
department ,
name ,
} : InferSchema < typeof schema >) {
return `Hello ${ name } , welcome to the ${ department } team!` ;
}
The completable() helper enables autocomplete functionality for prompt parameters. The completion function receives:
value - The current input value
context - Optional context including other arguments
Creating Prompts with CLI
Use the xmcp CLI to quickly scaffold a new prompt:
xmcp create prompt my-prompt
This creates a new prompt file at src/prompts/my-prompt.ts with the basic structure:
import { z } from "zod" ;
import { type InferSchema , type PromptMetadata } from "xmcp" ;
export const schema = {
// Add your parameters here
};
export const metadata : PromptMetadata = {
name: "my-prompt" ,
title: "My Prompt" ,
description: "TODO: Add description" ,
role: "user" ,
};
export default function myPrompt ( params : InferSchema < typeof schema >) {
// TODO: Implement your prompt logic here
return `Your prompt content here` ;
}
Return Values
Prompts can return:
Simple strings - Direct text content:
return "Your prompt text here" ;
Text content objects - Structured format:
return {
type: "text" ,
text: "Your prompt text here" ,
};
Multiple content blocks - For complex prompts:
return [
{ type: "text" , text: "First part" },
{ type: "text" , text: "Second part" },
];
Prompt Roles
The role field determines how the prompt is presented to the AI model:
user Most common role. Used for instructions and requests from the user.
assistant Used for prompts that should appear as assistant responses.
system Used for system-level instructions and context.
Dynamic Prompts
Prompts can include dynamic content based on parameters:
export const schema = {
language: z . enum ([ "typescript" , "python" , "go" ]),
code: z . string (),
};
export default function reviewCode ({ language , code } : InferSchema < typeof schema >) {
const languageSpecific = {
typescript: "Check for proper TypeScript types and interfaces" ,
python: "Ensure PEP 8 compliance and proper type hints" ,
go: "Verify Go idioms and error handling patterns" ,
};
return `Review this ${ language } code:
Specific checks:
- ${ languageSpecific [ language ] }
- General best practices
- Security considerations
Code:
\`\`\` ${ language }
${ code }
\`\`\` ` ;
}
Best Practices
Be Specific and Clear Write prompts that clearly communicate the expected output. Include examples when helpful.
Use Structured Formatting Use markdown, bullet points, and code blocks to make prompts easy to parse.
Parameterize Common Variations Instead of creating multiple similar prompts, use parameters to handle variations.
Set Appropriate Roles Choose the right role for your prompt’s purpose:
Use "user" for most prompts
Use "assistant" for few-shot examples
Use "system" for behavior instructions
Test with Different Inputs Ensure your prompts work correctly with various parameter values.
Common Use Cases
Code Analysis
export const metadata : PromptMetadata = {
name: "analyze-code" ,
title: "Code Analysis" ,
description: "Analyze code for complexity and maintainability" ,
role: "user" ,
};
Documentation Generation
export const metadata : PromptMetadata = {
name: "generate-docs" ,
title: "Generate Documentation" ,
description: "Generate documentation from code" ,
role: "user" ,
};
Test Creation
export const metadata : PromptMetadata = {
name: "create-tests" ,
title: "Create Tests" ,
description: "Generate unit tests for code" ,
role: "user" ,
};
Next Steps
Building Tools Learn how to create executable tools
Building Resources Create static or dynamic resources for context