Connect an AI agent to your OpenSearch cluster
OpenSearch ships its own MCP server inside the ML Commons plugin. Turning it on lets an agent search your indices, read mappings and run PPL against the data in the cluster, rather than being handed a query language and left to construct HTTP calls itself.
It is present on every OpenSearch version ClusterNest offers (3.0.0 and later), and it is off by default. Two API calls turn it on.
This is a different server from the one in Connect an AI Agent via MCP. That one is the ClusterNest control plane: it creates clusters, rotates credentials and reads invoices. This one lives inside a single cluster and works on the data in it. They are complementary, and an agent can hold both connections at once.
1. Enable the server
Use your cluster's admin credentials:
curl -X PUT https://opensearch.awesome-enterprise.org/_cluster/settings \
-u "admin:$OPENSEARCH_PASSWORD" \
-H "Content-Type: application/json" \
-d '{"persistent": {"plugins.ml_commons.mcp_server_enabled": true}}'
The setting is persistent, so it survives restarts and version upgrades.
2. Register the tools it should expose
Nothing is exposed until you register it. Each entry is an ML Commons tool type, optionally with an input schema describing its parameters to the model:
curl -X POST https://opensearch.awesome-enterprise.org/_plugins/_ml/mcp/tools/_register \
-u "admin:$OPENSEARCH_PASSWORD" \
-H "Content-Type: application/json" \
-d '{
"tools": [
{ "type": "ListIndexTool" },
{ "type": "IndexMappingTool" },
{
"type": "SearchIndexTool",
"name": "SearchOsIndex",
"description": "Search an OpenSearch index by DSL query. Params: index (index name), query (DSL query object).",
"attributes": {
"input_schema": {
"type": "object",
"properties": {
"index": { "type": "string", "description": "The index to search" },
"query": { "type": "object", "description": "OpenSearch DSL query" }
},
"required": ["index", "query"]
}
}
}
]
}'
type is the only required field; name defaults to the type. Other tool types worth registering
depending on what the cluster is used for: PPLTool, SearchAlertsTool, SearchMonitorsTool,
SearchAnomalyDetectorsTool, SearchAnomalyResultsTool.
Check what is registered with:
curl https://opensearch.awesome-enterprise.org/_plugins/_ml/mcp/tools/_list \
-u "admin:$OPENSEARCH_PASSWORD"
Registered tools are stored in a system index and synced to every node from OpenSearch 3.1.0, so
this is a one-time call rather than something to repeat per node or after a restart. Registration is
not idempotent: re-registering a name that already exists is rejected, so list first if you are
scripting it. POST /_plugins/_ml/mcp/tools/_remove takes a list of names back off again.
3. Point a client at it
The endpoint depends on the cluster's version:
| Version | Transport | Endpoint |
|---|---|---|
| 3.3.0 and later | Streamable HTTP | https://opensearch.awesome-enterprise.org/_plugins/_ml/mcp |
| 3.0.0 to 3.2.0 | SSE | https://opensearch.awesome-enterprise.org/_plugins/_ml/mcp/sse |
Authentication is the cluster's own, so the client needs an Authorization header carrying HTTP
basic credentials. In Claude Code:
claude mcp add --transport http --scope user \
--header "Authorization: Basic $(printf 'admin:%s' "$OPENSEARCH_PASSWORD" | base64)" \
production-logs https://opensearch.awesome-enterprise.org/_plugins/_ml/mcp
Other clients take the same URL and header in their own config format.
Two things to get right before this works from a laptop or a CI runner:
- The IP allowlist. Whatever runs the agent has to be inside the cluster's
opensearch_whitelist. A local agent means your own address, and an agent running somewhere else means that host's address. - The user the agent connects as. The tools run with exactly the permissions of those
credentials.
admingives an agent the whole cluster, deletes included. For anything beyond trying it out, create an internal user with a read-only role over the indices it should see and connect with that instead.