index.js•8.9 kB
#!/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);