Skip to content

Latest commit

 

History

History
210 lines (169 loc) · 7.38 KB

File metadata and controls

210 lines (169 loc) · 7.38 KB

Elasticsearch MCP Server

A comprehensive Model Context Protocol (MCP) server for Elasticsearch, written in Go. Provides 220 tools covering the entire Elasticsearch REST API surface, with YAML-configurable profiles to control which tools are exposed to AI clients.

Built for Elasticsearch 9.x. Tested against ES 9.3.0.

Features

  • 220 tools across 17 API domains -- full coverage of the Elasticsearch REST API
  • YAML profile system -- 4 built-in profiles (full, readonly, minimal, admin), easily create your own
  • Single binary -- ~10MB, no runtime dependencies
  • Stdio transport -- works with Claude Desktop, Claude Code, and any MCP-compatible client
  • Secure -- supports Basic auth, API key auth, and TLS with custom CA certificates
  • Structured errors -- extracts Elasticsearch error details (type, reason, root cause) into clean responses

Quick Start

Build

go build -o elasticsearch-mcp ./cmd/server

Run

Set your Elasticsearch connection via environment variables:

export ES_BASE_URL=http://localhost:9200
# Optional auth:
# export ES_USERNAME=elastic
# export ES_PASSWORD=changeme
# Or:
# export ES_API_KEY=your-base64-api-key

The server communicates over stdio (stdin/stdout) per the MCP protocol.

Claude Desktop Configuration

Add to your Claude Desktop claude_desktop_config.json:

{
  "mcpServers": {
    "elasticsearch": {
      "command": "/path/to/elasticsearch-mcp",
      "env": {
        "ES_BASE_URL": "http://localhost:9200",
        "ES_MCP_PROFILE": "full",
        "ES_MCP_CONFIG_DIR": "/path/to/config"
      }
    }
  }
}

Claude Code Configuration

Add to your .mcp.json:

{
  "mcpServers": {
    "elasticsearch": {
      "command": "/path/to/elasticsearch-mcp",
      "env": {
        "ES_BASE_URL": "http://localhost:9200",
        "ES_MCP_PROFILE": "readonly"
      }
    }
  }
}

Tool Coverage

API Domain Tools Examples
Documents 13 index, get, delete, update, bulk, reindex, mget, update/delete by query
Search 16 search, msearch, count, templates, scroll, PIT, field_caps, knn, explain
Indices 37 create, delete, mappings, settings, aliases, templates, shrink, split, clone, rollover, stats
Cluster & Nodes 17 health, state, stats, settings, allocation explain, reroute, nodes info/stats/hot_threads
Cat 24 indices, shards, nodes, health, aliases, allocation, thread_pool, ML jobs
Ingest 5 get/put/delete pipeline, simulate, grok patterns
Snapshot 10 repos, create/restore/delete snapshots, status, verify, cleanup
ILM 10 policies, explain, status, start/stop, retry, move to step
Data Streams 5 get, create, delete, stats, migrate
Security 39 users, roles, role mappings, privileges, API keys, tokens, SAML, OIDC, service tokens, cache
SQL 3 query, translate, clear cursor
EQL 4 search, async get/status/delete
Tasks 3 list, get, cancel
Scripts 5 get/put/delete, painless execute, languages
Transforms 10 get/put/delete, start/stop, preview, stats, reset, schedule, upgrade
Enrich 5 get/put/delete policy, execute, stats
Watcher 11 get/put/delete watch, execute, ack, activate/deactivate, stats, start/stop, query

Total: 220 tools

Profiles

Profiles control which tools are exposed to the MCP client. Set via ES_MCP_PROFILE environment variable.

Profile Enabled Description
full 220 All tools enabled (default)
readonly 114 Read-only operations -- no create, update, or delete
admin 194 Everything except destructive delete operations
minimal 17 Essential everyday tools only

Custom Profiles

Create a YAML file in config/profiles/:

# config/profiles/search-only.yaml
name: "search-only"
description: "Only search and read operations"
disable_unlisted: true

enable:
  - es_search
  - es_search_count
  - es_search_template
  - es_cat_indices
  - es_cluster_health

Profile fields:

  • enable_all: true -- start with all tools enabled
  • disable_unlisted: true -- start with all tools disabled, only enable listed ones
  • enable: [...] -- list of tool names to enable
  • disable: [...] -- list of tool names to disable (useful with enable_all)

Environment Variables

Variable Default Description
ES_BASE_URL http://localhost:9200 Elasticsearch endpoint URL
ES_USERNAME Basic auth username
ES_PASSWORD Basic auth password
ES_API_KEY API key (base64-encoded, alternative to basic auth)
ES_CA_CERT Path to custom CA certificate for TLS
ES_INSECURE false Skip TLS verification
ES_DEBUG false Enable debug logging
ES_MCP_PROFILE full Active profile name
ES_MCP_CONFIG_DIR (auto-detected) Path to config directory containing tools.yaml

Project Structure

.
├── cmd/server/
│   └── main.go              # Entry point, MCP server setup
├── api/
│   ├── registry.go           # Central registration of all API packages
│   ├── cat/                   # _cat API tools
│   ├── cluster/               # Cluster + Nodes API tools
│   ├── datastreams/           # Data Stream API tools
│   ├── documents/             # Document API tools
│   ├── enrich/                # Enrich API tools
│   ├── eql/                   # EQL API tools
│   ├── ilm/                   # ILM API tools
│   ├── indices/               # Index Management API tools
│   ├── ingest/                # Ingest Pipeline API tools
│   ├── scripts/               # Scripts API tools
│   ├── search/                # Search API tools
│   ├── security/              # Security API tools
│   ├── snapshot/              # Snapshot API tools
│   ├── sql/                   # SQL API tools
│   ├── tasks/                 # Tasks API tools
│   ├── transforms/            # Transforms API tools
│   └── watcher/               # Watcher API tools
├── internal/
│   ├── client/                # HTTP client for Elasticsearch
│   ├── config/                # Config loading (env vars + YAML)
│   └── registry/              # Thread-safe tool registry
├── config/
│   ├── tools.yaml             # Master tool definitions
│   └── profiles/
│       ├── full.yaml
│       ├── readonly.yaml
│       ├── minimal.yaml
│       └── admin.yaml
├── go.mod
└── go.sum

Architecture

Each API domain is a self-contained Go package under api/. Every package follows the same pattern:

type Package struct{ client *client.Client }

func (p *Package) Tools() []mcp.Tool        { /* tool definitions */ }
func (p *Package) Handlers() map[string]func { /* tool handlers */ }
func Register(reg *registry.Registry, c *client.Client) { /* registration */ }

The central api/registry.go imports all 17 packages and calls their Register() functions. The internal/registry provides thread-safe tool management with enable/disable filtering based on the active profile.

Requirements

  • Go 1.23+
  • Elasticsearch 8.x or 9.x

License

MIT