UNPKG

mcp-think-tank

Version:

Structured thinking and knowledge management tool for Model Context Protocol

246 lines (245 loc) 9.82 kB
import { fileSystemAdapter } from './FileSystemAdapter.js'; import { networkAdapter } from './NetworkAdapter.js'; /** * Integrates file and URL caching with FastMCP tools * This demonstrates how to implement Story 3-G: Execution cache for file/URL reads */ export class AdapterIntegration { /** * Register cached file reading tools with FastMCP * @param server FastMCP server instance */ static registerCachedFileTools(server) { // Register a tool for reading files with caching server.addTool({ name: 'cached_read_file', description: 'Read a file with content-based caching', parameters: { type: 'object', properties: { filePath: { type: 'string', description: 'Path to the file to read' }, encoding: { type: 'string', description: 'File encoding (defaults to utf8)', enum: ['utf8', 'ascii', 'base64', 'hex', 'binary'], default: 'utf8' } }, required: ['filePath'] }, execute: async (args, context) => { try { const content = await fileSystemAdapter.readFileAsText(args.filePath, args.encoding || 'utf8'); // Return TextContent format expected by FastMCP return { type: 'text', text: content, metadata: { stats: fileSystemAdapter.getCacheStats() } }; } catch (error) { // Return error as text return { type: 'text', text: `Failed to read file: ${error.message}`, metadata: { error: true, stats: fileSystemAdapter.getCacheStats() } }; } } }); // Register a tool for reading JSON files with caching server.addTool({ name: 'cached_read_json', description: 'Read and parse a JSON file with content-based caching', parameters: { type: 'object', properties: { filePath: { type: 'string', description: 'Path to the JSON file to read' } }, required: ['filePath'] }, execute: async (args, context) => { try { const data = await fileSystemAdapter.readJsonFile(args.filePath); // Return as JSON string return { type: 'text', text: JSON.stringify(data, null, 2), metadata: { contentType: 'application/json', stats: fileSystemAdapter.getCacheStats() } }; } catch (error) { return { type: 'text', text: `Failed to read JSON file: ${error.message}`, metadata: { error: true, stats: fileSystemAdapter.getCacheStats() } }; } } }); } /** * Register cached URL fetching tools with FastMCP * @param server FastMCP server instance */ static registerCachedNetworkTools(server) { // Register a tool for fetching URLs with caching server.addTool({ name: 'cached_fetch_url', description: 'Fetch a URL with content-based caching', parameters: { type: 'object', properties: { url: { type: 'string', description: 'URL to fetch' }, encoding: { type: 'string', description: 'Response encoding (defaults to utf8)', enum: ['utf8', 'ascii', 'base64', 'hex', 'binary'], default: 'utf8' } }, required: ['url'] }, execute: async (args, context) => { try { const content = await networkAdapter.fetchText(args.url, args.encoding || 'utf8'); return { type: 'text', text: content, metadata: { url: args.url, stats: networkAdapter.getCacheStats() } }; } catch (error) { return { type: 'text', text: `Failed to fetch URL: ${error.message}`, metadata: { error: true, url: args.url, stats: networkAdapter.getCacheStats() } }; } } }); // Register a tool for fetching JSON from URLs with caching server.addTool({ name: 'cached_fetch_json', description: 'Fetch and parse JSON from a URL with content-based caching', parameters: { type: 'object', properties: { url: { type: 'string', description: 'URL to fetch JSON from' } }, required: ['url'] }, execute: async (args, context) => { try { const data = await networkAdapter.fetchJson(args.url); return { type: 'text', text: JSON.stringify(data, null, 2), metadata: { contentType: 'application/json', url: args.url, stats: networkAdapter.getCacheStats() } }; } catch (error) { return { type: 'text', text: `Failed to fetch JSON: ${error.message}`, metadata: { error: true, url: args.url, stats: networkAdapter.getCacheStats() } }; } } }); } /** * Replace existing file reading tools with cached versions * This shows how to update existing tools to use caching * @param server FastMCP server instance */ static enhanceExistingTools(server) { // Example of enhancing an existing tool with caching // This is just a demonstration - actual implementation would depend on existing tools // Hypothetical read_file tool enhancement const existingReadFile = server.getToolByName?.('read_file'); if (existingReadFile) { // Create a wrapped version of the tool const cachedReadFile = { ...existingReadFile, execute: async (args, context) => { // If the params include a target_file or file property, use caching if (args.target_file || args.file) { const filePath = args.target_file || args.file; try { const content = await fileSystemAdapter.readFileAsText(filePath); // Format the response to match the original tool's format return existingReadFile.execute({ ...args, _cached_content: content // Provide the content to avoid reading the file again }, context); } catch (error) { // Fall back to original tool if caching fails console.error(`[AdapterIntegration] Cache miss or error for ${filePath}:`, error); return existingReadFile.execute(args, context); } } // For other cases, use the original tool return existingReadFile.execute(args, context); } }; // Replace the existing tool // This would require access to the tools registry, which might not be directly accessible // server.replaceTool(cachedReadFile); // Alternatively, register as a new tool // server.addTool({ // ...cachedReadFile, // name: 'enhanced_read_file' // }); } } /** * Register all cached tools with FastMCP * @param server FastMCP server instance */ static registerAll(server) { this.registerCachedFileTools(server); this.registerCachedNetworkTools(server); // Uncomment to enhance existing tools // this.enhanceExistingTools(server); } }