Skip to main content
Glama
chrisleekr

MCP Server Boilerplate

by chrisleekr
index.ts7.71 kB
/* eslint-disable max-lines-per-function */ import { zodToJsonSchema } from 'zod-to-json-schema'; import { loggingContext, sendProgressNotification } from '@/core/server'; import { createResourceLink, createStructuredContent, Tool, ToolBuilder, ToolContext, ToolInputSchema, ToolResult, } from '@/tools/types'; import packageJson from '../../../package.json'; import { EchoInput, EchoInputSchema, EchoOutput } from './types'; /** * Echo tool implementation */ async function* executeEcho( input: EchoInput, context: ToolContext ): AsyncGenerator<ToolResult & { data?: EchoOutput }> { const progressToken = context.progressToken; loggingContext.log('info', `Progress token: ${progressToken}`); loggingContext.setContextValue('tool', 'echo'); const startTime = Date.now(); try { loggingContext.log('debug', 'Executing echo tool', { data: { input } }); // Send mid-progress notification if (context.server) { await sendProgressNotification(context.server, { progressToken, progress: 0, total: 100, message: 'Starting echo tool', }); } // Validate input using Zod schema const validatedInput = EchoInputSchema.parse(input); // Process the message let processedMessage = validatedInput.message; if (validatedInput.uppercase) { processedMessage = processedMessage.toUpperCase(); } // Repeat the message const repeatedMessage = Array(validatedInput.repeat) .fill(processedMessage) .join(' '); // Send completion notification if (context.server) { await sendProgressNotification(context.server, { progressToken, progress: 100, total: 100, message: 'Echo tool completed', }); } // Prepare output const output: EchoOutput = { originalMessage: validatedInput.message, processedMessage: repeatedMessage, repeat: validatedInput.repeat, uppercase: validatedInput.uppercase, length: repeatedMessage.length, }; const executionTime = Date.now() - startTime; loggingContext.log('info', 'Echo tool executed successfully', { data: { messageLength: validatedInput.message.length, repeat: validatedInput.repeat, executionTime, }, }); // Create structured content for the new MCP spec const structuredOutput = createStructuredContent( output, { type: 'object', properties: { originalMessage: { type: 'string', description: 'The original input message', }, processedMessage: { type: 'string', description: 'The processed output message', }, repeat: { type: 'number', description: 'Number of repetitions applied', }, uppercase: { type: 'boolean', description: 'Whether uppercase transformation was applied', }, length: { type: 'number', description: 'Length of the final processed message', }, }, required: [ 'originalMessage', 'processedMessage', 'repeat', 'uppercase', 'length', ], }, 'json' ); // Create example resource links const resourceLinks = [ createResourceLink( 'echo://documentation', 'Echo Tool Documentation', 'Documentation for the echo tool functionality', 'text/markdown' ), createResourceLink( `echo://result/${Date.now()}`, 'Echo Result', 'The result of this echo operation', 'application/json' ), ]; yield { success: true, data: output, executionTime, timestamp: new Date().toISOString(), metadata: { toolVersion: packageJson.version, mcpSpecVersion: '2025-06-18', originalLength: validatedInput.message.length, finalLength: repeatedMessage.length, features: ['structured_output', 'resource_links'], }, structuredContent: structuredOutput, resourceLinks, }; } catch (error) { const executionTime = Date.now() - startTime; const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'; loggingContext.log('error', 'Echo tool execution failed', { data: { error: { message: errorMessage, stack: error instanceof Error ? error.stack : undefined, }, input, executionTime, }, }); yield { success: false, error: errorMessage, executionTime, timestamp: new Date().toISOString(), metadata: { toolVersion: packageJson.version, inputValidation: 'failed', }, }; } } /** * Create and export the echo tool */ export const echoTool: Tool<EchoInput, EchoOutput> = new ToolBuilder< EchoInput, EchoOutput >('echo') .description( 'Echo a message back with optional transformations, repetition, and structured output support' ) .inputSchema(zodToJsonSchema(EchoInputSchema) as typeof ToolInputSchema) .outputSchema({ type: 'object', properties: { originalMessage: { type: 'string', description: 'The original input message', }, processedMessage: { type: 'string', description: 'The processed output message', }, repeat: { type: 'number', description: 'Number of repetitions applied' }, uppercase: { type: 'boolean', description: 'Whether uppercase transformation was applied', }, length: { type: 'number', description: 'Length of the final processed message', }, }, required: [ 'originalMessage', 'processedMessage', 'repeat', 'uppercase', 'length', ], }) .examples([ { input: { message: 'Hello, World!' }, output: { success: true, data: { originalMessage: 'Hello, World!', processedMessage: 'Hello, World!', repeat: 1, uppercase: false, length: 13, }, structuredContent: { type: 'structured', content: { originalMessage: 'Hello, World!', processedMessage: 'Hello, World!', repeat: 1, uppercase: false, length: 13, }, format: 'json', }, resourceLinks: [ { type: 'resource_link', uri: 'echo://documentation', name: 'Echo Tool Documentation', description: 'Documentation for the echo tool functionality', mimeType: 'text/markdown', }, ], }, description: 'Simple echo example', }, { input: { message: 'Hello', repeat: 3, uppercase: true }, output: { success: true, data: { originalMessage: 'Hello', processedMessage: 'HELLO HELLO HELLO', repeat: 3, uppercase: true, length: 17, }, structuredContent: { type: 'structured', content: { originalMessage: 'Hello', processedMessage: 'HELLO HELLO HELLO', repeat: 3, uppercase: true, length: 17, }, format: 'json', }, }, description: 'Echo with repetition and uppercase transformation', }, ]) .tags(['utility', 'example', 'text']) .version(packageJson.version) .timeout(2000) .streamingImplementation(executeEcho) .build();

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/chrisleekr/mcp-server-boilerplate'

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