Elastic MCP Server
Provides integration with the Elastic Stack to enable read-only log search, aggregation, and analysis across Elasticsearch and Kibana.
Allows searching and aggregating logs stored in Elasticsearch indices with support for filters, time ranges, and free-text queries.
Enables listing Kibana data views, querying logs through Kibana's API, and utilizing Kibana spaces for log analysis.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Elastic MCP Servershow me recent error logs from the last hour"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Elastic MCP Server
A Model Context Protocol (MCP) server that gives AI assistants read-only access to your Elasticsearch/Kibana logs. Ask questions in natural language and get answers backed by real log data.
Works with Claude Code, Claude Desktop, and any MCP-compatible client. Your project can be in any language — Python, Java, Go, Node.js, etc. This server runs independently.
How It Works
Your project (any language) elastic-mcp-server Kibana / Elasticsearch
┌───────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Claude Code or │ stdio │ │ HTTPS │ │
│ Claude Desktop │────MCP──>│ Translates to │────────->│ Executes query │
│ │<─────────│ Kibana queries │<─────────│ Returns results │
└───────────────────┘ └──────────────────┘ └──────────────────┘The server runs as a standalone Node.js process alongside your project. Claude spawns it, communicates via stdio, and uses it to search your logs. It doesn't depend on your project's language, framework, or build system. All requests are read-only.
Related MCP server: Graylog MCP Server
Requirements
Node.js >= 18 or Docker (only for running this MCP server — your project can use any language)
Quick Start
Option A: Node.js
1. Clone and build
git clone https://github.com/vanovarderesyan/elastic-mcp-server.git
cd elastic-mcp-server
npm install
npm run buildThis creates the compiled server at dist/main.js.
2. Configure
Add the MCP server to your AI assistant. You need:
The absolute path to
dist/main.jswhere you cloned this repoYour Kibana URL and credentials
Claude Code — create or edit .mcp.json in any project directory:
{
"mcpServers": {
"elasticsearch": {
"command": "node",
"args": ["/home/john/elastic-mcp-server/dist/main.js"],
"env": {
"ELASTIC_NODES": "https://kibana.example.com",
"ELASTIC_USERNAME": "your-username",
"ELASTIC_PASSWORD": "your-password"
}
}
}
}Claude Desktop — edit the config file:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"elasticsearch": {
"command": "node",
"args": ["/home/john/elastic-mcp-server/dist/main.js"],
"env": {
"ELASTIC_NODES": "https://kibana.example.com",
"ELASTIC_USERNAME": "your-username",
"ELASTIC_PASSWORD": "your-password"
}
}
}
}Note: Replace
/home/john/elastic-mcp-serverwith the actual path where you cloned this repo.
Option B: Docker
No Node.js required — just Docker.
1. Build the image
git clone https://github.com/vanovarderesyan/elastic-mcp-server.git
cd elastic-mcp-server
docker build -t elastic-mcp-server .2. Configure
Claude Code — create or edit .mcp.json:
{
"mcpServers": {
"elasticsearch": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "ELASTIC_NODES=https://kibana.example.com",
"-e", "ELASTIC_USERNAME=your-username",
"-e", "ELASTIC_PASSWORD=your-password",
"elastic-mcp-server"
]
}
}
}Claude Desktop — same structure in your claude_desktop_config.json.
Why
-iand no-t? MCP communicates over stdin/stdout using structured JSON. The-iflag keeps stdin open for the MCP protocol. The-tflag (TTY) is not needed and would interfere with the JSON stream.
Cloudflare Zero Trust with Docker
If your Kibana is behind Cloudflare Access, the container needs access to your host's Cloudflare tokens. Mount the ~/.cloudflared directory as a read-only volume:
{
"mcpServers": {
"elasticsearch": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-v", "/home/john/.cloudflared:/root/.cloudflared:ro",
"-e", "ELASTIC_NODES=https://kibana.example.com",
"-e", "ELASTIC_USERNAME=your-username",
"-e", "ELASTIC_PASSWORD=your-password",
"elastic-mcp-server"
]
}
}
}Replace /home/john/.cloudflared with your actual home directory path (e.g., /Users/jane/.cloudflared on macOS).
You must authenticate on your host machine first:
cloudflared access login https://kibana.example.comThe container reads the cached token from the mounted volume. When the token expires, re-run cloudflared access login on your host — the container picks up the new token automatically.
Alternatively, pass a token directly via environment variable:
"-e", "CF_ACCESS_TOKEN=eyJhbGciOi..."3. Discover your indices
Every Elasticsearch setup is different. Your indices might be named filebeat-*, logstash-*, production-api-*, staging-*, or something else entirely. The first thing to do after setup is ask Claude to list what's available:
List all data viewsThis shows you the actual index patterns in your Kibana. Use those names when searching.
Important: By default, the
indexparameter is*, which searches all environments (production, staging, dev, etc.). Always specify the index when searching to avoid mixing logs from different environments:
Search for errors in production-api-* from the last hour
Show me logs from staging-auth-service-* today
Find "timeout" errors in filebeat-production-*4. Start asking questions
Show me errors in production-* from the last hour
What are the top 10 services by log volume today in production-*?
Find logs containing "connection refused" in staging-*
Show error trends over the past 24 hours in filebeat-*
What fields are available in the logs-nginx-* index?Tip: If you're not sure which index to use, just ask Claude — it will use the
list_data_viewstool to find the right one.
Tools
The server exposes 7 read-only tools:
search_logs
Search logs with filters, time ranges, and free-text queries.
Parameter | Type | Default | Description |
| string |
| Index pattern (e.g., |
| string | Free-text query (Lucene syntax) | |
| string | Filter by | |
| string | Start time ( | |
| string | End time ( | |
| object | Key-value field filters (e.g., | |
| string | Log level inside JSON message ( | |
| string | Phrase search within message field | |
| boolean |
| Exclude health/readiness probe logs |
| number |
| Max results to return |
|
|
| Sort order by timestamp |
aggregate_logs
Run aggregations for analytics and trend analysis.
Parameter | Type | Default | Description |
| string |
| Index pattern |
| enum |
| |
| string | Field to aggregate on | |
| string | Filter by service name | |
| string | Time range | |
| string |
| Interval for |
| string | Free-text filter | |
| string | Phrase search in message | |
| object | Key-value field filters |
list_indices
List available data views filtered by pattern.
Parameter | Type | Default | Description |
| string |
| Glob-style filter (e.g., |
list_data_views
List all Kibana data views (index patterns). No parameters.
get_mapping
Get field names, types, and whether they are aggregatable for an index.
Parameter | Type | Description |
| string | Index pattern (e.g., |
get_document
Fetch a single document by its Elasticsearch ID.
Parameter | Type | Description |
| string | Index name or pattern |
| string | Document ID |
cluster_health
Check Kibana connectivity and list sample data views. No parameters.
Configuration
All configuration is via environment variables in the env block of your MCP config.
Variable | Required | Default | Description |
| Yes | Kibana base URL (e.g., | |
| No | Basic auth username | |
| No | Basic auth password | |
| No | auto | Cloudflare Access JWT (see below) |
| No |
| Kibana space name |
| No |
| Set |
| No |
| Request timeout in milliseconds |
| No |
| Maximum number of search results |
| No | (all) | Comma-separated allowlist of |
Index Patterns
The index parameter in search and aggregation tools accepts Elasticsearch index patterns. These depend on your setup. Common examples:
Setup | Typical Pattern | Example |
Filebeat |
|
|
Logstash |
|
|
Fluentd/Fluent Bit |
|
|
Data streams |
|
|
Custom per-env |
|
|
Use the list_data_views tool to see what's available in your Kibana, or ask Claude: "What indices do we have?"
Service Allowlist
Restrict which Kubernetes services can be queried by setting ALLOWED_SERVICES:
"ALLOWED_SERVICES": "api-gateway,auth-service,payment-service"When empty or unset, all services are accessible.
Authentication
Basic Auth
Set ELASTIC_USERNAME and ELASTIC_PASSWORD in the env block. These are sent as a standard HTTP Basic auth header on every request.
Cloudflare Zero Trust (optional)
If your Kibana is behind Cloudflare Zero Trust (formerly Cloudflare Access), the server handles token management automatically. No extra configuration is needed beyond the initial login.
How it works
When the server starts, it looks for a Cloudflare Access JWT to include as a cf-access-token header on every request to Kibana. The token resolution order is:
Read from
~/.cloudflared/cache —cloudflaredstores tokens as files named<hostname>-<audience>-tokenafter a successful loginAuto-refresh via
cloudflared access login— if the cached token is expired or missing, the server runscloudflared access login <url>which opens a browser for authentication (Node.js only, not in Docker)Fall back to
CF_ACCESS_TOKENenv var — if the above steps fail, the server uses the token from the environment variableRetry on 401/403 — if a request fails with an auth error, the server re-reads the token from disk and retries once (handles cases where the token was refreshed externally)
Prerequisites
Install cloudflared:
# macOS
brew install cloudflared
# Linux (Debian/Ubuntu)
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflare-main $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflare-main.list
sudo apt update && sudo apt install cloudflaredFirst-time setup
cloudflared access login https://your-kibana-url.comA browser window opens for authentication. After completing the login, a JWT is cached in ~/.cloudflared/. The server reads this automatically — no need to copy tokens manually.
Token lifecycle
Scenario | What happens |
Token valid | Used automatically from |
Token expired | Server runs |
Token expired (Docker) | Browser can't open — re-run |
Manual token | Set |
Request gets 401/403 | Server re-reads token from disk and retries once |
Docker considerations
Docker containers can't open a browser for interactive Cloudflare login. Two options:
Option 1: Mount the host's token cache (recommended)
"-v", "/home/john/.cloudflared:/root/.cloudflared:ro"The container reads your host's cached tokens. When they expire, re-run cloudflared access login on your host machine — the container sees the updated token immediately via the mounted volume.
Option 2: Pass token via environment variable
"-e", "CF_ACCESS_TOKEN=eyJhbGciOi..."Obtain a token manually (cloudflared access login, then read the file from ~/.cloudflared/) and pass it directly. Note: this token will eventually expire and you'll need to update it.
Not using Cloudflare?
If your Kibana is not behind Cloudflare Zero Trust, you can ignore all of the above. The server will skip Cloudflare authentication entirely when no token is found and cloudflared is not installed.
Project Structure
src/
main.ts # Entry point — registers tools and starts stdio transport
kibana-client.ts # Kibana HTTP client with auth and retry logic
cf-token.ts # Cloudflare Access token auto-management
allowed-services.ts # Service allowlist filtering
utils/
format-response.ts # Response truncation and formatting
tools/
search-logs.tool.ts # search_logs
aggregate-logs.tool.ts # aggregate_logs
list-indices.tool.ts # list_indices
list-data-views.tool.ts # list_data_views
get-mapping.tool.ts # get_mapping
get-document.tool.ts # get_document
cluster-health.tool.ts # cluster_healthLicense
MIT
Available Tools
7 toolsaggregate_logsA
Run aggregations on logs: terms (top values), date_histogram (trends over time), stats (min/max/avg), count. Supports service filtering.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | End time, e.g., "now" | |
| from | No | Start time, e.g., "now-1h" | |
| field | Yes | Field to aggregate on | |
| index | No | Index pattern, e.g., "logs-*", "filebeat-*" | * |
| query | No | Free text query string (Lucene syntax) | |
| aggType | Yes | Aggregation type | |
| filters | No | Key-value field filters | |
| service | No | Filter by kubernetes.container.name, e.g., "my-service" | |
| interval | No | Interval for date_histogram, e.g., "1h", "1d" | 1h |
| timeField | No | Timestamp field name | @timestamp |
| messageQuery | No | Search text within the message field (match_phrase) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It only says 'Run aggregations' and does not state that the operation is read-only, that it returns aggregated buckets rather than raw documents, or any permission/time-range constraints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero filler. The core capability and aggregation types are front-loaded, and the service-filtering note is a useful secondary detail. Every phrase earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter tool with no annotations and no output schema, the description is thin: it does not describe the return shape, default index behavior, or how it relates to search_logs. The schema documents parameters well, but non-parameter context (output, safety, usage boundaries) is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, which sets a baseline of 3, but the description adds real value by explaining the aggType enum semantics: terms=top values, date_histogram=trends over time, stats=min/max/avg. It also highlights the service filtering parameter, which is one of many schema fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Run aggregations on logs') and enumerates four aggregation types with intuitive glosses (top values, trends over time, min/max/avg). This clearly distinguishes it from sibling tools like search_logs (raw retrieval) and list_indices/get_mapping (metadata).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage through phrases like 'trends over time' and 'top values', which hint at analytical use cases. However, it never explicitly says when to use this tool instead of search_logs, nor does it name alternatives or exclusion conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cluster_healthB
Check Kibana connectivity and list available data views as a health check.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It only states the actions taken and does not mention read-only behavior, return format, failure modes, or any side effects. Some of this is predictable for a health check, but it is not described.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single clear sentence with no filler. The key action and resource are front-loaded and every word contributes meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool this is relatively complete, but there is no output schema and no mention of what the health check actually returns. The overlap with list_data_views also leaves a gap in context that could confuse an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and schema description coverage is 100%, so the baseline is 4. There is no parameter information missing from the description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's actions: checking Kibana connectivity and listing available data views. However, it overlaps with the sibling tool list_data_views and the name 'cluster_health' suggests cluster status rather than Kibana connectivity, so sibling differentiation is missing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'as a health check' implies when to use this tool, but there is no explicit guidance on when to choose it over list_data_views or other siblings. No exclusions or alternative routing are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_documentB
Fetch a single document by its ID. Searches across the given index pattern.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Document ID | |
| index | Yes | Index name or pattern |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the core operation but does not describe what happens when the document is not found, whether an index pattern can match multiple indices, or what the response format is.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences with no redundancy or filler. It front-loads the primary purpose and adds one useful contextual clause about index patterns.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with only two fully documented parameters, but with no output schema or annotations, the description still leaves gaps around return values and error behavior. It is adequate for a basic fetch operation but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters. The description adds no meaningful parameter detail beyond what the schema provides; 'given index pattern' simply restates the existing schema description for index.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool fetches a single document by ID, which is a specific operation on a specific resource. It distinguishes itself from search_logs and get_mapping by focusing on a single document retrieval, though it does not explicitly name or contrast sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies this tool should be used when a document ID is known, but it provides no explicit guidance about when to choose this tool over search_logs or other siblings. There are no exclusions, prerequisites, or alternative tool references.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_mappingA
Get field names and types for an index pattern via Kibana. Shows field names, types, and whether they are searchable/aggregatable.
| Name | Required | Description | Default |
|---|---|---|---|
| index | Yes | Index pattern, e.g., "logs-my-service*" or "filebeat-*" |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral disclosure burden. It semantically implies a read-only operation through 'Get' and 'Shows' and explains the returned information. However, it doesn't explicitly state that no changes occur or how invalid index patterns are handled, which would add useful transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with no filler. The primary action and output are front-loaded, and every clause adds relevant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter read tool with no output schema, the description adequately explains the purpose and the kind of data returned. It doesn't detail response structure or error behavior, but those are minor gaps given the simplicity of the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents the 'index' parameter with an example. The description reinforces that it applies to an index pattern but adds no new parameter-level meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states a specific verb ('Get') and resource ('field names and types for an index pattern'), and clarifies the output includes searchability/aggregatability flags. This clearly distinguishes it from siblings like list_indices and list_data_views.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes the use case clear: when an agent needs index pattern field mappings, types, and search/aggregation metadata. It doesn't explicitly name alternatives or exclusion conditions, but the context is strong enough for an agent to select it appropriately.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_data_viewsA
List Kibana data views (index patterns). Shows all available log sources with their index patterns and names.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the behavioral burden. It discloses that this is a non-mutating listing operation and describes the informational content returned. It does not discuss pagination or access requirements, but the scope is simple enough that 'List' and 'Shows' provide adequate transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences with no filler. The core action and resource are front-loaded, and the second sentence adds the only useful output detail without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter list operation with no output schema, the description fully covers what the tool does, what it returns (index patterns and names), and enough context to choose it. There are no missing fields or expected inputs that an agent would need to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero parameters, so the baseline is 4. The description does not need to clarify parameter semantics because there are none to document; the empty schema already conveys that the tool takes no input.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') with a clear resource ('Kibana data views (index patterns)') and states what the tool exposes: all available log sources with their index patterns and names. This is unambiguous and distinguishes it from sibling list_indices by naming the Kibana-specific resource.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool: when you need to see Kibana data views or available log sources. However, it does not explicitly compare to the sibling list_indices tool or state when one should choose data views over raw index listing, leaving some routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_indicesA
List available indices by searching Kibana data views. Filter by pattern to find specific service logs.
| Name | Required | Description | Default |
|---|---|---|---|
| pattern | No | Filter pattern, e.g., "logs-*" or "filebeat-*" | * |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden of behavioral disclosure. It explains the mechanism ('searching Kibana data views') and filtering behavior, which is useful, but it does not mention what the returned list contains, how pattern matching works beyond the schema examples, or any permissions or side effects. For a read-only listing tool this is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description consists of two tight sentences that front-load the core function and then clarify the filtering use case. There is no filler, repetition, or unnecessary detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one optional parameter and no output schema, the description covers the core behavior and typical usage well. It does not explicitly describe the return format, but 'List available indices' strongly implies an enumeration of indices, and the sibling tool list makes the context reasonably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%; the schema already documents the pattern parameter with defaults and examples. The description adds the intended use ('find specific service logs') but no new technical detail, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb and resource: 'List available indices by searching Kibana data views.' It also gives a concrete use case ('Filter by pattern to find specific service logs') and is distinguishable from the sibling tool list_data_views, which targets data views themselves rather than indices.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool (when you need to find indices via Kibana data views, especially for service logs), but it does not explicitly contrast it with alternatives such as list_data_views, search_logs, or get_mapping. No when-not-to-use guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_logsB
Search logs via Kibana with filters and time ranges. Supports service filtering by kubernetes.container.name, free-text queries, and field filters.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | End time, e.g., "now" | |
| from | No | Start time, e.g., "now-1h" or "2026-04-07T10:00:00Z" | |
| size | No | Max results (default 50) | |
| sort | No | Sort order on time field | desc |
| index | No | Index pattern, e.g., "logs-*", "filebeat-*", or "production-my-service*" | * |
| query | No | Free text query string (Lucene syntax). Searches the message field. | |
| filters | No | Key-value field filters, e.g., {"level": "error"}. For JSON log level inside message, use messageLevel instead. | |
| service | No | Filter by kubernetes.container.name, e.g., "my-service" | |
| timeField | No | Timestamp field name | @timestamp |
| messageLevel | No | Filter by log level inside JSON message field, e.g., "error", "warn", "info" | |
| messageQuery | No | Search text within the message field (match_phrase), e.g., "Too Many Requests" or "Error syncing" | |
| excludeHealthChecks | No | Exclude health/liveness/readiness check logs |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full burden. It does not state whether this operation is read-only, what kind of results are returned, how pagination works, or any limits or side effects. The phrase 'Search logs' implies a read operation, but important behavioral details like result format and result limits are missing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, tightly written sentence that front-loads the core action and then lists supported capabilities without redundancy. Every phrase earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 12 parameters, no annotations, and no output schema, the description leaves important gaps: it does not specify what the tool returns (e.g., raw log entries), how to interpret results, or how to distinguish it from aggregate_logs. For a high-complexity tool, this level of context is insufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema documents every parameter. The description only summarizes the filter options (service, free-text, field filters) without adding new semantic detail beyond what the schema already provides. It meets the baseline but does not elevate it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: searching logs via Kibana with filters and time ranges. It distinguishes itself from sibling tools like list_indices and aggregate_logs by focusing on log search rather than listing, mapping, or aggregation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The usage is implied through the description of filtering and time-range capabilities, but there is no explicit guidance on when to choose this tool over aggregate_logs or get_document. No alternatives or exclusions are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
7 tool updates
v1.0.0- First observed
aggregate_logs - First observed
cluster_health - First observed
get_document - First observed
get_mapping - First observed
list_data_views - First observed
list_indices - First observed
search_logs
TDQS
Scored across 7 tools
Most tools have clear, distinct roles, but list_indices, list_data_views, and cluster_health all surface data-view/index information and could be confused during discovery. The remaining search, aggregate, mapping, and document tools are well separated.
The tool names mostly follow a predictable verb_noun pattern: list_*, get_*, search_*, and aggregate_*. cluster_health is the main outlier, since it reads as a noun phrase rather than an imperative action like the others.
Seven tools is a reasonable size for a focused Kibana/Elasticsearch log server. The count is slightly higher than necessary because listing functionality is split across multiple overlapping tools.
The toolset covers the full log-exploration workflow: discover data sources, inspect mappings, search logs, aggregate logs, and fetch individual documents. Health checking is also present, so agents can verify connectivity without hitting a dead end.
Related MCP Connectors
Search your AI chat history (ChatGPT, Claude, Codex) from any MCP client. Remote, private, read-only
MCP server for AI dialogue using various LLM models via AceDataCloud
Official Microsoft MCP Server to query Microsoft Entra data using natural language
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceA read-only MCP server that exposes Quickwit log search and aggregations to LLM clients, enabling natural language log investigation.Apache 2.0
- AlicenseAqualityDmaintenanceAn MCP server that gives AI assistants direct access to your Graylog logs -- search, aggregate, analyze, and cluster log data through natural language.2316 npmMIT
- AlicenseAqualityBmaintenanceA read-only MCP server that enables AI assistants to search, aggregate, and explore OpenSearch log data through 12 tools for connectivity, index discovery, search, and aggregations.17MIT
- AlicenseNot gradedqualityCmaintenanceA Python MCP server that provides AI agents with a controlled, read-first interface to Elasticsearch, Kibana Security, Fleet, and Elastic Defend.MIT