This plugin transforms Fess (Enterprise Search Server) into a Model Context Protocol (MCP) server, enabling JSON-RPC 2.0 based interactions with Fess's search capabilities. The MCP API provides a standardized interface for executing search operations, retrieving index statistics, and accessing system information.
This project is a work in progress. Features, APIs, and documentation may evolve as development continues. Contributions and feedback are welcome.
See Maven Repository.
- Download the plugin JAR from the Maven Repository
- Place it in your Fess plugin directory
- Restart Fess
For detailed instructions, see the Plugin Administration Guide.
- JSON-RPC 2.0 Compliance: Fully compliant with JSON-RPC 2.0 specification
- MCP Protocol Support: Implements MCP protocol version 2024-11-05
- Search Tools: Execute full-text search queries with advanced filtering
- Index Statistics: Retrieve index and system information
- Resources: Access to Fess index statistics and configuration
- Prompts: Pre-defined search templates for common use cases
- Extensible Architecture: Easy to add new tools and capabilities
The MCP API is available at:
POST http://<fess-server>:<port>/mcp
All requests must be sent as JSON-RPC 2.0 formatted POST requests.
Initialize the MCP session and retrieve server capabilities.
Request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {}
}Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {},
"resources": {},
"prompts": {}
},
"serverInfo": {
"name": "fess-mcp-server",
"version": "1.0.0"
}
}
}List all available tools.
Request:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}Response:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"tools": [
{
"name": "search",
"description": "Search documents via Fess",
"inputSchema": {
"type": "object",
"properties": {
"q": {
"type": "string",
"description": "query string"
},
"num": {
"type": "integer",
"description": "number of results"
},
"start": {
"type": "integer",
"description": "start position"
},
"sort": {
"type": "string",
"description": "sort order"
}
},
"required": ["q"]
}
},
{
"name": "get_index_stats",
"description": "Get index statistics and information",
"inputSchema": {
"type": "object",
"properties": {}
}
}
]
}
}Execute a specific tool.
Request (Search):
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "search",
"arguments": {
"q": "elasticsearch",
"num": 10,
"start": 0
}
}
}Response:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "**Title**: Introduction to Elasticsearch\n**URL**: https://example.com/elasticsearch-intro\n**Score**: 1.234\n\nElasticsearch is a distributed, RESTful search and analytics engine..."
},
{
"type": "text",
"text": "**Title**: Elasticsearch Tutorial\n**URL**: https://example.com/es-tutorial\n**Score**: 1.123\n\nLearn how to use Elasticsearch for full-text search..."
}
]
}
}Request (Index Stats):
{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "get_index_stats",
"arguments": {}
}
}List available resources.
Request:
{
"jsonrpc": "2.0",
"id": 5,
"method": "resources/list",
"params": {}
}Response:
{
"jsonrpc": "2.0",
"id": 5,
"result": {
"resources": [
{
"uri": "fess://index/stats",
"name": "Index Statistics",
"description": "Fess index statistics and configuration information",
"mimeType": "application/json"
}
]
}
}Read a specific resource by URI.
Request:
{
"jsonrpc": "2.0",
"id": 6,
"method": "resources/read",
"params": {
"uri": "fess://index/stats"
}
}Response:
{
"jsonrpc": "2.0",
"id": 6,
"result": {
"contents": [
{
"uri": "fess://index/stats",
"mimeType": "application/json",
"text": "{\"index_name\":\"fess.search\",\"document_count\":1234,\"store_size\":\"10mb\",...}"
}
]
}
}List available prompts.
Request:
{
"jsonrpc": "2.0",
"id": 7,
"method": "prompts/list",
"params": {}
}Response:
{
"jsonrpc": "2.0",
"id": 7,
"result": {
"prompts": [
{
"name": "basic_search",
"description": "Perform a basic search with a query string",
"arguments": [
{"name": "query", "description": "The search query", "required": true}
]
},
{
"name": "advanced_search",
"description": "Perform an advanced search with filters and sorting",
"arguments": [
{"name": "query", "description": "The search query", "required": true},
{"name": "sort", "description": "Sort order", "required": false},
{"name": "num", "description": "Number of results to return", "required": false}
]
}
]
}
}Get a prompt with arguments substituted.
Request:
{
"jsonrpc": "2.0",
"id": 8,
"method": "prompts/get",
"params": {
"name": "basic_search",
"arguments": {
"query": "machine learning"
}
}
}Response:
{
"jsonrpc": "2.0",
"id": 8,
"result": {
"messages": [
{
"role": "user",
"content": {
"type": "text",
"text": "Please search for: machine learning"
}
}
]
}
}The search tool supports the following parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
q |
string | Yes | Query string for full-text search |
start |
integer | No | Start position for pagination (default: 0) |
offset |
integer | No | Alias for start position |
num |
integer | No | Number of results to return (default: 3) |
sort |
string | No | Sort order (e.g., "score.desc", "last_modified.desc") |
fields.label |
array | No | Specific labels to filter by |
lang |
string | No | Language filter |
preference |
string | No | Search preference |
# Initialize
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {}
}'
# Search documents
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "search",
"arguments": {
"q": "machine learning",
"num": 5
}
}
}'
# Get index statistics
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_index_stats",
"arguments": {}
}
}'import requests
import json
url = "http://localhost:8080/mcp"
headers = {"Content-Type": "application/json"}
# Search request
search_request = {
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search",
"arguments": {
"q": "elasticsearch",
"num": 10
}
}
}
response = requests.post(url, headers=headers, data=json.dumps(search_request))
result = response.json()
print(json.dumps(result, indent=2))The API returns standard JSON-RPC 2.0 error responses:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32601,
"message": "Unknown method: invalid_method"
}
}| Code | Message | Description |
|---|---|---|
| -32700 | Parse error | Invalid JSON was received |
| -32600 | Invalid Request | The JSON sent is not a valid Request object |
| -32601 | Method not found | The method does not exist |
| -32602 | Invalid params | Invalid method parameter(s) |
| -32603 | Internal error | Internal JSON-RPC error |
mvn clean packagemvn testContributions are welcome! Please feel free to submit a Pull Request.
Apache License 2.0
For issues and questions, please use the GitHub Issues.