Skip to main content
Glama

Kibana MCP Server

by TocharianOU
resources.ts4.65 kB
import { z } from "zod"; import fs from 'fs'; import path from 'path'; import yaml from 'js-yaml'; import { fileURLToPath } from 'url'; import { dirname } from 'path'; import type { ServerBase, KibanaClient, ResourceResponse } from "./types"; // ESM-compatible __dirname const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // --- API index and search logic --- interface ApiEndpoint { path: string; method: string; description?: string; summary?: string; parameters?: any[]; requestBody?: any; responses?: any; deprecated?: boolean; tags?: string[]; } let apiEndpointIndex: ApiEndpoint[] = []; let isIndexBuilt = false; let YAML_FILE_PATH = ''; // Build the API index from the OpenAPI YAML file async function buildApiIndex(): Promise<void> { if (isIndexBuilt) return; // Only search for YAML file in the main directory const possiblePaths = [ path.join(process.cwd(), 'kibana-openapi-source.yaml') ]; for (const p of possiblePaths) { if (fs.existsSync(p)) { YAML_FILE_PATH = p; break; } } if (!YAML_FILE_PATH) { isIndexBuilt = true; return; } const yamlContent = fs.readFileSync(YAML_FILE_PATH, 'utf8'); const openApiDoc: any = yaml.load(yamlContent); if (!openApiDoc || !openApiDoc.paths) { isIndexBuilt = true; return; } for (const [pathStr, pathObj] of Object.entries(openApiDoc.paths)) { for (const [method, methodObj] of Object.entries(pathObj as Record<string, any>)) { if (["get", "post", "put", "delete", "patch"].includes(method)) { apiEndpointIndex.push({ path: pathStr as string, method: method.toUpperCase(), description: (methodObj as any).description, summary: (methodObj as any).summary, parameters: (methodObj as any).parameters, requestBody: (methodObj as any).requestBody, responses: (methodObj as any).responses, deprecated: (methodObj as any).deprecated, tags: (methodObj as any).tags }); } } } isIndexBuilt = true; } function searchApiEndpoints(query: string): ApiEndpoint[] { if (!isIndexBuilt) throw new Error('API index not built yet'); const q = query.toLowerCase(); return apiEndpointIndex.filter(e => e.path.toLowerCase().includes(q) || (e.description && e.description.toLowerCase().includes(q)) || (e.summary && e.summary.toLowerCase().includes(q)) || (e.tags && e.tags.some(tag => tag.toLowerCase().includes(q))) ); } export function registerResources(server: ServerBase, kibanaClient: KibanaClient, spaceName: string) { // 1. API path list resource server.resource( "kibana-api-paths", "kibana-api://paths", async (uri: URL, params: Record<string, string>): Promise<ResourceResponse> => { await buildApiIndex(); const search = params.search || ""; const endpoints = search ? searchApiEndpoints(search) : apiEndpointIndex; return { contents: [ { uri: uri.href, mimeType: "application/json", text: JSON.stringify({ space: spaceName, total_endpoints: endpoints.length, search_query: search || "all", endpoints: endpoints.map(e => ({ method: e.method, path: e.path, summary: e.summary, description: e.description })) }, null, 2) } ] }; } ); // 2. Single API endpoint detail resource server.resource( "kibana-api-path-detail", "kibana-api://path/{method}/{encoded_path}", async (uri: URL, params: Record<string, string>): Promise<ResourceResponse> => { await buildApiIndex(); const method = params.method?.toUpperCase(); const path = decodeURIComponent(params.encoded_path); const endpoint = apiEndpointIndex.find(e => e.method === method && e.path === path); if (!endpoint) { return { contents: [ { uri: uri.href, mimeType: "application/json", text: JSON.stringify({ space: spaceName, error: "API endpoint not found", requested: { method, path } }, null, 2) } ] }; } return { contents: [ { uri: uri.href, mimeType: "application/json", text: JSON.stringify({ space: spaceName, endpoint: endpoint }, null, 2) } ] }; } ); }

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/TocharianOU/mcp-server-kibana'

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