Skip to main content
Glama
cyberbalsa

OpenSearch MCP Server

by cyberbalsa

getIndexMapping

Retrieve field mappings for a specified index in OpenSearch to analyze and understand data structure for effective querying and log analysis within the Wazuh security framework.

Instructions

Get the field mappings for an index

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
indexYesIndex name to inspect

Implementation Reference

  • index.js:244-304 (registration)
    Full registration of the 'getIndexMapping' tool using FastMCP server.addTool, including schema, description, and execute handler that queries OpenSearch for index mappings and formats them hierarchically.
    server.addTool({ name: "getIndexMapping", description: "Get the field mappings for an index", parameters: z.object({ index: z.string().describe("Index name to inspect"), }), execute: async (args, { log }) => { log.info("Getting index mapping", { index: args.index }); return safeOpenSearchQuery(async () => { const response = await client.indices.getMapping({ index: args.index, timeout: "20s" }); const mappings = response.body; if (!mappings) { return `No mappings found for index ${args.index}.`; } const indexName = Object.keys(mappings)[0]; const properties = mappings[indexName]?.mappings?.properties || {}; if (Object.keys(properties).length === 0) { return `No field mappings found for index ${args.index}.`; } let resultText = `## Field Mappings for ${args.index}\n\n`; function processProperties(props, prefix = '') { Object.entries(props).forEach(([field, details]) => { const fullPath = prefix ? `${prefix}.${field}` : field; if (details.type) { resultText += `- **${fullPath}**: ${details.type}`; if (details.fields) { resultText += ` (has multi-fields)`; } resultText += '\n'; } // Recursively process nested fields if (details.properties) { processProperties(details.properties, fullPath); } // Process multi-fields if (details.fields) { Object.entries(details.fields).forEach(([subField, subDetails]) => { resultText += ` - ${fullPath}.${subField}: ${subDetails.type}\n`; }); } }); } processProperties(properties); return resultText; }, `Failed to get mapping for index ${args.index}.`); }, });
  • The handler function that executes the tool: logs the action, uses safeOpenSearchQuery to call client.indices.getMapping, extracts properties, recursively processes nested and multi-fields, formats as markdown list, and returns the result.
    execute: async (args, { log }) => { log.info("Getting index mapping", { index: args.index }); return safeOpenSearchQuery(async () => { const response = await client.indices.getMapping({ index: args.index, timeout: "20s" }); const mappings = response.body; if (!mappings) { return `No mappings found for index ${args.index}.`; } const indexName = Object.keys(mappings)[0]; const properties = mappings[indexName]?.mappings?.properties || {}; if (Object.keys(properties).length === 0) { return `No field mappings found for index ${args.index}.`; } let resultText = `## Field Mappings for ${args.index}\n\n`; function processProperties(props, prefix = '') { Object.entries(props).forEach(([field, details]) => { const fullPath = prefix ? `${prefix}.${field}` : field; if (details.type) { resultText += `- **${fullPath}**: ${details.type}`; if (details.fields) { resultText += ` (has multi-fields)`; } resultText += '\n'; } // Recursively process nested fields if (details.properties) { processProperties(details.properties, fullPath); } // Process multi-fields if (details.fields) { Object.entries(details.fields).forEach(([subField, subDetails]) => { resultText += ` - ${fullPath}.${subField}: ${subDetails.type}\n`; }); } }); } processProperties(properties); return resultText; }, `Failed to get mapping for index ${args.index}.`); },
  • Zod input schema defining the required 'index' parameter as a string.
    parameters: z.object({ index: z.string().describe("Index name to inspect"), }),
  • Helper function used by getIndexMapping to safely execute OpenSearch queries with error handling and user-friendly error messages.
    async function safeOpenSearchQuery(operation, fallbackMessage) { try { debugLog('Executing OpenSearch query'); const result = await operation(); debugLog('OpenSearch query completed successfully'); return result; } catch (error) { console.error(`OpenSearch error: ${error.message}`, error); debugLog('OpenSearch query failed:', error); // Check for common OpenSearch errors if (error.message.includes('timeout')) { throw new UserError(`OpenSearch request timed out. The query may be too complex or the cluster is under heavy load.`); } else if (error.message.includes('connect')) { throw new UserError(`Cannot connect to OpenSearch. Please check your connection settings in .env file.`); } else if (error.message.includes('no such index')) { throw new UserError(`The specified index doesn't exist in OpenSearch.`); } else if (error.message.includes('unauthorized')) { throw new UserError(`Authentication failed with OpenSearch. Please check your credentials in .env file.`); } // For any other errors throw new UserError(fallbackMessage || `OpenSearch operation failed: ${error.message}`); } }

Other Tools

Related Tools

Latest Blog Posts

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/cyberbalsa/mcp-opensearch-js'

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