GitHub - mjochum64/mcp-solr-search: MCP-Server for Apache Solr (original) (raw)

This project implements a Model Context Protocol (MCP) server that provides document search capabilities through Apache Solr. It allows Large Language Models to search and retrieve documents from Solr collections using the MCP standard.

Features

Current Version

Version 1.0.0 - See CHANGELOG.md for details on all changes.

What is MCP?

The Model Context Protocol (MCP) is a standardized way for applications to provide context to Large Language Models (LLMs). This project implements an MCP server that exposes Apache Solr's search capabilities to LLMs, allowing them to:

Requirements

Installation

  1. Install uv (if not already installed):
  2. Install the project dependencies:
    Or with pip:
  3. Copy the environment template and configure it:
    cp .env.example .env

Edit .env with your Solr connection details

  1. Create and activate a virtual environment (important):
    python -m venv .venv
    source .venv/bin/activate # On Linux/macOS

OR

..venv\Scripts\activate # On Windows

Note: Always ensure the virtual environment is activated before running the server or client tools. Many connection issues are caused by running commands outside the virtual environment.

MCP Compatibility Notes

This project is currently developed and tested with MCP 1.6.0, which has some API differences from earlier versions:

If you're using a different MCP version, you may need to adjust the code accordingly. See the TASK.md file under "Discovered During Work" for more details on compatibility issues.

Direct HTTP Access Workaround

Since MCP 1.6.0 doesn't support direct HTTP access through its standard API, this project includes a FastAPI-based alternative server that mimics the MCP interface but ensures HTTP accessibility:

Run the FastAPI-based server for direct HTTP access

python run_server.py --mode http

This server provides:

Example of direct HTTP access with curl:

Tool endpoint example

curl -X POST http://localhost:8765/tool/search
-H "Content-Type: application/json"
-d '{"query": ":", "rows": 5}'

Resource endpoint example

curl -G http://localhost:8765/resource/solr%3A%2F%2Fsearch%2F%2A%3A%2A

Usage

Starting the Solr Development Environment

The project includes a Docker Compose setup with Apache Solr and sample documents for development and testing:

Start the Solr container with sample data

./start_solr.sh

Access the Solr Admin UI

open http://localhost:8983/solr/

This will:

  1. Start an Apache Solr 9.4 container
  2. Create a "documents" collection
  3. Load 10 sample documents with various fields
  4. Configure everything for immediate use with the MCP server

Running the MCP Server

You can run the MCP server using the provided wrapper script which supports different modes:

Show help and available options

python run_server.py --mode help

Run the MCP protocol server (for LLM integration)

python run_server.py --mode mcp

Run the HTTP API server (for direct HTTP access)

python run_server.py --mode http

Specify a custom port

python run_server.py --mode http --port 9000

For development with MCP Inspector GUI:

MCP development environment with inspector GUI

mcp dev src/server/mcp_server.py

For Claude Desktop integration:

Install the MCP server for Claude Desktop

mcp install src/server/mcp_server.py --name "Solr Search"

Using the Solr MCP Server

The server exposes the following MCP endpoints:

Example: Using the search tool

Example of using the search tool from an MCP client

result = await session.call_tool( "search", arguments={ "query": "machine learning", "filter_query": "category:technology", "sort": "date desc", "rows": 5, "start": 0 } )

Example: Using the document retrieval tool

Example of retrieving a document by ID

document = await session.call_tool( "get_document", arguments={ "id": "doc123", "fields": ["title", "content", "author"] } )

Configuration

The following environment variables can be configured in your .env file:

# MCP Server Configuration
MCP_SERVER_NAME=Solr Search
MCP_SERVER_PORT=8765

# Apache Solr Configuration
SOLR_BASE_URL=http://localhost:8983/solr
SOLR_COLLECTION=documents
SOLR_USERNAME=
SOLR_PASSWORD=

# Authentication (for future use)
JWT_SECRET_KEY=your_jwt_secret_key
JWT_ALGORITHM=HS256
JWT_EXPIRATION_MINUTES=1440  # 24 hours

# Logging
LOG_LEVEL=INFO

Testing the MCP Server

There are several ways to test and interact with the MCP Solr server:

1. Using the MCP Inspector (GUI)

This is the most convenient method for testing and debugging:

Start the server with the inspector

mcp dev src/server/mcp_server.py

