Skip to main content
Glama
SuReaper

NullShot Typescript MCP Template

by SuReaper
mcp-generation-patterns.mdc5.8 kB
--- globs: src/tools.ts,src/resources.ts,src/prompts.ts,src/server.ts description: "Code generation patterns for MCP server components" --- # MCP Component Generation Patterns ## Tool Generation Rules When generating tools in [tools.ts](mdc:src/tools.ts): ```typescript // ALWAYS follow this exact pattern server.tool( 'action_noun', // Use snake_case, action + noun format 'Action description in imperative mood', { // REQUIRED parameters first, then optional required_param: z.string().describe('Clear description'), optional_param: z.string().optional().describe('Optional description'), }, async ({ required_param, optional_param }) => { try { // Validate inputs if needed if (!required_param?.trim()) { throw new Error('Required parameter cannot be empty'); } // Core logic here const result = await performAction(required_param, optional_param); return { content: [{ type: "text", text: `Success: ${result.message}` }], result // Include actual data for programmatic use }; } catch (error) { return { content: [{ type: "text", text: `Error: ${error.message}` }], isError: true }; } } ); ``` **Tool Naming Convention:** - `create_item` not `createItem` or `item_create` - `get_status` not `status` or `getStatus` - `update_settings` not `updateSettings` ## Resource Generation Rules When generating resources in [resources.ts](mdc:src/resources.ts): ```typescript // Pattern for single item resources server.resource( 'get_item', 'data://service/items/{id}', async (uri: URL) => { const id = uri.pathname.split('/').pop(); // Implementation } ); // Pattern for collection resources server.resource( 'list_items', 'data://service/items?filter={filter}', async (uri: URL) => { const filter = uri.searchParams.get('filter'); // Implementation } ); ``` **Resource URI Patterns:** - Use descriptive schemes: `data://`, `config://`, `status://` - Always include placeholders: `{id}`, `{category}`, `{filter}` - Support query parameters for filtering/options ## Prompt Generation Rules When generating prompts in [prompts.ts](mdc:src/prompts.ts): ```typescript // Interactive prompts for user guidance server.prompt( 'help_getting_started', 'Get help with initial setup and usage', (args?: { topic?: string }) => ({ messages: [{ role: 'assistant', content: { type: 'text', text: `Welcome! I can help you with ${args?.topic || 'getting started'}. Here are the available options: 1. Basic setup - Get started with initial configuration 2. Advanced features - Learn about advanced capabilities 3. Troubleshooting - Solve common issues What would you like to learn about?` } }] }) ); // System prompts for AI behavior server.prompt( 'system_behavior', 'Configure AI assistant behavior for this domain', () => ({ messages: [{ role: 'system', content: { type: 'text', text: `You are a helpful assistant specialized in [domain]. Guidelines: - Always be accurate and helpful - Ask clarifying questions when needed - Provide step-by-step instructions - Include relevant examples` } }] }) ); ``` ## Server Extension Pattern When extending the server class in [server.ts](mdc:src/server.ts): ```typescript export class DomainMcpServer extends McpHonoServerDO<Env> { constructor(ctx: DurableObjectState, env: Env) { super(ctx, env); } getImplementation(): Implementation { return { name: 'DomainMcpServer', // Use descriptive, domain-specific name version: '1.0.0', }; } configureServer(server: McpServer): void { setupServerTools(server); // Always include all three setupServerResources(server); setupServerPrompts(server); } // Only add setupRoutes if custom HTTP endpoints are needed protected setupRoutes(app: Hono<{ Bindings: Env }>): void { super.setupRoutes(app); // CRITICAL: Always call parent first // Group related endpoints app.get('/api/health', this.handleHealthCheck.bind(this)); app.post('/api/webhook', this.handleWebhook.bind(this)); } private async handleHealthCheck(c: any) { return c.json({ status: 'ok', timestamp: Date.now() }); } private async handleWebhook(c: any) { // Implementation } } ``` ## Error Handling Patterns Always include proper error handling: ```typescript // In tools try { const result = await riskyOperation(); return { content: [{ type: "text", text: `Success: ${result}` }] }; } catch (error) { console.error('Tool error:', error); return { content: [{ type: "text", text: `Error: ${error.message}` }], isError: true }; } // In resources try { const data = await fetchData(); return { contents: [{ text: JSON.stringify(data), uri: uri.href }] }; } catch (error) { throw new Error(`Resource fetch failed: ${error.message}`); } ``` ## Validation Patterns Use Zod for comprehensive validation: ```typescript // Complex parameter schemas { // Strings with constraints title: z.string().min(1).max(100).describe('Item title (1-100 chars)'), // Enums for controlled values status: z.enum(['draft', 'published', 'archived']).describe('Publication status'), // Optional with defaults priority: z.number().min(1).max(5).default(3).describe('Priority level (1-5)'), // Arrays with validation tags: z.array(z.string().min(1)).optional().describe('List of tags'), // Nested objects metadata: z.object({ category: z.string(), subcategory: z.string().optional() }).optional().describe('Additional metadata') } ```

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/SuReaper/cortensor-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server