Memory Cache MCP Server

  • build
#!/usr/bin/env node import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ErrorCode, ListResourcesRequestSchema, ListToolsRequestSchema, McpError, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js'; import { CacheManager } from './CacheManager.js'; class MemoryCacheServer { constructor() { this.server = new Server({ name: 'charly-memory-cache-server', version: '0.1.0', }, { capabilities: { resources: {}, tools: {}, }, }); this.cacheManager = new CacheManager(); this.setupResourceHandlers(); this.setupToolHandlers(); // Error handling this.server.onerror = (error) => console.error('[MCP Error]', error); process.on('SIGINT', async () => { await this.close(); process.exit(0); }); } setupResourceHandlers() { // List available resources this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({ resources: [ { uri: 'cache://stats', name: 'Cache Statistics', mimeType: 'application/json', description: 'Real-time cache performance metrics', }, ], })); // Handle resource reads this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => { if (request.params.uri === 'cache://stats') { return { contents: [ { uri: request.params.uri, mimeType: 'application/json', text: JSON.stringify(this.cacheManager.getStats(), null, 2), }, ], }; } throw new McpError(ErrorCode.InvalidRequest, `Unknown resource: ${request.params.uri}`); }); } setupToolHandlers() { this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ { name: 'store_data', description: 'Store data in the cache with optional TTL', inputSchema: { type: 'object', properties: { key: { type: 'string', description: 'Unique identifier for the cached data', }, value: { type: 'any', description: 'Data to cache', }, ttl: { type: 'number', description: 'Time-to-live in seconds (optional)', }, }, required: ['key', 'value'], }, }, { name: 'retrieve_data', description: 'Retrieve data from the cache', inputSchema: { type: 'object', properties: { key: { type: 'string', description: 'Key of the cached data to retrieve', }, }, required: ['key'], }, }, { name: 'clear_cache', description: 'Clear specific or all cache entries', inputSchema: { type: 'object', properties: { key: { type: 'string', description: 'Specific key to clear (optional - clears all if not provided)', }, }, }, }, { name: 'get_cache_stats', description: 'Get cache statistics', inputSchema: { type: 'object', properties: {}, }, }, ], })); this.server.setRequestHandler(CallToolRequestSchema, async (request) => { try { switch (request.params.name) { case 'store_data': { const { key, value, ttl } = request.params.arguments; this.cacheManager.set(key, value, ttl); return { content: [ { type: 'text', text: `Successfully stored data with key: ${key}`, }, ], }; } case 'retrieve_data': { const { key } = request.params.arguments; const value = this.cacheManager.get(key); if (value === undefined) { return { content: [ { type: 'text', text: `No data found for key: ${key}`, }, ], isError: true, }; } return { content: [ { type: 'text', text: JSON.stringify(value, null, 2), }, ], }; } case 'clear_cache': { const { key } = request.params.arguments; if (key) { const success = this.cacheManager.delete(key); return { content: [ { type: 'text', text: success ? `Successfully cleared cache entry: ${key}` : `No cache entry found for key: ${key}`, }, ], }; } else { this.cacheManager.clear(); return { content: [ { type: 'text', text: 'Successfully cleared all cache entries', }, ], }; } } case 'get_cache_stats': { const stats = this.cacheManager.getStats(); return { content: [ { type: 'text', text: JSON.stringify(stats, null, 2), }, ], }; } default: throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`); } } catch (error) { return { content: [ { type: 'text', text: error instanceof Error ? error.message : String(error), }, ], isError: true, }; } }); } async run() { const transport = new StdioServerTransport(); await this.server.connect(transport); console.error('Memory Cache MCP server running on stdio'); } async close() { this.cacheManager.destroy(); await this.server.close(); } } const server = new MemoryCacheServer(); server.run().catch(console.error);