Then open http://127.0.0.1:6274 in your browser to access the MCP Inspector.

  1. Using the Resource:
    • Find the resource solr://search/{query} in the sidebar
    • Replace {query} with your search term (e.g., *:* for all documents)
    • Click "Execute"
  2. Using the Search Tool:
    • Go to the "Tools" section and select the "search" tool
    • Enter parameters in JSON format:
      {
      "query": ":",
      "filter_query": "category:technology",
      "sort": "id asc",
      "rows": 5,
      "start": 0
      }
    • Click "Execute"

Retrieving a document:

  1. Go to the "Tools" section and select the "get_document" tool
  2. Enter parameters in JSON format:
    {
    "id": "doc1",
    "fields": ["title", "content", "author"]
    }
  3. Click "Execute"

2. Using a Python Client

You can create a simple Python client to test the server:

import asyncio from mcp.client import MCPClient

async def test_solr_search(): # Connect to the MCP server async with MCPClient(url="http://localhost:8765") as client: # Get server info to verify connection server_info = await client.get_server_info() print("Connected to MCP server:", server_info.name)

    # Execute a search
    search_result = await client.call_tool(
        "search", 
        arguments={
            "query": "*:*",
            "filter_query": None,
            "sort": "id asc",
            "rows": 5,
            "start": 0
        }
    )
    print("Search results:", search_result)
    
    # If documents were found, retrieve the first one
    if "response" in search_result and search_result["response"]["numFound"] > 0:
        doc_id = search_result["response"]["docs"][0]["id"]
        document = await client.call_tool(
            "get_document",
            arguments={
                "id": doc_id,
                "fields": ["title", "content"]
            }
        )
        print(f"Document with ID {doc_id}:", document)

if name == "main": asyncio.run(test_solr_search())

Save this as test_solr_client.py and run:

python test_solr_client.py

3. Using Direct HTTP Requests

You can also test with curl or any HTTP client. Note that the MCP server expects specific request formats:

Testing search tool with curl

curl -X POST http://localhost:8765/tool/search
-H "Content-Type: application/json"
-d '{"query": ":", "rows": 5}'

Retrieving a document with curl

curl -X POST http://localhost:8765/tool/get_document
-H "Content-Type: application/json"
-d '{"id": "doc1"}'

Using the resource endpoint

curl -G http://localhost:8765/resource/solr%3A%2F%2Fsearch%2F%2A%3A%2A
--data-urlencode "query=:"

4. Troubleshooting Connection Issues

If you can access the MCP Inspector but not connect with other clients:

  1. Check CORS settings:
    • If using a web client from a different origin, CORS might be blocking requests
  2. Verify network access:
    • Ensure port 8765 is accessible from the client
  3. Check for authentication requirements:
    • If authentication is enabled, ensure clients are including the required credentials
  4. Inspect request format:
    • MCP expects specific endpoint formats and JSON structures
  5. Use the debug server mode:
    MCP_DEBUG=1 python run_server.py --mode mcp

Development

Running Tests

Run all tests (unit and integration)

pytest

Run only unit tests

pytest tests/test_server.py

Run only integration tests (requires running Solr)

pytest tests/test_integration_server.py -m integration

Run with coverage

pytest --cov=src

Integration tests will automatically skip if the Solr server is not available, so they're safe to run even without a running Docker environment.

Project Structure

/src
  server.py         # Main MCP server implementation
/tests
  test_server.py    # Unit tests with mocked Solr responses
  test_integration_server.py # Integration tests with real Solr
/docker
  /solr
    load_sample_data.py  # Script to load sample documents
    /configsets
      /documents
        /conf
          schema.xml     # Solr schema definition
          solrconfig.xml # Solr configuration
          stopwords.txt  # Stopwords for text analysis
docker-compose.yml   # Docker Compose configuration for Solr
start_solr.sh        # Script to start Solr and load data
.env.example         # Environment variables template
pyproject.toml       # Project configuration
PLANNING.md          # Project planning document
TASK.md              # Project tasks and progress tracking
CHANGELOG.md         # Documentation of project changes
README.md            # This file

Versioning

This project follows Semantic Versioning. For the versions available, see the CHANGELOG.md file for details on what has changed in each version.

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature-name
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin feature-name
  5. Submit a pull request

License

This project is licensed under the MIT License.