Content
# Easysearch MCP Server
Easysearch MCP Server, based on Model Context Protocol (MCP) SDK implementation, provides 130+ tools covering full Easysearch functionality.
## Technology Stack
- Go 1.26.5
- github.com/elastic/go-elasticsearch/v7 v7.10.0
- github.com/modelcontextprotocol/go-sdk v1.4.1
- go.uber.org/zap v1.28.0
- github.com/spf13/cobra
- github.com/sony/gobreaker/v2
## Features
| Module | Number of Tools | Description |
|------|--------|------|
| Cluster Management | 8 | Health check, status view, setting update, shard allocation, routing reallocation |
| Index Management | 32 | Create/delete/mapping/setting/alias/clone/split/shrink/rollover/freeze/rebuild |
| Document Operations | 6 | Write/get/update/delete/batch/batch get |
| Basic Search | 5 | Keyword search/template search/count/multi search/field capabilities |
| Advanced Search | 5 | DSL search/aggregation/aggregation simplification/SQL query/KNN |
| Scroll Search | 3 | Scroll init/continue/clear |
| Monitoring CAT | 19 | Node/index/shard/thread pool/segment/recovery/plugin/snapshot/field/template/task |
| Node Management | 5 | Node info/stats/hot threads/usage stats |
| Snapshot Management | 7 | Repository CRUD/snapshot CRUD+restore |
| Snapshot Lifecycle | 4 | SLM policy CRUD+execution |
| Task Management | 3 | Task list/details/cancel |
| Ingest Pipeline | 4 | Pipeline CRUD+simulation |
| Index Lifecycle | 5 | ILM explain/status/enable/disable |
| Search Pipeline | 4 | Search pipeline CRUD + set index default pipeline |
| Vector Search | 5 | Embedding generation/vector search/semantic search (auto-vectorization)/hybrid search (RRF)/vectorization pipeline |
| Security Management | 11 | User CRUD/role CRUD/API Key CRUD+invalidation |
| Cross-Cluster Replication | 6 | Follow/pause/resume/unfollow/status/stats |
| Monitoring and Alerting | 7 | Watch CRUD+execution+acknowledgment |
| Data Transformation | 6 | Transform enable/disable+status+CRUD |
## Quick Start
### Configuration
Copy `config.yaml.example` to `config.yaml`:
```yaml
server:
url: http://localhost:9200
username: admin
password: your_password
verify_ssl: true
transport: http # stdio | http
host: 0.0.0.0
port: 8080
api_key: "" # HTTP mode API Key authentication (add Authorization: Bearer <api_key> in request header)
timeout: 30 # Request timeout (seconds)
log:
level: info
file_path: logs/easysearch-mcp.log
```
### Running
```bash
# Local compilation and execution
go build -o easysearch-mcp-server ./cmd/easysearch-mcp-server
./easysearch-mcp-server start -c config.yaml
# Or use cross-compilation to deploy to Linux server
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
go build -ldflags="-s -w" -o easysearch-mcp-server ./cmd/easysearch-mcp-server
```
### Command Line Subcommands
| Command | Description |
|------|------|
| `start` | Start MCP server |
| `check` | Check configuration file and Easysearch connectivity |
| `migrate` | Data migration tool (cross-cluster index migration, supports scroll+bulk and dry-run) |
| `version` | Display version information |
```bash
# Check configuration and connectivity
./easysearch-mcp-server check -c config.yaml
# Display version
./easysearch-mcp-server version
```
### Transport Mode
- **stdio**: Communicate with MCP client through standard input/output
- **http** (Streamable HTTP): Listen on `host:port`, support remote connection
### Authentication and Security
When `transport` is set to `http` or `sse`, API Key authentication can be enabled through `api_key` configuration:
```bash
curl -X POST http://localhost:8080 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your_api_key_here" \
-d '{"jsonrpc":"2.0","id":"1","method":"tools/call","params":{"name":"cluster_health"}}'
```
### Health Check
HTTP mode provides tiered health check endpoints:
```bash
# Full health check (includes Elasticsearch, memory, disk, goroutine checks)
curl http://localhost:8080/health
# Liveness probe
curl http://localhost:8080/health/live
# Readiness probe
curl http://localhost:8080/health/ready
```
### Docker Deployment
The project provides Dockerfile and docker-compose.yml:
```bash
# Build and start
docker compose up -d
# Build with specified version
VERSION=1.0.0 docker compose build
# Override configuration with environment variables
EASYSEARCH_URL=http://192.168.1.100:9200 \
OLLAMA_URL=http://192.168.1.100:11434/api/embeddings \
docker compose up -d
```
Environment Variables:
| Variable | Default Value | Description |
|------|--------|------|
| `EASYSEARCH_URL` | `http://host.docker.internal:9200` | Easysearch address |
| `EASYSEARCH_USERNAME` | Empty | ES username |
| `EASYSEARCH_PASSWORD` | Empty | ES password |
| `EASYSEARCH_TRANSPORT` | `http` | Transport mode |
| `OLLAMA_URL` | `http://host.docker.internal:11434/api/embeddings` | Ollama address |
| `OLLAMA_MODEL` | `bge-large-zh-v1.5` | Embedding model |
| `LOG_LEVEL` | `info` | Log level |
## Documentation
See detailed architecture description in [`docs/项目架构.md`](docs/项目架构.md).
## Vector Search Example
Call Easysearch vector search functionality through MCP tool.
### 1. Create Vector Index
Vector field type is `knn_dense_float_vector`, supporting LSH or exact model:
```json
{
"index": "my_vector_index",
"mappings": {
"properties": {
"title": { "type": "text" },
"content": { "type": "text" },
"content_vector": {
"type": "knn_dense_float_vector",
"knn": {
"dims": 1024,
"model": "lsh",
"similarity": "cosine",
"L": 99,
"k": 1
}
}
}
}
}
```
### 2. Generate Vector Embedding
Call Ollama to convert text to vector:
```
embedding_generate text="Vector search test" model="quentinz/bge-large-zh-v1.5:latest" \
url="http://192.168.1.87:11434/api/embeddings"
```
Return 1024-dimensional float array.
### 3. Vector Search
Use `knn_nearest_neighbors` query to sort by similarity:
```
vector_search index="my_vector_index" field="content_vector" \
query_text="Vector search test" size=10
```
Support `query_text` mode (automatically call Ollama to generate embedding), or directly pass `query_vector`. Optional parameters `model` (default lsh), `similarity` (default cosine), `candidates` (default size×10).
### 4. Hybrid Search (Vector + Full-text)
Use official Search Pipeline + `hybrid` query type + RRF (reciprocal rank fusion) to implement hybrid search.
**Step 1: Create Search Pipeline**
```json
{
"pipeline_id": "hybrid-pipeline",
"body": {
"rewrite_processors": [{
"semantic_query_enricher": {
"tag": "hybrid",
"url": "http://localhost:11434/v1/embeddings",
"vendor": "openai",
"api_key": "ollama",
"default_model_id": "quentinz/bge-large-zh-v1.5:latest",
"vector_field_model_id": { "content_vector": "quentinz/bge-large-zh-v1.5:latest" }
}
}],
"rerank_processors": [{
"hybrid_ranker_processor": {
"combination": { "technique": "rrf", "rank_constant": 60 }
}
}],
"enrich_processors": [{ "hybrid_score_explanation": {} }]
}
}
```
**Step 2: Set Index Default Pipeline**
```
search_pipeline_set_default index="my_vector_index" pipeline_id="hybrid-pipeline"
```
**Step 3: Execute Hybrid Search**
```
hybrid_search index="my_vector_index" query="Search keyword" \
vector_field="content_vector" \
text_fields=["title","content"] \
title_boost=2.0 content_boost=1.0
```
Optional parameters `pipeline_id` (use index default pipeline if not passed), `candidates` (default size×10), `query_strategy` (default LSH_COSINE).
### 5. Semantic Search (Text Auto-Vectorization)
Use `semantic` query type, query text is automatically converted to vector by pipeline's `semantic_query_enricher` service, no need for client to generate embedding:
```
semantic_search index="my_vector_index" query_text="Search keyword" \
vector_field="content_vector" size=10
```
Need to pre-create search pipeline with `semantic_query_enricher` and set as index default pipeline (see Section 4).
### 6. Auto-Vectorization Pipeline
Create Ingest Pipeline, automatically call external embedding service to generate vector when writing documents:
```
vector_pipeline_create pipeline_id="text_to_vector" \
url="http://192.168.1.87:11434/api/embeddings" \
vendor="ollama" model_id="quentinz/bge-large-zh-v1.5:latest" dims=1024
```
Then write documents only need to provide `content` field, Pipeline automatically fills `content_vector`.
## Integrate OpenCode
### Remote Mode
Configure `~/.config/opencode/opencode.json`:
```json
{
"mcp": {
"easysearch": {
"type": "remote",
"url": "http://<server>:8080"
}
}
}
```
### Local Mode
```json
{
"mcp": {
"easysearch": {
"type": "local",
"command": ["/path/to/easysearch-mcp-server"],
"env": {
"EASYSEARCH_URL": "http://localhost:9200",
"EASYSEARCH_USER": "admin",
"EASYSEARCH_PASSWORD": "your_password"
}
}
}
}
```
### Multi-Environment Configuration
Support loading configuration files by environment, priority: default < `config.yaml` < `config.{env}.yaml` < environment variables
```bash
# Specify environment through EASYSEARCH_ENV
export EASYSEARCH_ENV=production
./easysearch-mcp-server start -c config.yaml
# Automatically load config.production.yaml to override basic configuration
```
### API Documentation
After starting HTTP/SSE mode, access the following endpoints to view API documentation:
- `/docs` - Swagger UI interactive documentation
- `/openapi.json` - OpenAPI 3.0 specification
## Project Structure
```
cmd/easysearch-mcp-server/ Entrance(Cobra CLI)
├── main.go Root command
├── start.go start subcommand: Start service
├── check.go check subcommand: Configuration check
├── migrate.go migrate subcommand: Data migration
└── version.go version subcommand: Version information
internal/
├── api/ OpenAPI documentation generation
├── auth/ Authentication middleware(API Key/Basic/JWT/Mixed)
├── breaker/ Circuit breaker(gobreaker encapsulation)
├── cache/ Response caching
├── client/ Easysearch HTTP client
│ ├── client.go ESClient interface and implementation(Retry/Circuit breaker/Caching/Tracing)
│ └── mock_client.go Test mock
├── config/ Configuration loading(YAML + Environment variables + fsnotify hot reloading)
├── di/ Dependency injection container
├── health/ Health check(ES/Memory/Disk/Goroutine)
├── lifecycle/ Lifecycle manager(Ordered start and stop)
├── logger/ Log encapsulation(zap + lumberjack rotation)
├── metrics/ Prometheus metrics collection
├── middleware/ HTTP middleware chain
├── pool/ Goroutine pool
├── rate/ Token bucket rate limiting
├── security/ Security middleware(CORS / Host verification / Response header)
├── server/ HTTP server & MCP integration
│ └── server.go EasysearchMCPServer main structure
├── tools/ Tool implementation(19 modules)
│ ├── tools.go Module definition & AddToolWithMetrics
│ ├── register.go Module unified registration entry
│ ├── responses.go Unified response format ToolResponse
│ ├── ollama_client.go Ollama Embedding HTTP client
│ ├── cluster.go Cluster management(8 tools)
│ ├── indices.go Index management(32 tools)
│ ├── documents.go Document operation(6 tools)
│ ├── search_basic.go Basic search(5 tools)
│ ├── search_advanced.go Advanced search(5 tools)
│ ├── search_scroll.go Scroll search(3 tools)
│ ├── search_pipeline.go Search pipeline(4 tools)
│ ├── cat.go CAT API(19 tools)
│ ├── nodes.go Node management(5 tools)
│ ├── snapshot.go Snapshot management(7 tools)
│ ├── slm.go Snapshot lifecycle(4 tools)
│ ├── tasks.go Task management(3 tools)
│ ├── ingest.go Ingest Pipeline(4 tools)
│ ├── ilm.go Index lifecycle(5 tools)
│ ├── vector.go Vector search and hybrid search(5 tools)
│ ├── security.go Security management(11 tools)
│ ├── ccr.go Cross-cluster replication(6 tools)
│ ├── transform.go Data transformation(6 tools)
│ └── watch.go Monitoring and alerting(7 tools)
├── tracing/ Tracing(X-Trace-ID / X-Span-ID)
└── validator/ Request body size verification
docs/
├── Project Architecture.md Detailed architecture description
integration/ Integration test(End-to-end)
benchmark/ Performance benchmark test
```
## Development
```bash
go build ./...
go vet ./...
```
### Static Code Check
The project uses [golangci-lint](https://golangci-lint.run/) for static code analysis. The configuration file is located at `.golangci.yml`, and it enables various checkers such as errcheck, gosimple, govet, staticcheck, bodyclose, and revive.
```bash
# Install golangci-lint
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
# Run static check
golangci-lint run ./...
# Automatically fix fixable issues
golangci-lint run --fix ./...
```
### Testing
```bash
# Run all unit tests
go test ./...
# Run tests with coverage
go test ./internal/... -cover -count=1
# Run integration tests
go test ./integration/ -count=1
# Run benchmark tests
go test -bench=. -benchmem -run=^$ ./benchmark/
```
### Test Coverage
| Module | Coverage |
|------|--------|
| cache | 100% |
| pool | 98.3% |
| api | 97.8% |
| tracing | 97.6% |
| middleware | 92.3% |
| breaker | 90.9% |
| lifecycle | 90.4% |
| rate | 89.7% |
| metrics | 89.3% |
| security | 83.6% |
| health | 81.0% |
| config | 78.2% |
| logger | 67.3% |
| client | 65.9% |
| di | 61.7% |
| server | 26.5% |
| auth | 30.7% |
| validator | 14.1% |
| tools | 13.6% |
# Reference
https://github.com/cloudsmithy/easysearch-mcp-server
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available