diff --git a/README.md b/README.md index d2ee32d..1f773b6 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ This server connects agents to your Elasticsearch data using the Model Context P * `list_indices`: List all available Elasticsearch indices * `get_mappings`: Get field mappings for a specific Elasticsearch index -* `search`: Perform an Elasticsearch search with the provided query DSL +* `search`: Perform an Elasticsearch search with the provided query DSL. Supports highlighting, query profiling, and query explanation. * `get_shards`: Get shard information for all or specific indices ## Prerequisites diff --git a/index.ts b/index.ts index a9b1497..3629502 100644 --- a/index.ts +++ b/index.ts @@ -313,10 +313,22 @@ export async function createElasticsearchMcpServer (config: ElasticsearchConfig) } ) .describe( - 'Complete Elasticsearch query DSL object that can include query, size, from, sort, etc.' - ) + "Complete Elasticsearch query DSL object that can include query, size, from, sort, etc." + ), + + profile: z + .boolean() + .optional() + .default(false) + .describe("Whether to include query profiling information"), + + explain: z + .boolean() + .optional() + .default(false) + .describe("Whether to include explanation of how the query was executed"), }, - async ({ index, queryBody }) => { + async ({ index, queryBody, profile, explain }) => { try { // Get mappings to identify text fields for highlighting const mappingResponse = await esClient.indices.getMapping({ @@ -327,8 +339,10 @@ export async function createElasticsearchMcpServer (config: ElasticsearchConfig) const searchRequest: estypes.SearchRequest = { index, - ...queryBody - } + ...queryBody, + profile, + explain, + }; // Always do highlighting if (indexMappings.properties != null) { @@ -374,6 +388,10 @@ export async function createElasticsearchMcpServer (config: ElasticsearchConfig) } } + if (explain && hit._explanation) { + content += `\nExplanation:\n${JSON.stringify(hit._explanation, null, 2)}` + } + return { type: 'text' as const, text: content.trim() @@ -396,6 +414,16 @@ export async function createElasticsearchMcpServer (config: ElasticsearchConfig) } : null + const fragments = [metadataFragment, ...contentFragments] + + if (profile && result.profile) { + const profileFragment = { + type: "text" as const, + text: `\nQuery Profile:\n${JSON.stringify(result.profile, null, 2)}`, + } + fragments.push(profileFragment) + } + return { content: (aggregationsFragment != null) ? [metadataFragment, aggregationsFragment, ...contentFragments] @@ -504,9 +532,9 @@ async function main (): Promise { // by requiring the stdio protocol (http will come later) if (process.env.RUNNING_IN_CONTAINER === "true") { if (process.argv.length != 3 || process.argv[2] !== "stdio" ) { - console.log("Missing protocol argument."); - console.log("Usage: npm start stdio"); - process.exit(1); + console.log("Missing protocol argument.") + console.log("Usage: npm start stdio") + process.exit(1) } }