Skip to main content
Glama

Elasticsearch Knowledge Graph for MCP

by j3k0
kg-inspection.ts7.04 kB
import logger from './logger.js'; import { KnowledgeGraphClient } from './kg-client.js'; import GroqAI from './ai-service.js'; /** * Inspect knowledge graph entities based on a query and information needed * @param {KnowledgeGraphClient} kgClient - The knowledge graph client * @param {string} informationNeeded - Description of what information is needed * @param {string|undefined} reason - Reason for the inspection (provides context to AI) * @param {string[]} keywords - Keywords related to the information needed * @param {string|undefined} zone - Memory zone to search in * @param {string[]|undefined} entityTypes - Optional filter to specific entity types * @returns {Promise<{ * entities: Array<{name: string, entityType: string, observations?: string[]}>, * relations: Array<{from: string, to: string, type: string, fromZone: string, toZone: string}>, * tentativeAnswer?: string * }>} */ export async function inspectKnowledgeGraph( kgClient: KnowledgeGraphClient, informationNeeded: string, reason: string | undefined, keywords: string[] = [], zone: string | undefined, entityTypes: string[] | undefined ): Promise<{ entities: Array<{name: string, entityType: string, observations?: string[]}>, relations: Array<{from: string, to: string, type: string, fromZone: string, toZone: string}>, tentativeAnswer?: string }> { try { // Prepare the search query using keywords const query = keywords.length > 0 ? keywords.join(' OR ') : '*'; logger.info(`Inspecting knowledge graph with query: ${query} for information: ${informationNeeded}`); // First search for entities matching the keywords (or all entities if no keywords provided) // Use this search to get up to 50 entities based on name matches const initialSearchParams = { query, includeObservations: false, // First search only for names, not full content entityTypes, limit: 50, // Get up to 50 matching entities sortBy: 'relevance' as const, // Sort by relevance by default zone, }; // First search - just get entity names that match keywords const initialSearchResults = await kgClient.userSearch(initialSearchParams); const initialEntities = initialSearchResults.entities; if (initialEntities.length === 0) { return { entities: [], relations: [], tentativeAnswer: "No matching entities found in the knowledge graph" }; } // If AI service is not enabled, just return the initial entities with a basic response if (!GroqAI.isEnabled) { logger.warn('AI service not enabled, returning initial entities without filtering'); // Get relations for these entities const entityNames = initialEntities.map(e => e.name); const relationsResult = await kgClient.getRelationsForEntities(entityNames, zone); const relations = relationsResult.relations; // Format relations for response const formattedRelations = relations.map(r => ({ from: r.from, to: r.to, type: r.relationType, fromZone: r.fromZone, toZone: r.toZone })); return { entities: initialEntities, relations: formattedRelations, tentativeAnswer: "AI service not enabled. Returning matching entities without analysis." }; } // Now do a detailed search with the AI to determine which entities are most relevant // We pass the initial entities to the AI filter to determine relevance // We also include observations this time to give AI more context const detailedSearchParams = { query, includeObservations: true, // Include full observations for AI analysis entityTypes, limit: 50, sortBy: 'relevance' as const, zone, informationNeeded, // This triggers AI filtering reason }; // Second search - get full entity details and use AI to filter by relevance const detailedSearchResults = await kgClient.userSearch(detailedSearchParams); const detailedEntities = detailedSearchResults.entities; const relations = detailedSearchResults.relations; // If no entities were found relevant, return the initial search results if (detailedEntities.length === 0) { // Rerun search without AI filtering but with a smaller limit const fallbackSearchParams = Object.assign({}, initialSearchParams, { limit: 10, includeObservations: true }); const fallbackSearchResults = await kgClient.userSearch(fallbackSearchParams); const fallbackEntities = fallbackSearchResults.entities; // Get relations for these entities const entityNames = fallbackEntities.map(e => e.name); const relationsResult = await kgClient.getRelationsForEntities(entityNames, zone); const relations = relationsResult.relations; // Format relations for response const formattedRelations = relations.map(r => ({ from: r.from, to: r.to, type: r.relationType, fromZone: r.fromZone, toZone: r.toZone })); return { entities: fallbackEntities, relations: formattedRelations, tentativeAnswer: "AI filtering did not find relevant entities. Returning top matching entities without filtering." }; } // Now use AI to generate a tentative answer based on the detailed entities and their relations const systemPrompt = `You are an intelligent knowledge graph analyzer. Your task is to analyze entities and their relations to provide a concise answer to the user's information needs. Base your answer ONLY on the information in the entities and relations provided.`; let userPrompt = `Information needed: ${informationNeeded}`; if (reason) { userPrompt += `\nContext/Reason: ${reason}`; } userPrompt += `\n\nHere are the relevant entities and their relations: Entities: ${JSON.stringify(detailedEntities, null, 2)} Relations: ${JSON.stringify(relations, null, 2)} Provide a concise, direct answer to the information needed based on these entities and relations. Be specific and detailed, but avoid unnecessary verbosity. Focus only on the information that directly answers the query.`; let tentativeAnswer = "Could not generate an AI answer based on the entities."; try { // Use AI to generate an answer tentativeAnswer = await GroqAI.chatCompletion({ system: systemPrompt, user: userPrompt }); } catch (error) { logger.error('Error getting AI-generated answer:', { error }); } // Return the final results return { entities: detailedEntities, relations, tentativeAnswer }; } catch (error) { logger.error('Error inspecting knowledge graph:', { error }); return { entities: [], relations: [], tentativeAnswer: `Error inspecting knowledge graph: ${error.message}` }; } }

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/j3k0/mcp-brain-tools'

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