Elasticsearch MCP Server
Query Elasticsearch logs directly from Claude Cowork — with or without an SSH tunnel.
Installation
1. Install the plugin
Get es-mcp from the Cowork plugin marketplace and install it.
2. Install uv
The MCP server runs via uvx, which requires uv to be installed on your machine:
# Windows
powershell -ExecutionPolicy Bypass -c "irm https://astral.sh/uv/install.ps1 | iex"
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
3. Add the MCP entry to claude_desktop_config.json
Open the file at:
Windows: %APPDATA%\Claude\claude_desktop_config.json
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Add this minimal entry inside "mcpServers": { }:
{
"mcpServers": {
"elasticsearch-logs": {
"command": "uvx",
"args": ["artisan-es-reader-plugin@latest", "artisan-es-reader-plugin"]
}
}
}
That's it — no env vars needed.
4. Configure your profiles by asking Claude
Restart Cowork, then just ask Claude to add your Elasticsearch connections:
"Add a tealive_production profile — bastion is 43.216.208.205, pem is at ~/keys/prod.pem"
Claude will call configure_profile and save your settings to ~/.es-mcp/profiles.json
automatically. You can add as many profiles as you like this way.
5. Restart Cowork
The SSH tunnel starts automatically on first tool use.
How profiles are stored
Profiles are saved to ~/.es-mcp/profiles.json — a plain, human-readable JSON file
you can also edit directly if you prefer:
{
"default": "tealive_production",
"profiles": {
"tealive_production": {
"es_use_ssl": true,
"es_verify_certs": false,
"es_username": "your-username",
"es_password": "your-password",
"ssh_host": "43.216.208.205",
"ssh_username": "ubuntu",
"ssh_pem_file": "~/keys/prod.pem"
},
"baskbear": {
"es_use_ssl": true,
"es_verify_certs": false,
"ssh_host": "baskbear-bastion-ip",
"ssh_username": "ubuntu",
"ssh_pem_file": "~/keys/baskbear.pem"
}
}
}
Config priority order
The server looks for profiles in this order — the first match wins:
ES_PROFILESenv var (JSON string) — backward compat for existing usersES_PROFILES_FILEenv var — path to a custom JSON file~/.es-mcp/profiles.json— auto-discovered (written byconfigure_profile)- Legacy flat
ES_*/SSH_*env vars — single profile named "default"
Selecting a profile
Every tool accepts an optional profile argument. Just ask naturally:
"Search baskbear logs for payment errors" "Show recent errors in tealive production"
Omit it and the default profile is used. Call list_profiles to see what's
configured, or connection_info to inspect a specific one.
Per-profile settings reference
| Key | Description | Default |
|---|---|---|
es_host / es_port |
ES host/port for direct connections (ignored when ssh_host is set) |
localhost / 9200 |
es_username / es_password |
Elasticsearch credentials | empty |
es_use_ssl |
true if ES runs HTTPS |
false |
es_verify_certs |
false for self-signed certs |
false |
ssh_host |
Bastion / jump host IP or hostname. Leave unset for a direct connection | empty |
ssh_port / ssh_username |
SSH port / user | 22 / ubuntu |
ssh_pem_file |
Path to the PEM key on this machine (e.g. ~/keys/prod.pem) |
~/.ssh/id_rsa |
ssh_remote_es_host / ssh_remote_es_port |
ES host/port as seen from the bastion | localhost / 9200 |
ssh_local_port |
Local tunnel port (0 = auto) |
0 |
ssh_keepalive |
Seconds between SSH keepalive packets so idle tunnels aren't dropped (0 disables) |
30 |
Tunnel resilience
SSH tunnels are kept alive with periodic keepalive packets (ssh_keepalive,
30s by default) so the server's idle timeout doesn't drop them. If a tunnel is
dropped anyway, it is detected and automatically rebuilt on the next query —
no need to restart Claude.
Available tools
All tools accept an optional profile argument to choose the Elasticsearch source.
| Tool | What it does |
|---|---|
configure_profile |
Add or update a profile — saves to ~/.es-mcp/profiles.json |
delete_profile |
Remove a profile |
list_profiles |
List configured profiles and the default |
list_indices |
List indices (supports glob pattern) |
search_logs |
Full-text search with filters, sort, pagination |
get_recent_errors |
Error-level entries from the last N minutes |
get_index_mapping |
Field schema for an index |
run_aggregation |
Run a custom ES aggregation |
connection_info |
Show active connection / tunnel status |
Updating
For users
Updates are automatic — just restart Cowork and uvx will pull the latest version from PyPI.
For maintainers
- Make changes to
src/es_mcp/server.py - Bump the version in
pyproject.toml - Build and publish:
python -m build twine upload dist/*
- Users get the new version automatically on next Cowork restart — no action needed on their end
Metadata
Release files for artisan-es-reader-plugin 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| artisan_es_reader_plugin-0.6.0.tar.gz | 39.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| artisan_es_reader_plugin-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 49.0 kB
Release files / artisan_es_reader_plugin-0.6.0.tar.gz
| Download URL | artisan_es_reader_plugin-0.6.0.tar.gz |
|---|---|
| Size | 39.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
10c615abdb97bbdc99b096272448b2e9b558425753dae7bb4aab169ff0f84472
|
|
BLAKE2b-256 checksum How to use checksums |
aeb2a6f7a3d7bb1728ac497e6649dac7fe49b7523e5c4320ca49027645853d37
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Release files / artisan_es_reader_plugin-0.6.0-py3-none-any.whl
| Download URL | artisan_es_reader_plugin-0.6.0-py3-none-any.whl |
|---|---|
| Size | 10.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d57888ed8e335985f85e69176c3eff9ce31d28b55eca5f191bb76aadc1cc2215
|
|
BLAKE2b-256 checksum How to use checksums |
0d9b2a7ba95249c08789188977a9128a502a3b610ab76948390ee7476a982cc3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Security for artisan-es-reader-plugin 0.6.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.