UNPKG

mcp-mongo-server

Version:

A Model Context Protocol server for MongoDB connections

113 lines (112 loc) 4.03 kB
/** * Handles completion requests from the Model Context Protocol * @param options The request options * @returns Completion result with matching values */ export async function handleCompletionRequest({ request, client, db, isReadOnlyMode, }) { const { ref, argument } = request.params; // Handle completions for prompts if (ref.type === "ref/prompt") { return handlePromptCompletion(client, db, isReadOnlyMode, ref.name, argument); } // Handle completions for resources if (ref.type === "ref/resource") { return handleResourceCompletion(client, db, isReadOnlyMode, ref.uri, argument); } // Default empty response if reference type is not supported return emptyCompletionResult(); } /** * Handle completion requests for prompts * @param client MongoDB client * @param db MongoDB database * @param isReadOnlyMode Whether the database is in read-only mode * @param promptName Name of the prompt * @param argument Argument being completed * @returns Completion result */ async function handlePromptCompletion(client, db, isReadOnlyMode, promptName, argument) { if (!promptName) { return emptyCompletionResult(); } // Handle collection name completions if (argument.name === "collection") { return await completeCollectionNames(argument.value, db, isReadOnlyMode); } // Add other prompt completions here as needed return emptyCompletionResult(); } /** * Handle completion requests for resources * @param client MongoDB client * @param db MongoDB database * @param isReadOnlyMode Whether the database is in read-only mode * @param uri Resource URI * @param argument Argument being completed * @returns Completion result */ async function handleResourceCompletion(client, db, isReadOnlyMode, promptName, argument) { if (!promptName) { return emptyCompletionResult(); } // Handle collection name completions if (argument.name === "collection") { return await completeCollectionNames(argument.value, db, isReadOnlyMode); } // Add other prompt completions here as needed return emptyCompletionResult(); } /** * Get collection name completions for a partial value * @param partialValue Partial collection name * @param db MongoDB database * @param isReadOnlyMode Whether the database is in read-only mode * @returns Completion result with matching collection names */ async function completeCollectionNames(partialValue, db, isReadOnlyMode) { try { console.warn(`Completing collection names with partial value: ${partialValue}`); // Get list of collections const collections = await db.listCollections().toArray(); // Filter collections by partial value (case insensitive) const matchingCollections = collections .map((c) => c.name) .filter((name) => // Filter out system collections !name.startsWith("system.") && // Match partial value name.toLowerCase().includes(partialValue.toLowerCase())) // Sort alphabetically .sort(); console.warn(`Found ${matchingCollections.length} matching collections`); // Limit to 100 items as per spec const MAX_ITEMS = 100; const limitedResults = matchingCollections.slice(0, MAX_ITEMS); const hasMore = matchingCollections.length > MAX_ITEMS; return { completion: { values: limitedResults, total: matchingCollections.length, hasMore, }, }; } catch (error) { console.error("Error completing collection names:", error); // Return empty result on error return emptyCompletionResult(); } } /** * Create an empty completion result * @returns Empty completion result object */ function emptyCompletionResult() { return { completion: { values: [], total: 0, hasMore: false, }, }; }