Skip to main content
Version: 0.8.0

MCP Streamable HTTP Server

Introduced 0.8.0

The MCP server is exposed via the /_plugins/_ml/mcp endpoint and implements the Streamable HTTP transport defined by the Model Context Protocol (MCP). It allows agents or clients to connect to Lucenia and discover or invoke available tools.

important

This server does not open a persistent SSE connection with the client; all communication happens over stateless HTTP calls. If a client sends a GET request (typically, to establish an SSE connection), the server returns a 405 Method Not Allowed response.

Prerequisites

Before connecting to the MCP server, enable the MCP server functionality in your cluster:

PUT /_cluster/settings
{
"persistent": {
"plugins.ml_commons.mcp_server_enabled": "true"
}
}

You can also optionally register custom tools using the Register MCP Tools API.

Endpoint

POST /_plugins/_ml/mcp

Request format

The MCP server uses JSON-RPC 2.0 for communication. All requests should be sent as POST requests with a JSON body:

{
"jsonrpc": "2.0",
"id": "string|number",
"method": "string",
"params": {}
}

Request fields

FieldTypeDescriptionRequired
jsonrpcStringJSON-RPC version (must be "2.0")Yes
idString/NumberUnique identifier for the requestYes
methodStringMethod to invoke on the MCP serverYes
paramsObjectParameters for the method callNo

Supported methods

tools/list

List all available tools on the MCP server.

curl -X POST "https://localhost:9200/_plugins/_ml/mcp" \
-H "Content-Type: application/json" \
-H "Authorization: Basic $(echo -n 'username:password' | base64)" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}'

Example response

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "ListIndexTool",
"description": "Lists indices in the cluster",
"inputSchema": {
"type": "object",
"properties": {
"indices": {
"type": "array",
"description": "List of index names to filter"
}
}
}
},
{
"name": "SearchIndexTool",
"description": "Searches documents in an index",
"inputSchema": {
"type": "object",
"properties": {
"index": {
"type": "string",
"description": "Index name to search"
},
"query": {
"type": "object",
"description": "Search query"
}
},
"required": ["index"]
}
}
]
}
}

tools/call

Execute a specific tool with provided parameters.

curl -X POST "https://localhost:9200/_plugins/_ml/mcp" \
-H "Content-Type: application/json" \
-H "Authorization: Basic $(echo -n 'username:password' | base64)" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "ListIndexTool",
"arguments": {
"indices": []
}
}
}'

Example response

{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{
"type": "text",
"text": "health status index uuid pri rep docs.count docs.deleted store.size pri.store.size\nyellow open my-index abc123def456 1 1 5 0 10.2kb 10.2kb"
}
]
}
}

initialize

Initialize the MCP connection and get server capabilities.

curl -X POST "https://localhost:9200/_plugins/_ml/mcp" \
-H "Content-Type: application/json" \
-H "Authorization: Basic $(echo -n 'username:password' | base64)" \
-d '{
"jsonrpc": "2.0",
"id": 0,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"clientInfo": {
"name": "my-client",
"version": "1.0.0"
}
}
}'

Example response

{
"jsonrpc": "2.0",
"id": 0,
"result": {
"protocolVersion": "2024-11-05",
"serverInfo": {
"name": "Lucenia MCP Server",
"version": "0.8.0"
},
"capabilities": {
"tools": {}
}
}
}

Built-in tools

The MCP server provides several built-in tools that are available without registration:

Zero-configuration tools

These tools require no additional parameters during registration:

Tool NameDescription
ListIndexToolLists indices in the cluster
CatIndexToolReturns detailed index information
SearchIndexToolSearches documents in an index
GetMappingsToolRetrieves index mappings
GetSettingsToolRetrieves index settings

Parameterized tools

These tools require parameters to be provided during registration:

Tool NameDescriptionRequired Parameters
VectorSearchToolPerforms vector similarity searchmodel_id, embedding_field
RAGToolRetrieval-augmented generationmodel_id, index

Client examples

Python with fastmcp

You can connect to the MCP server using any client that supports the Streamable HTTP transport. The following example uses the fastmcp library:

import asyncio
from fastmcp import Client

async def main():
async with Client("http://localhost:9200/_plugins/_ml/mcp") as client:
# List available tools
tools = await client.list_tools()
for tool in tools:
print(f"Tool: {tool.name}")

# Call a tool
result = await client.call_tool("ListIndexTool", {"indices": []})
print("Result:", result)

asyncio.run(main())

Python with httpx

import httpx
import json

def call_mcp(method: str, params: dict = None):
payload = {
"jsonrpc": "2.0",
"id": 1,
"method": method
}
if params:
payload["params"] = params

response = httpx.post(
"http://localhost:9200/_plugins/_ml/mcp",
json=payload,
auth=("username", "password"),
headers={"Content-Type": "application/json"}
)
return response.json()

# List tools
tools = call_mcp("tools/list")
print("Available tools:", tools)

# Call a tool
result = call_mcp("tools/call", {
"name": "ListIndexTool",
"arguments": {"indices": []}
})
print("Result:", result)

JavaScript/Node.js

async function callMCP(method, params = {}) {
const response = await fetch('http://localhost:9200/_plugins/_ml/mcp', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + btoa('username:password')
},
body: JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: method,
params: params
})
});
return response.json();
}

// List tools
const tools = await callMCP('tools/list');
console.log('Available tools:', tools);

// Call a tool
const result = await callMCP('tools/call', {
name: 'ListIndexTool',
arguments: { indices: [] }
});
console.log('Result:', result);

JSON-RPC error codes

The MCP server uses standard JSON-RPC 2.0 error codes:

CodeMessageDescription
-32700Parse errorInvalid JSON in request
-32600Invalid RequestRequest is not a valid JSON-RPC object
-32601Method not foundRequested method does not exist
-32602Invalid paramsInvalid method parameters
-32603Internal errorServer internal error

Custom error codes

CodeMessageDescription
-32000Tool not foundRequested tool does not exist
-32001Tool execution failedTool execution encountered an error
-32002Authentication requiredRequest requires authentication

Best practices

  1. Use unique request IDs: Use descriptive, unique request IDs for easier debugging and correlation
  2. Handle errors gracefully: Implement comprehensive error handling for all JSON-RPC error codes
  3. Initialize first: Call the initialize method before using other methods to ensure compatibility
  4. Check tool availability: Use tools/list to verify tools are available before calling them
  5. Provide required arguments: Ensure all required arguments are provided when calling tools