This is an automated email from the ASF dual-hosted git repository.
epugh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr-mcp.git
The following commit(s) were added to refs/heads/main by this push:
new e68709b docs: Break up readme (#14)
e68709b is described below
commit e68709b8471b365a47c6bc933e012392005bed89
Author: Aditya Parikh <[email protected]>
AuthorDate: Tue Nov 4 09:20:20 2025 -0500
docs: Break up readme (#14)
---
.github/workflows/build.yml | 51 ---
CONTRIBUTING.md | 132 ++++++++
README.md | 762 +++++---------------------------------------
dev-docs/ARCHITECTURE.md | 201 ++++++++++++
dev-docs/DEPLOYMENT.md | 372 +++++++++++++++++++++
dev-docs/DEVELOPMENT.md | 319 +++++++++++++++++++
dev-docs/TROUBLESHOOTING.md | 445 ++++++++++++++++++++++++++
7 files changed, 1547 insertions(+), 735 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
deleted file mode 100644
index 281bd62..0000000
--- a/.github/workflows/build.yml
+++ /dev/null
@@ -1,51 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-name: SonarQube
-on:
- push:
- branches:
- - main
- pull_request:
- types: [opened, synchronize, reopened]
-jobs:
- build:
- name: Build and analyze
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- with:
- fetch-depth: 0 # Shallow clones should be disabled for a better
relevancy of analysis
- - name: Set up JDK 17
- uses: actions/setup-java@v4
- with:
- java-version: 17
- distribution: 'zulu' # Alternative distribution options are available
- - name: Cache SonarQube packages
- uses: actions/cache@v4
- with:
- path: ~/.sonar/cache
- key: ${{ runner.os }}-sonar
- restore-keys: ${{ runner.os }}-sonar
- - name: Cache Gradle packages
- uses: actions/cache@v4
- with:
- path: ~/.gradle/caches
- key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
- restore-keys: ${{ runner.os }}-gradle
- - name: Build and analyze
- env:
- SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- run: ./gradlew build sonar --info
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..3fbb590
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,132 @@
+# Contributing to Solr MCP Server
+
+Thank you for your interest in contributing to the Solr MCP Server! This
document provides guidelines for contributing to the project.
+
+## Developer documentation
+
+To avoid duplication, the environment setup, build/run/test workflows, and
detailed developer guides live in the dev-docs folder:
+
+- Development Guide (build, run, test, IDE, CI): dev-docs/DEVELOPMENT.md
+- Architecture: dev-docs/ARCHITECTURE.md
+- Deployment (Docker, HTTP vs STDIO): dev-docs/DEPLOYMENT.md
+- Troubleshooting: dev-docs/TROUBLESHOOTING.md
+
+If you're ready to contribute code, see Submitting Changes below.
+
+## Code Style and Quality
+
+We use Spotless for code formatting and style enforcement. CI enforces
`spotlessCheck` on pull requests.
+
+- Commands and details: dev-docs/DEVELOPMENT.md#common-gradle-tasks
+- Build system overview: dev-docs/DEVELOPMENT.md#build-system
+
+### Coding Standards
+
+- Follow standard Java conventions
+- Write meaningful commit messages
+- Add JavaDoc for public APIs
+- Include unit tests for new features
+- Keep methods focused and concise
+
+## Testing
+
+To keep this document concise, please see the Development Guide for all
testing workflows and tips:
+
+- Testing overview: dev-docs/DEVELOPMENT.md#testing
+- Unit tests: dev-docs/DEVELOPMENT.md#unit-tests
+- Integration tests: dev-docs/DEVELOPMENT.md#integration-tests
+- Docker image tests: dev-docs/DEVELOPMENT.md#docker-integration-tests
+- Coverage reports: dev-docs/DEVELOPMENT.md#testing
+
+## Submitting Changes
+
+### Pull Request Process
+
+1. **Create a feature branch**
+ ```bash
+ git checkout -b feature/your-feature-name
+ ```
+
+2. **Make your changes**
+ - Write clean, well-documented code
+ - Add tests for new functionality
+ - Update documentation as needed
+
+3. **Format your code**
+ ```bash
+ ./gradlew spotlessApply
+ ```
+
+4. **Run tests**
+ ```bash
+ ./gradlew build
+ ```
+
+5. **Commit your changes**
+ ```bash
+ git add .
+ git commit -m "feat: add your feature description"
+ ```
+
+6. **Push to your fork**
+ ```bash
+ git push origin feature/your-feature-name
+ ```
+
+7. **Create a Pull Request**
+ - Provide a clear description of the changes
+ - Reference any related issues
+ - Ensure CI checks pass
+
+### Commit Message Guidelines
+
+We follow the [Conventional Commits](https://www.conventionalcommits.org/)
specification:
+
+```
+<type>(<scope>): <description>
+
+[optional body]
+
+[optional footer]
+```
+
+**Types:**
+- `feat`: New feature
+- `fix`: Bug fix
+- `docs`: Documentation changes
+- `style`: Code style changes (formatting, etc.)
+- `refactor`: Code refactoring
+- `test`: Adding or updating tests
+- `chore`: Maintenance tasks
+
+**Examples:**
+```
+feat(search): add fuzzy search support
+fix(indexing): handle null values in CSV parser
+docs: update installation instructions
+test: add integration tests for collection service
+```
+
+## Development workflow references
+
+For implementation details and examples, see the Development Guide:
+
+- Adding new MCP tools: dev-docs/DEVELOPMENT.md#adding-a-new-mcp-tool
+- Adding a new document format:
dev-docs/DEVELOPMENT.md#adding-a-new-document-format
+- Project structure and architecture: dev-docs/ARCHITECTURE.md
+- Dependencies and version catalogs: dev-docs/DEVELOPMENT.md#build-system
+- Documentation practices: dev-docs/DEVELOPMENT.md#modifying-configuration
+
+## Questions or Need Help?
+
+- Open an issue for bugs or feature requests
+- Start a discussion for questions or ideas
+- Check existing issues and discussions first
+
+## Code of Conduct
+
+Be respectful, inclusive, and professional. We're all here to build something
great together.
+
+## License
+
+By contributing, you agree that your contributions will be licensed under the
Apache License 2.0.
diff --git a/README.md b/README.md
index b37baf5..ff22f3b 100644
--- a/README.md
+++ b/README.md
@@ -2,715 +2,109 @@
# Solr MCP Server
-A Spring AI Model Context Protocol (MCP) server that provides tools for
interacting with Apache Solr. This server
-enables AI assistants like Claude to search, index, and manage Solr
collections through the MCP protocol.
-
-## Overview
-
-This project provides a set of tools that allow AI assistants to interact with
Apache Solr, a powerful open-source
-search platform. By implementing the Spring AI MCP protocol, these tools can
be used by any MCP-compatible client,
-including Claude Desktop. The project uses SolrJ, the official Java client for
Solr, to communicate with Solr instances.
-
-The server provides the following capabilities:
-
-- Search Solr collections with advanced query options
-- Index documents into Solr collections
-- Manage and monitor Solr collections
-- Retrieve and analyze Solr schema information
-
-### Transport Profiles
-
-The server supports two transport modes:
-
-- **STDIO (Standard Input/Output)** - Recommended for local development and
production use with Claude Desktop. This is
- the default and most secure option for local deployments.
-- **HTTP (Streamable HTTP)** - For testing with MCP Inspector and remote
deployments. ⚠️ **Note:** HTTP
- mode is inherently insecure without additional security measures (see
Security Considerations below).
-
-## Prerequisites
-
-- Java 25 or higher
-- Docker and Docker Compose (for running Solr)
-- Gradle 9.1.0+ (wrapper included in project)
-
-## Installation and Setup
-
-### 1. Clone the repository
-
-```bash
-git clone https://github.com/yourusername/solr-mcp.git
-cd solr-mcp
-```
-
-### 2. Start Solr using Docker Compose
-
-```bash
-docker-compose up -d
-```
-
-This will start a Solr instance in SolrCloud mode with ZooKeeper and create
two sample collections:
-
-- `books` - A collection with sample book data
-- `films` - A collection with sample film data
-
-### 3. Build the Project
-
-This project uses Gradle with version catalogs for dependency management. All
dependencies and their versions are
-centrally managed in `gradle/libs.versions.toml`.
-
-```bash
-# Build the project and run tests
-./gradlew build
-
-# Build without tests (faster)
-./gradlew assemble
-
-# Clean and rebuild
-./gradlew clean build
-```
-
-The build produces two JAR files in `build/libs/`:
-
-- `solr-mcp-0.0.1-SNAPSHOT.jar` - Executable JAR with all dependencies (fat
JAR)
-- `solr-mcp-0.0.1-SNAPSHOT-plain.jar` - Plain JAR without dependencies
-
-### 4. Building using Docker Images instead of JARs
-
-This project uses [Jib](https://github.com/GoogleContainerTools/jib) to build
optimized Docker images without requiring
-Docker installed. Jib creates layered images for faster rebuilds and smaller
image sizes.
-
-#### Option 1: Build to Docker Daemon
-
-Build directly to your local Docker daemon (requires Docker installed):
-
-```bash
-./gradlew jibDockerBuild
-```
-
-This creates a local Docker image: `solr-mcp:0.0.1-SNAPSHOT`
-
-Verify the image:
-
-```bash
-docker images | grep solr-mcp
-```
-
-#### Option 2: Push to Docker Hub
-
-Authenticate with Docker Hub and push (No Local Docker daemon required):
-
-```bash
-# Login to Docker Hub
-docker login
-
-# Build and push
-./gradlew jib -Djib.to.image=YOUR_DOCKERHUB_USERNAME/solr-mcp:0.0.1-SNAPSHOT
-```
-
-#### Option 3: Push to GitHub Container Registry
-
-Authenticate with GitHub Container Registry and push (No Local Docker daemon
required):
-
-```bash
-# Create a Personal Access Token (classic) with write:packages scope at:
-# https://github.com/settings/tokens
-
-# Login to GitHub Container Registry
-export GITHUB_TOKEN=YOUR_GITHUB_TOKEN
-echo $GITHUB_TOKEN | docker login ghcr.io -u YOUR_GITHUB_USERNAME
--password-stdin
-
-# Build and push
-./gradlew jib
-Djib.to.image=ghcr.io/YOUR_GITHUB_USERNAME/solr-mcp:0.0.1-SNAPSHOT
-```
-
-#### Multi-Platform Support
-
-The Docker images are built with multi-platform support for:
-
-- `linux/amd64` (Intel/AMD 64-bit)
-- `linux/arm64` (Apple Silicon M1/M2/M3/M4/M5)
-
-#### Automated Builds with GitHub Actions
-
-This project includes a GitHub Actions workflow that automatically builds and
publishes Docker images to both GitHub
-Container Registry and Docker Hub.
-
-**Triggers:**
-
-- Push to `main` branch - Builds and publishes images tagged with
`version-SHA` and `latest`
-- Version tags (e.g., `v1.0.0`) - Builds and publishes images tagged with the
version number and `latest`
-- Pull requests - Builds and tests only (no publishing)
-
-**Published Images:**
-
-- GitHub Container Registry: `ghcr.io/OWNER/solr-mcp:TAG`
-- Docker Hub: `DOCKERHUB_USERNAME/solr-mcp:TAG`
-
-**Setup for Docker Hub Publishing:**
-
-To enable Docker Hub publishing, configure these repository secrets:
-
-1. Go to your GitHub repository Settings > Secrets and variables > Actions
-2. Add the following secrets:
- - `DOCKERHUB_USERNAME`: Your Docker Hub username
- - `DOCKERHUB_TOKEN`: Docker Hub access token (create at
https://hub.docker.com/settings/security)
-
-**Note:** GitHub Container Registry publishing works automatically using the
`GITHUB_TOKEN` provided by GitHub Actions.
-
-#### Running the Docker Container
-
-Run the container with STDIO mode:
-
-```bash
-docker run -i --rm solr-mcp:0.0.1-SNAPSHOT
-```
-
-Or with custom Solr URL:
-
-```bash
-docker run -i --rm \
- -e SOLR_URL=http://your-solr-host:8983/solr/ \
- solr-mcp:0.0.1-SNAPSHOT
-```
-
-**Note for Linux users:** If you need to connect to Solr running on the host
machine, add the `--add-host` flag:
-
-```bash
-docker run -i --rm \
- --add-host=host.docker.internal:host-gateway \
- solr-mcp:0.0.1-SNAPSHOT
-```
-
-#### Docker Executable Configuration
-
-Jib needs to find the Docker executable to build images. The build is
configured to automatically detect Docker based on
-your operating system:
-
-- **macOS**: `/usr/local/bin/docker`
-- **Linux**: `/usr/bin/docker`
-- **Windows**: `C:\Program Files\Docker\Docker\resources\bin\docker.exe`
-
-If Docker is installed in a different location, set the `DOCKER_EXECUTABLE`
environment variable:
-
-```bash
-export DOCKER_EXECUTABLE=/custom/path/to/docker
-./gradlew jibDockerBuild
-```
-
-## Project Structure
-
-The codebase follows a clean, modular architecture organized by functionality:
-
-```
-src/main/java/org/apache/solr/mcp/server/
-├── Main.java # Application entry point
-├── config/ # Configuration classes
-│ ├── SolrConfig.java # Solr client bean configuration
-│ └── SolrConfigurationProperties.java # Solr connection properties
-├── search/ # Search functionality
-│ ├── SearchService.java # MCP tool for searching Solr
-│ └── SearchResponse.java # Search result DTOs
-├── indexing/ # Document indexing functionality
-│ ├── IndexingService.java # MCP tool for indexing documents
-│ └── documentcreator/ # Document format parsers
-│ ├── IndexingDocumentCreator.java # Interface for document creators
-│ ├── JsonDocumentCreator.java # JSON document parser
-│ ├── CsvDocumentCreator.java # CSV document parser
-│ ├── XmlDocumentCreator.java # XML document parser
-│ ├── SolrDocumentCreator.java # Factory for document creators
-│ ├── FieldNameSanitizer.java # Field name sanitization utility
-│ └── DocumentProcessingException.java # Indexing exceptions
-└── metadata/ # Collection management functionality
- ├── CollectionService.java # MCP tools for collection operations
- ├── SchemaService.java # MCP tool for schema retrieval
- ├── CollectionUtils.java # Collection utility methods
- └── Dtos.java # Collection-related DTOs (records)
-```
-
-### Key Components
-
-- **MCP Tools**: Service classes annotated with `@McpTool` expose
functionality to AI assistants
- - `SearchService` - Search queries with filtering, faceting, and pagination
- - `IndexingService` - Document indexing with support for JSON, CSV, and
XML formats
- - `CollectionService` - Collection management (list, stats, health checks)
- - `SchemaService` - Schema introspection
-
-- **Configuration**: Spring Boot configuration using properties files
- - `application.properties` - Default configuration
- - `application-stdio.properties` - STDIO transport profile
- - `application-http.properties` - HTTP transport profile
-
-- **Document Creators**: Strategy pattern implementation for parsing different
document formats
- - Automatically sanitizes field names to comply with Solr schema
requirements
- - Supports nested JSON structures and multi-valued fields
-
-- **DTOs**: Java records for immutable data transfer objects (removed Lombok
dependency)
-
-## Available Tools
-
-The server provides the following tools that can be used by MCP clients:
-
-### 1. Search
-
-Search a Solr collection with advanced query options.
-
-```
-Tool: Search
-Description: Search specified Solr collection with query, optional filters,
facets, sorting, and pagination.
-Parameters:
- - collection: Solr collection to query
- - query: Solr q parameter (defaults to "*:*" if not specified)
- - filterQueries: Solr fq parameter (optional)
- - facetFields: Solr facet fields (optional)
- - sortClauses: Solr sort parameter (optional)
- - start: Starting offset for pagination (optional)
- - rows: Number of rows to return (optional)
-```
-
-### 2. Index Documents
-
-Index JSON documents into a Solr collection.
-
-```
-Tool: index_documents
-Description: Index documents from JSON string into Solr collection
-Parameters:
- - collection: Solr collection to index into
- - json: JSON string containing documents to index
-```
-
-### 3. List Collections
-
-List all available Solr collections.
-
-```
-Tool: listCollections
-Description: List solr collections
-Parameters: None
-```
-
-### 4. Get Collection Stats
-
-Get detailed statistics and metrics for a Solr collection.
-
-```
-Tool: getCollectionStats
-Description: Get stats/metrics on a Solr collection
-Parameters:
- - collection: Name of the collection
-```
-
-### 5. Check Collection Health
-
-Check the health status of a Solr collection.
-
-```
-Tool: checkHealth
-Description: Check health of a Solr collection
-Parameters:
- - collection: Name of the collection
-```
-
-### 6. Get Schema
-
-Retrieve the schema for a Solr collection.
-
-```
-Tool: getSchema
-Description: Get schema for a Solr collection
-Parameters:
- - collection: Name of the collection
-```
-
-## Adding to Claude Desktop
-
-You can add this MCP server to Claude Desktop using either the JAR file or
Docker container.
-
-### Option 1: Using JAR File
-
-1. Build the project as a standalone JAR:
-
-```bash
-./gradlew build
-```
-
-2. In Claude Desktop, go to Settings > Developer > Edit Config
-
-3. Add the following configuration to your MCP settings:
-
+A Spring AI Model Context Protocol (MCP) server that provides tools for
interacting with Apache Solr. Enables AI assistants like Claude to search,
index, and manage Solr collections through the MCP protocol.
+
+## What’s inside
+
+- 🔍 Search Solr collections with filtering, faceting, and pagination
+- 📝 Index documents in JSON, CSV, and XML
+- 📊 Manage collections and view statistics
+- 🔧 Inspect schema
+- 🔌 Transports: STDIO (Claude Desktop) and HTTP (MCP Inspector)
+- 🐳 Docker images built with Jib
+
+## Get started (users)
+
+- Prerequisites: Java 25+, Docker (and Docker Compose), Git
+- Start Solr with sample data:
+ ```bash
+ docker compose up -d
+ ```
+- Run the server:
+ - Option A (JAR):
+ ```bash
+ ./gradlew build
+ java -jar build/libs/solr-mcp-0.0.1-SNAPSHOT.jar
+ ```
+ - Option B (Docker):
+ ```bash
+ docker run -i --rm ghcr.io/apache/solr-mcp:latest
+ ```
+
+For more ways to run (HTTP mode, custom SOLR_URL, Linux host networking) see
the Deployment Guide: docs/DEPLOYMENT.md
+
+### Claude Desktop
+
+Add this to your Claude Desktop config (macOS path shown); then restart Claude.
```json
{
- "mcpServers": {
- "solr-search-mcp": {
- "command": "java",
- "args": [
- "-jar",
-
"/absolute/path/to/solr-mcp/build/libs/solr-mcp-0.0.1-SNAPSHOT.jar"
- ],
- "env": {
- "SOLR_URL": "http://localhost:8983/solr/",
- "PROFILES": "stdio"
- }
+ "mcpServers": {
+ "solr-mcp": {
+ "command": "docker",
+ "args": ["run", "-i", "--rm", "ghcr.io/apache/solr-mcp:latest"],
+ "env": {
+ "SOLR_URL": "http://localhost:8983/solr/"
}
}
+ }
}
```
-**Note:** Replace `/absolute/path/to/solr-mcp` with the actual path to your
project directory.
+More configuration options: docs/DEPLOYMENT.md#docker-images-with-jib
-### Option 2: Using Docker Container
+## Available MCP tools
-1. Build the Docker image:
+| Tool | Description |
+|------|-------------|
+| `search` | Search Solr collections with advanced query options |
+| `index_documents` | Index documents from JSON, CSV, or XML |
+| `listCollections` | List all available Solr collections |
+| `getCollectionStats` | Get statistics and metrics for a collection |
+| `checkHealth` | Check the health status of a collection |
+| `getSchema` | Retrieve schema information for a collection |
-```bash
-./gradlew jibDockerBuild
-```
-
-2. In Claude Desktop, go to Settings > Developer > Edit Config
-
-3. Add the following configuration to your MCP settings:
-
-```json
-{
- "mcpServers": {
- "solr-search-mcp": {
- "command": "docker",
- "args": [
- "run",
- "-i",
- "--rm",
- "solr-mcp:0.0.1-SNAPSHOT"
- ],
- "env": {
- "SOLR_URL": "http://localhost:8983/solr/"
- }
- }
- }
-}
-```
-
-**Note for macOS/Windows users:** Docker Desktop automatically provides
`host.docker.internal` for accessing services on
-the host machine. The container is pre-configured to use this.
-
-**Note for Linux users:** You need to add the `--add-host` flag to enable
communication with services running on the
-host:
-
-```json
-{
- "mcpServers": {
- "solr-search-mcp": {
- "command": "docker",
- "args": [
- "run",
- "-i",
- "--rm",
- "--add-host=host.docker.internal:host-gateway",
- "solr-mcp:0.0.1-SNAPSHOT"
- ],
- "env": {
- "SOLR_URL": "http://host.docker.internal:8983/solr/"
- }
- }
- }
-}
-```
-
-### Using a Public Docker Image
-
-If you've pushed the image to Docker Hub or GitHub Container Registry, you can
use it directly:
-
-#### Docker Hub
-
-```json
-{
- "mcpServers": {
- "solr-search-mcp": {
- "command": "docker",
- "args": [
- "run",
- "-i",
- "--rm",
- "YOUR_DOCKERHUB_USERNAME/solr-mcp:0.0.1-SNAPSHOT"
- ],
- "env": {
- "SOLR_URL": "http://localhost:8983/solr/"
- }
- }
- }
-}
-```
-
-#### GitHub Container Registry
-
-```json
-{
- "mcpServers": {
- "solr-search-mcp": {
- "command": "docker",
- "args": [
- "run",
- "-i",
- "--rm",
- "ghcr.io/YOUR_GITHUB_USERNAME/solr-mcp:0.0.1-SNAPSHOT"
- ],
- "env": {
- "SOLR_URL": "http://localhost:8983/solr/"
- }
- }
- }
-}
-```
-
-### Restart Claude Desktop & Invoke
-
-After configuring, restart Claude Desktop to load the MCP server.
-
-
-
-## Testing with MCP Inspector
-
-For development and testing, you can use the [MCP
Inspector](https://github.com/modelcontextprotocol/inspector):
-
-```bash
-# Install the MCP Inspector (requires Node.js)
-➜ ~ npx @modelcontextprotocol/inspector
-
-Starting MCP inspector...
-⚙️ Proxy server listening on localhost:6277
-🔑 Session token: 12345
- Use this token to authenticate requests or set DANGEROUSLY_OMIT_AUTH=true
to disable auth
-
-🚀 MCP Inspector is up and running at:
- http://localhost:6274/?MCP_PROXY_AUTH_TOKEN=12345
-
-🌐 Opening browser...
-```
-
-This provides a web interface to test MCP tools interactively.
-
+## Screenshots
-# HTTP Mode
+- Claude Desktop (STDIO):
-
+ 
-```shell
-./gradlew bootRun --args='--spring.profiles.active=http'
-```
-
-## Tools Usage Examples
-
-Here are some examples of how to use the tools from an MCP client like Claude:
-
-### Searching for Books
-
-```
-I need to search for fantasy books in the Solr collection. Can you help me?
-```
-
-Claude can use the Search tool to query the books collection:
+- MCP Inspector (HTTP):
-```
-I'll search for fantasy books in the Solr collection.
-
-Using the Search tool with:
-- collection: books
-- query: genre_s:fantasy
-- rows: 5
-
-Here are the fantasy books I found:
-1. "A Game of Thrones" by George R.R. Martin
-2. "A Clash of Kings" by George R.R. Martin
-...
-```
+ 
-### Indexing New Documents
+- MCP Inspector (STDIO):
-```
-I have some new book data I'd like to add to Solr. Can you help me index it?
-```
+ 
-Claude can use the index_documents tool:
-
-```
-I'll help you index that book data into Solr.
+## Documentation
-Using the index_documents tool with:
-- collection: books
-- json: [{"id":"123456789","name":["The New Book"],"author":["Jane
Author"],"genre_s":"mystery","price":[12.99]}]
+- Architecture: docs/ARCHITECTURE.md
+- Development (build, run, test, add features): docs/DEVELOPMENT.md
+- Deployment (Docker, HTTP vs STDIO, CI/CD, MCP Registry): docs/DEPLOYMENT.md
+- Troubleshooting: docs/TROUBLESHOOTING.md
-The document has been successfully indexed into the books collection.
-```
-
-### Listing Collections
-
-```
-What Solr collections are available in the system?
-```
-
-Claude can use the listCollections tool:
-
-```
-I'll check what Solr collections are available.
-
-Using the listCollections tool.
-
-The following collections are available:
-1. books
-2. films
-```
-
-### Getting Collection Statistics
-
-```
-Can you tell me more about the 'books' collection? I'd like to know its size
and other metrics.
-```
-
-Claude can use the getCollectionStats tool:
-
-```
-I'll get statistics for the 'books' collection.
-
-Using the getCollectionStats tool with:
-- collection: books
-
-Here are the statistics for the 'books' collection:
-- Number of documents: 1,245
-- Segment count: 5
-- Query performance:
- - Average query time: 12ms
- - Cache hit ratio: 0.85
-- Handler statistics:
- - Select handler requests: 1,532
- - Update handler requests: 245
-```
-
-### Checking Collection Health
-
-```
-Is the 'films' collection healthy and responding properly?
-```
-
-Claude can use the checkHealth tool:
-
-```
-I'll check the health of the 'films' collection.
-
-Using the checkHealth tool with:
-- collection: films
-
-Health status:
-- Healthy: Yes
-- Response time: 8ms
-- Total documents: 532
-- Last checked: 2023-06-15 14:32:45
-```
-
-### Retrieving Schema Information
-
-```
-What fields are defined in the 'books' collection schema?
-```
-
-Claude can use the getSchema tool:
-
-```
-I'll retrieve the schema for the 'books' collection.
-
-Using the getSchema tool with:
-- collection: books
-
-The 'books' collection has the following fields:
-- id (string): Unique identifier
-- name (text_general): Book title
-- author (text_general): Book author
-- genre_s (string): Genre
-- price (float): Book price
-- in_stock_b (boolean): Whether the book is in stock
-- publish_date (date): Publication date
-```
-
-## Security Considerations
-
-### STDIO Transport Security
-
-STDIO transport is the recommended option for local deployments because:
-
-- Communication occurs within the same machine through process pipes
-- No network exposure or open ports
-- OS-level process isolation provides security boundaries
-- Credentials are not exposed over the network
-
-### HTTP Transport Security Risks
-
-⚠️ **Warning**: The current HTTP implementation is **insecure** for production
use without additional security
-measures.
-
-HTTP transport has the following security vulnerabilities when deployed
without authentication:
-
-1. **No Authentication or Authorization**: By default, the HTTP endpoints are
publicly accessible without any
- authentication mechanism
-2. **No Transport Encryption**: HTTP traffic is unencrypted and can be
intercepted (use HTTPS in production)
-3. **No Origin Validation**: Without proper origin header validation, the
server is vulnerable to DNS rebinding attacks
-4. **Network Exposure**: Unlike STDIO, HTTP endpoints are exposed over the
network and accessible to any client that can
- reach the server
-
-### Securing HTTP Deployments
-
-If you need to deploy the MCP server with HTTP transport for remote access,
you **must** implement security
-controls:
-
-1. **Use HTTPS**: Always use TLS/SSL encryption for production deployments
-2. **Implement OAuth2 Authentication**: Follow
- the [Spring AI MCP OAuth2
guide](https://spring.io/blog/2025/04/02/mcp-server-oauth2/) to add
authentication
-3. **Validate Origin Headers**: Implement origin header validation to prevent
DNS rebinding attacks
-4. **Network Isolation**: Deploy behind a firewall or VPN, restricting access
to trusted networks
-5. **Use API Gateways**: Consider deploying behind an API gateway with
authentication and rate limiting
-
-### Recommendation
-
-- **Local development/testing**: Use HTTP mode for testing with MCP Inspector,
but only on localhost
-- **Claude Desktop integration**: Always use STDIO mode
-- **Production remote deployments**: Only use HTTP with OAuth2 authentication,
HTTPS, and proper network security
- controls
-
-## Troubleshooting
-
-If you encounter issues:
-
-1. Ensure Solr is running and accessible. By default, the server connects to
http://localhost:8983/solr/, but you can
- set the `SOLR_URL` environment variable to point to a different Solr
instance.
-2. Check the logs for any error messages
-3. Verify that the collections exist using the Solr Admin UI
-4. If using HTTP mode, ensure the server is running on the expected port
(default: 8080)
-5. For STDIO mode with Claude Desktop, verify the JAR path is absolute and
correct in the configuration
-
-## FAQ
-
-### Why use Jib instead of Spring Boot Buildpacks?
-
-This project uses [Jib](https://github.com/GoogleContainerTools/jib) for
building Docker images instead of Spring Boot
-Buildpacks for a critical compatibility reason:
+## Contributing
-**STDIO Mode Compatibility**: Docker images built with Spring Boot Buildpacks
were outputting logs and diagnostic
-information to stdout, which interfered with the MCP protocol's STDIO
transport. The MCP protocol requires a clean
-stdout channel for protocol messages - any extraneous output causes connection
errors and prevents the server from
-working properly with MCP clients like Claude Desktop.
+We welcome contributions!
-Jib provides additional benefits:
+- Start here: CONTRIBUTING.md
+- Developer workflows, coding standards, and tests: docs/DEVELOPMENT.md
-- **Clean stdout**: Jib-built images don't pollute stdout with build
information or runtime logs
-- **No Docker daemon required**: Jib can build images without Docker installed
-- **Faster builds**: Layered image building with better caching
-- **Smaller images**: More efficient layer organization
-- **Multi-platform support**: Easy cross-platform image building for amd64 and
arm64
+## Support
-If you're building an MCP server with Docker support, ensure your
containerization approach maintains a clean stdout
-channel when running in STDIO mode.
+- Issues: https://github.com/apache/solr-mcp/issues
+- Discussions: https://github.com/apache/solr-mcp/discussions
## License
-This project is licensed under the Apache License 2.0.
+Apache License 2.0 — see LICENSE
-## Contributing
+## Acknowledgments
+
+Built with:
-Contributions are welcome! Please feel free to submit a Pull Request.
+- Spring AI MCP — https://spring.io/projects/spring-ai
+- Apache Solr — https://solr.apache.org/
+- Jib — https://github.com/GoogleContainerTools/jib
+- Testcontainers — https://www.testcontainers.org/
diff --git a/dev-docs/ARCHITECTURE.md b/dev-docs/ARCHITECTURE.md
new file mode 100644
index 0000000..eae59f0
--- /dev/null
+++ b/dev-docs/ARCHITECTURE.md
@@ -0,0 +1,201 @@
+# Architecture
+
+This document describes the architecture and design decisions of the Solr MCP
Server.
+
+## Project Structure
+
+The codebase follows a clean, modular architecture organized by functionality:
+
+```
+src/main/java/org/apache/solr/mcp/server/
+├── Main.java # Application entry point
+├── config/ # Configuration classes
+│ ├── SolrConfig.java # Solr client bean configuration
+│ └── SolrConfigurationProperties.java # Solr connection properties
+├── search/ # Search functionality
+│ ├── SearchService.java # MCP tool for searching Solr
+│ └── SearchResponse.java # Search result DTOs
+├── indexing/ # Document indexing functionality
+│ ├── IndexingService.java # MCP tool for indexing documents
+│ └── documentcreator/ # Document format parsers
+│ ├── IndexingDocumentCreator.java # Orchestrator that delegates to
format-specific creators
+│ ├── JsonDocumentCreator.java # JSON document parser (implements
SolrDocumentCreator)
+│ ├── CsvDocumentCreator.java # CSV document parser (implements
SolrDocumentCreator)
+│ ├── XmlDocumentCreator.java # XML document parser (implements
SolrDocumentCreator)
+│ ├── SolrDocumentCreator.java # Common interface for document
creators
+│ ├── FieldNameSanitizer.java # Field name sanitization utility
+│ └── DocumentProcessingException.java # Indexing exceptions
+└── metadata/ # Collection management functionality
+ ├── CollectionService.java # MCP tools for collection operations
+ ├── SchemaService.java # MCP tool for schema retrieval
+ ├── CollectionUtils.java # Collection utility methods
+ └── Dtos.java # Collection-related DTOs (records)
+```
+
+## Key Components
+
+### MCP Tools
+
+Service classes annotated with `@McpTool` expose functionality to AI
assistants:
+
+- **SearchService** - Search queries with filtering, faceting, and pagination
+- **IndexingService** - Document indexing with support for JSON, CSV, and XML
formats
+- **CollectionService** - Collection management (list, stats, health checks)
+- **SchemaService** - Schema introspection
+
+### Configuration
+
+Spring Boot configuration using properties files:
+
+- `application.properties` - Default configuration
+- `application-stdio.properties` - STDIO transport profile
+- `application-http.properties` - HTTP transport profile
+
+### Document Creators
+
+Strategy pattern implementation for parsing different document formats:
+
+- Automatically sanitizes field names to comply with Solr schema requirements
+- Supports nested JSON structures and multi-valued fields
+- Delegation via service composition (IndexingDocumentCreator) to the
appropriate format-specific creator
+
+### DTOs
+
+Plain Java classes (POJOs) used as data transfer objects:
+
+- No Lombok dependency; simple, explicit types
+- Designed for straightforward serialization/deserialization
+- Favor clarity; immutability can be introduced where it adds value
+
+## Design Decisions
+
+### Why Spring AI MCP?
+
+Spring AI MCP provides a robust framework for implementing the Model Context
Protocol with:
+- Built-in transport layer support (STDIO and HTTP)
+- Annotation-based tool registration
+- Spring Boot integration for configuration and dependency injection
+
+### Why Jib instead of Spring Boot Buildpacks?
+
+**STDIO Mode Compatibility**: Docker images built with Spring Boot Buildpacks
output logs and diagnostic information to stdout, which interferes with the MCP
protocol's STDIO transport. The MCP protocol requires a clean stdout channel
for protocol messages.
+
+Additional Jib benefits:
+- **Clean stdout**: No pollution of protocol messages
+- **No Docker daemon required**: Can build images without Docker installed
+- **Faster builds**: Layered image building with better caching
+- **Smaller images**: More efficient layer organization
+- **Multi-platform support**: Easy cross-platform image building for amd64 and
arm64
+
+### Transport Modes
+
+#### STDIO (Recommended for Claude Desktop)
+
+- Communication via standard input/output streams
+- No network exposure
+- OS-level process isolation
+- Secure for local deployments
+
+#### HTTP (For MCP Inspector / Remote Access)
+
+- RESTful endpoints using Spring Web
+- Streamable HTTP transport
+- Requires additional security measures for production
+- Useful for testing and remote deployments
+
+### Document Processing
+
+The document creator pattern allows for:
+- **Extensibility**: Easy to add new format parsers
+- **Testability**: Each creator can be tested independently
+- **Field Sanitization**: Automatic conversion of field names to
Solr-compatible format
+- **Explicit Format Selection**: Separate methods for JSON/CSV/XML (no
automatic detection)
+
+### Error Handling
+
+- Custom exceptions for domain-specific errors
+- Proper error messages propagated to MCP clients
+- Validation at tool entry points
+
+## Testing Architecture
+
+### Unit Tests
+- Test individual components in isolation
+- Mock external dependencies (Solr, Spring beans)
+- Fast execution for quick feedback
+
+### Integration Tests
+- Use Testcontainers for real Solr instances
+- Test end-to-end workflows
+- Verify Docker image functionality
+
+### Test Structure
+```
+src/test/java/org/apache/solr/mcp/server/
+├── McpToolRegistrationTest.java # MCP tool registration tests
+├── BuildInfoReader.java # Test utility for build metadata
+├── SampleClient.java # Example MCP client
+├── search/
+│ ├── SearchServiceTest.java # Unit tests
+│ └── SearchServiceDirectTest.java # Integration tests
+├── indexing/
+│ ├── IndexingServiceTest.java
+│ ├── IndexingServiceDirectTest.java
+│ ├── CsvIndexingTest.java
+│ └── XmlIndexingTest.java
+├── metadata/
+│ ├── CollectionServiceTest.java
+│ ├── CollectionServiceIntegrationTest.java
+│ ├── SchemaServiceTest.java
+│ └── SchemaServiceIntegrationTest.java
+└── containerization/
+ ├── DockerImageStdioIntegrationTest.java
+ └── DockerImageHttpIntegrationTest.java
+```
+
+## Dependency Management
+
+All dependencies are managed via Gradle version catalogs in
`gradle/libs.versions.toml`:
+
+- Centralized version management
+- Easy upgrades and consistency
+- Clear dependency organization
+
+## Configuration Properties
+
+### Solr Connection
+- `SOLR_URL`: Solr instance URL (default: `http://localhost:8983/solr/`)
+
+### Transport Mode
+- `PROFILES`: Set to `stdio` or `http` to select transport mode
+
+### Docker Compose
+- `SPRING_DOCKER_COMPOSE_ENABLED`: Enable/disable Docker Compose integration
+
+## Future Considerations
+
+### Potential Enhancements
+
+1. **Authentication & Authorization**
+ - OAuth2 support for HTTP mode
+ - Token-based authentication
+ - Role-based access control
+
+2. **Additional Tools**
+ - Bulk operations
+ - Query suggestions
+ - Analytics and reporting
+
+3. **Performance**
+ - Response streaming for large result sets
+ - Query caching
+ - Connection pooling optimization
+
+4. **Monitoring**
+ - Metrics collection
+ - Health checks
+ - Performance monitoring
+
+5. **Multi-Solr Support**
+ - Connect to multiple Solr instances
+ - Cross-cluster operations
diff --git a/dev-docs/DEPLOYMENT.md b/dev-docs/DEPLOYMENT.md
new file mode 100644
index 0000000..c4f7d8a
--- /dev/null
+++ b/dev-docs/DEPLOYMENT.md
@@ -0,0 +1,372 @@
+# Deployment Guide
+
+This guide covers building Docker images, publishing to registries, and
deploying the Solr MCP Server.
+
+## Docker Images with Jib
+
+This project uses [Jib](https://github.com/GoogleContainerTools/jib) to build
optimized Docker images. Jib creates layered images for faster rebuilds and
smaller sizes.
+
+### Build to Docker Daemon
+
+Build directly to your local Docker daemon (requires Docker installed):
+
+```bash
+./gradlew jibDockerBuild
+```
+
+This creates: `solr-mcp:0.0.1-SNAPSHOT`
+
+Verify:
+```bash
+docker images | grep solr-mcp
+```
+
+### Push to Docker Hub
+
+Authenticate and push (no local Docker daemon required):
+
+```bash
+# Login to Docker Hub
+docker login
+
+# Build and push
+./gradlew jib -Djib.to.image=YOUR_DOCKERHUB_USERNAME/solr-mcp:0.0.1-SNAPSHOT
+```
+
+### Push to GitHub Container Registry
+
+Authenticate and push (no local Docker daemon required):
+
+```bash
+# Create Personal Access Token with write:packages scope:
+# https://github.com/settings/tokens
+
+# Login to GHCR
+export GITHUB_TOKEN=YOUR_GITHUB_TOKEN
+echo $GITHUB_TOKEN | docker login ghcr.io -u YOUR_GITHUB_USERNAME
--password-stdin
+
+# Build and push
+./gradlew jib
-Djib.to.image=ghcr.io/YOUR_GITHUB_USERNAME/solr-mcp:0.0.1-SNAPSHOT
+```
+
+### Multi-Platform Support
+
+Docker images are built with multi-platform support for:
+- `linux/amd64` (Intel/AMD 64-bit)
+- `linux/arm64` (Apple Silicon M1/M2/M3/M4/M5)
+
+Jib automatically selects the appropriate platform or builds the first
specified platform.
+
+## Running Docker Containers
+
+### STDIO Mode (Default)
+
+```bash
+docker run -i --rm solr-mcp:0.0.1-SNAPSHOT
+```
+
+With custom Solr URL:
+```bash
+docker run -i --rm \
+ -e SOLR_URL=http://your-solr-host:8983/solr/ \
+ solr-mcp:0.0.1-SNAPSHOT
+```
+
+### HTTP Mode
+
+```bash
+docker run -p 8080:8080 --rm \
+ -e PROFILES=http \
+ -e SOLR_URL=http://your-solr-host:8983/solr/ \
+ solr-mcp:0.0.1-SNAPSHOT
+```
+
+### Linux Host Networking
+
+On Linux, to connect to Solr on the host machine:
+
+```bash
+docker run -i --rm \
+ --add-host=host.docker.internal:host-gateway \
+ -e SOLR_URL=http://host.docker.internal:8983/solr/ \
+ solr-mcp:0.0.1-SNAPSHOT
+```
+
+## GitHub Actions CI/CD
+
+### Workflows
+
+- `.github/workflows/build-and-publish.yml` — Build, test, and publish Docker
images
+- `.github/workflows/publish-mcp.yml` — Publish to the Model Context Protocol
Registry on version tags
+
+### Docker image publishing
+
+Automated Docker image publishing is not configured in this repository.
+To publish images, use Jib from your local machine or set up your own workflow:
+
+- Docker Hub:
+ ```bash
+ docker login
+ ./gradlew jib -Djib.to.image=DOCKERHUB_USERNAME/solr-mcp:0.0.1-SNAPSHOT
+ ```
+- GitHub Container Registry (GHCR):
+ ```bash
+ export GITHUB_TOKEN=YOUR_GITHUB_TOKEN
+ echo $GITHUB_TOKEN | docker login ghcr.io -u YOUR_GITHUB_USERNAME
--password-stdin
+ ./gradlew jib
-Djib.to.image=ghcr.io/YOUR_GITHUB_USERNAME/solr-mcp:0.0.1-SNAPSHOT
+ ```
+
+### MCP Registry Publishing
+
+`.github/workflows/publish-mcp.yml` publishes to the Model Context Protocol
Registry.
+
+**Triggers:**
+- Version tags (e.g., `v0.1.0`)
+- Manual workflow dispatch
+
+**Authentication:**
+Uses GitHub OIDC (no secrets required)
+
+**Publishing Process:**
+
+1. Tag a release:
+ ```bash
+ git tag v0.1.0
+ git push origin v0.1.0
+ ```
+
+2. GitHub Actions automatically:
+ - Updates `server.json` version
+ - Authenticates with MCP Registry via OIDC
+ - Publishes server metadata
+ - Verifies publication
+
+3. Verify in registry:
+ ```bash
+ curl
"https://registry.modelcontextprotocol.io/v0/servers?search=io.github.apache/solr-mcp"
+ ```
+
+## MCP Registry Configuration
+
+### server.json
+
+The `server.json` file defines MCP registry metadata:
+
+```json
+{
+ "$schema":
"https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json",
+ "name": "io.github.apache/solr-mcp",
+ "description": "MCP server for Apache Solr",
+ "version": "0.0.1",
+ "packages": [
+ {
+ "registryType": "docker",
+ "identifier": "ghcr.io/apache/solr-mcp",
+ "version": "0.0.1-SNAPSHOT",
+ "transport": {
+ "type": "stdio"
+ }
+ }
+ ]
+}
+```
+
+### Docker Image Label
+
+The Docker image includes an MCP label for registry discovery:
+
+```kotlin
+labels.set(
+ mapOf(
+ "io.modelcontextprotocol.server.name" to "io.github.apache/solr-mcp"
+ )
+)
+```
+
+## Manual MCP Registry Publishing
+
+If you need to publish manually:
+
+1. **Install MCP Publisher CLI**
+ ```bash
+ # macOS
+ brew install modelcontextprotocol/tap/mcp-publisher
+
+ # Or download from GitHub releases
+ curl -L
https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher-[OS]-[ARCH].tar.gz
| tar xz
+ ```
+
+2. **Authenticate**
+ ```bash
+ # GitHub OIDC (recommended)
+ mcp-publisher login github-oidc
+
+ # Or with token
+ export MCP_GITHUB_TOKEN=your_token
+ mcp-publisher login github
+ ```
+
+3. **Publish**
+ ```bash
+ mcp-publisher publish
+ ```
+
+## Docker Executable Configuration
+
+Jib auto-detects Docker based on your operating system:
+
+- **macOS**: `/usr/local/bin/docker`
+- **Linux**: `/usr/bin/docker`
+- **Windows**: `C:\Program Files\Docker\Docker\resources\bin\docker.exe`
+
+Override if needed:
+```bash
+export DOCKER_EXECUTABLE=/custom/path/to/docker
+./gradlew jibDockerBuild
+```
+
+Or in `gradle.properties`:
+```properties
+systemProp.DOCKER_EXECUTABLE=/custom/path/to/docker
+```
+
+## Production Deployment
+
+### Using Docker Compose
+
+Example `compose.yaml`:
+
+```yaml
+version: '3.8'
+
+services:
+ solr:
+ image: solr:9.9-slim
+ ports:
+ - "8983:8983"
+ volumes:
+ - solr_data:/var/solr
+
+ solr-mcp:
+ image: ghcr.io/apache/solr-mcp:latest
+ environment:
+ - SOLR_URL=http://solr:8983/solr/
+ - PROFILES=http
+ ports:
+ - "8080:8080"
+ depends_on:
+ - solr
+
+volumes:
+ solr_data:
+```
+
+### Using Kubernetes
+
+Example deployment:
+
+```yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: solr-mcp
+spec:
+ replicas: 2
+ selector:
+ matchLabels:
+ app: solr-mcp
+ template:
+ metadata:
+ labels:
+ app: solr-mcp
+ spec:
+ containers:
+ - name: solr-mcp
+ image: ghcr.io/apache/solr-mcp:latest
+ env:
+ - name: SOLR_URL
+ value: "http://solr-service:8983/solr/"
+ - name: PROFILES
+ value: "http"
+ ports:
+ - containerPort: 8080
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: solr-mcp
+spec:
+ selector:
+ app: solr-mcp
+ ports:
+ - port: 8080
+ targetPort: 8080
+```
+
+## Security Considerations
+
+### STDIO Transport
+- Recommended for local deployments
+- No network exposure
+- OS-level process isolation
+- Secure by default
+
+### HTTP Transport
+⚠️ **Warning**: HTTP mode is insecure without additional measures.
+
+**Production requirements:**
+1. **Use HTTPS** with TLS/SSL certificates
+2. **Implement OAuth2** authentication (see [Spring AI MCP OAuth2
guide](https://spring.io/blog/2025/04/02/mcp-server-oauth2/))
+3. **Validate origin headers** to prevent DNS rebinding
+4. **Network isolation** via firewall/VPN
+5. **API Gateway** with rate limiting
+
+**Recommendation:**
+- Local development: HTTP on localhost only
+- Claude Desktop: Always use STDIO
+- Production remote: HTTP + OAuth2 + HTTPS + proper network security
+
+## Monitoring
+
+### Health Checks
+
+The server exposes Spring Boot Actuator endpoints:
+
+```bash
+# Health check
+curl http://localhost:8080/actuator/health
+
+# Build info
+curl http://localhost:8080/actuator/info
+```
+
+### Docker Health Check
+
+Add to Dockerfile or compose.yaml:
+
+```yaml
+healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 40s
+```
+
+## Backup and Recovery
+
+### Solr Data
+
+Backup Solr collections regularly:
+```bash
+# Using Solr API
+curl
"http://localhost:8983/solr/admin/collections?action=BACKUP&name=backup1&collection=books&location=/backup"
+```
+
+### Configuration
+
+Version control all configuration files:
+- `application.properties`
+- `server.json`
+- Docker Compose files
+- Kubernetes manifests
diff --git a/dev-docs/DEVELOPMENT.md b/dev-docs/DEVELOPMENT.md
new file mode 100644
index 0000000..28759f6
--- /dev/null
+++ b/dev-docs/DEVELOPMENT.md
@@ -0,0 +1,319 @@
+# Development Guide
+
+This guide covers development workflows, testing, and building the Solr MCP
Server.
+
+## Build System
+
+This project uses Gradle with version catalogs for dependency management. All
dependencies and their versions are centrally managed in
`gradle/libs.versions.toml`.
+
+### Common Gradle Tasks
+
+```bash
+# Build the project and run tests
+./gradlew build
+
+# Build without tests (faster)
+./gradlew assemble
+
+# Clean and rebuild
+./gradlew clean build
+
+# Run tests only
+./gradlew test
+
+# Run Docker integration tests
+./gradlew dockerIntegrationTest
+
+# Check code formatting
+./gradlew spotlessCheck
+
+# Apply code formatting
+./gradlew spotlessApply
+```
+
+### Build Outputs
+
+The build produces an executable JAR in `build/libs/`:
+
+- `solr-mcp-0.0.1-SNAPSHOT.jar` — Spring Boot executable (fat) JAR
+
+## Running Locally
+
+### Start Solr
+
+```bash
+docker compose up -d
+```
+
+This starts a Solr instance in SolrCloud mode with ZooKeeper and creates two
sample collections:
+- `books` - Collection with sample book data
+- `films` - Collection with sample film data
+
+### Run the Server
+
+#### STDIO Mode (Default)
+
+```bash
+./gradlew bootRun
+```
+
+Or using the JAR:
+```bash
+java -jar build/libs/solr-mcp-0.0.1-SNAPSHOT.jar
+```
+
+#### HTTP Mode
+
+```bash
+./gradlew bootRun --args='--spring.profiles.active=http'
+```
+
+The server will start on http://localhost:8080
+
+### Environment Variables
+
+- `SOLR_URL`: Solr instance URL (default: `http://localhost:8983/solr/`)
+- `PROFILES`: Transport mode (`stdio` or `http`)
+- `SPRING_DOCKER_COMPOSE_ENABLED`: Enable/disable Docker Compose integration
(default: `true`)
+
+Example:
+```bash
+SOLR_URL=http://my-solr:8983/solr/ ./gradlew bootRun
+```
+
+## Testing
+
+### Unit Tests
+
+Unit tests use mocked dependencies for fast, isolated testing:
+
+```bash
+# Run all unit tests
+./gradlew test
+
+# Run specific test class
+./gradlew test --tests SearchServiceTest
+
+# Run with coverage
+./gradlew test jacocoTestReport
+```
+
+### Integration Tests
+
+Integration tests use Testcontainers to spin up real Solr instances:
+
+```bash
+# Run integration tests
+./gradlew test --tests "*IntegrationTest"
+```
+
+### Docker Integration Tests
+
+These tests verify the Docker images built by Jib:
+
+```bash
+# Build Docker image first
+./gradlew jibDockerBuild
+
+# Run Docker integration tests
+./gradlew dockerIntegrationTest
+```
+
+This runs tests tagged with `@Tag("docker-integration")` which verify:
+- STDIO mode functionality
+- HTTP mode functionality
+- Container stability
+- Solr connectivity
+
+### Test with MCP Inspector
+
+The [MCP Inspector](https://github.com/modelcontextprotocol/inspector)
provides a web UI for testing:
+
+```bash
+# Start the server in HTTP mode
+./gradlew bootRun --args='--spring.profiles.active=http'
+
+# In another terminal, start MCP Inspector
+npx @modelcontextprotocol/inspector
+```
+
+Then open the browser URL provided (typically http://localhost:6274) and
connect to http://localhost:8080/mcp
+
+## Code Quality
+
+### Spotless Formatting
+
+This project uses Spotless for consistent code formatting:
+
+```bash
+# Check if code is formatted correctly
+./gradlew spotlessCheck
+
+# Auto-format all code
+./gradlew spotlessApply
+```
+
+**Important**: Always run `spotlessApply` before committing. The CI will
reject PRs with formatting issues.
+
+### Error Prone
+
+Error Prone is configured to catch common Java mistakes at compile time. It
will fail the build if issues are found.
+
+## Build Info
+
+The project generates build metadata at build time via the Spring Boot Gradle
plugin. This creates `META-INF/build-info.properties` containing:
+
+- `build.artifact`: Artifact name (e.g., "solr-mcp")
+- `build.group`: Group ID (e.g., "org.apache.solr")
+- `build.name`: Project name
+- `build.version`: Version (e.g., "0.0.1-SNAPSHOT")
+- `build.time`: Build timestamp
+
+This metadata is used by:
+- Spring Boot Actuator (`/actuator/info` endpoint)
+- Test utilities (e.g., `BuildInfoReader`)
+- Docker image labels
+- Runtime version introspection
+
+## Docker Development
+
+See [DEPLOYMENT.md](DEPLOYMENT.md) for detailed Docker build instructions.
+
+### Quick Docker Build
+
+```bash
+# Build to local Docker daemon
+./gradlew jibDockerBuild
+
+# Run the image
+docker run -i --rm solr-mcp:0.0.1-SNAPSHOT
+```
+
+### Docker Executable Configuration
+
+Jib needs to find the Docker executable. The build auto-detects based on your
OS:
+
+- **macOS**: `/usr/local/bin/docker`
+- **Linux**: `/usr/bin/docker`
+- **Windows**: `C:\Program Files\Docker\Docker\resources\bin\docker.exe`
+
+Override if needed:
+```bash
+export DOCKER_EXECUTABLE=/custom/path/to/docker
+./gradlew jibDockerBuild
+```
+
+## IDE Setup
+
+### IntelliJ IDEA
+
+1. Open the project directory
+2. IDEA will automatically detect it as a Gradle project
+3. Enable annotation processing for Lombok (if used)
+4. Install Spotless plugin for automatic formatting
+
+### VS Code
+
+1. Install Java Extension Pack
+2. Install Gradle Extension
+3. Open the project directory
+4. VS Code will configure automatically
+
+## Debugging
+
+### Debug STDIO Mode
+
+Since STDIO uses stdin/stdout for protocol communication, traditional
debugging can interfere. Use these approaches:
+
+1. **Log to file**:
+ ```java
+ System.setOut(new PrintStream(new FileOutputStream("debug.log")));
+ ```
+
+2. **Use IDE remote debugging**:
+ ```bash
+ ./gradlew bootRun --debug-jvm
+ ```
+ Then attach your IDE debugger to port 5005
+
+### Debug HTTP Mode
+
+Standard debugging works normally:
+
+1. Start in debug mode in your IDE
+2. Set breakpoints
+3. Make HTTP requests to http://localhost:8080
+
+## Common Development Tasks
+
+### Adding a New MCP Tool
+
+1. Create a new method in an existing service or new service class
+2. Annotate with `@McpTool`:
+ ```java
+ @McpTool(
+ name = "tool_name",
+ description = "What this tool does"
+ )
+ public String myTool(
+ @McpToolParameter(description = "Parameter description")
+ String param
+ ) {
+ // Implementation
+ }
+ ```
+3. Add tests
+4. Update documentation
+
+### Adding a New Document Format
+
+1. Create a new class implementing `IndexingDocumentCreator`
+2. Register in `SolrDocumentCreator` factory
+3. Add tests
+4. Update documentation
+
+### Modifying Configuration
+
+1. Update `application.properties` for defaults
+2. Update profile-specific properties as needed
+3. Update `SolrConfigurationProperties` if adding new properties
+4. Document changes in docs/ (e.g., DEVELOPMENT.md or DEPLOYMENT.md) and link
from README
+
+## Performance Testing
+
+### Load Testing HTTP Mode
+
+Use tools like Apache JMeter or wrk:
+
+```bash
+# Install wrk
+brew install wrk
+
+# Run load test
+wrk -t4 -c100 -d30s http://localhost:8080/mcp
+```
+
+### Profiling
+
+Use Java Flight Recorder:
+
+```bash
+java -XX:StartFlightRecording=duration=60s,filename=recording.jfr \
+ -jar build/libs/solr-mcp-0.0.1-SNAPSHOT.jar
+```
+
+Analyze with Java Mission Control.
+
+## Continuous Integration
+
+The project uses GitHub Actions for CI/CD. See:
+
+- `.github/workflows/build-and-publish.yml` - Build, test, and publish Docker
images
+- `.github/workflows/publish-mcp.yml` - Publish to the MCP Registry on version
tags
+
+Local CI simulation:
+
+```bash
+# Approximate what CI runs
+./gradlew clean build spotlessCheck
+```
diff --git a/dev-docs/TROUBLESHOOTING.md b/dev-docs/TROUBLESHOOTING.md
new file mode 100644
index 0000000..bc2b41d
--- /dev/null
+++ b/dev-docs/TROUBLESHOOTING.md
@@ -0,0 +1,445 @@
+# Troubleshooting Guide
+
+Common issues and solutions when working with the Solr MCP Server.
+
+## Solr Connection Issues
+
+### Cannot connect to Solr
+
+**Symptoms:**
+- Connection refused errors
+- UnknownHostException
+- Timeout errors
+
+**Solutions:**
+
+1. **Verify Solr is running**
+ ```bash
+ docker compose ps
+ # or
+ curl http://localhost:8983/solr/admin/info/system
+ ```
+
+2. **Check SOLR_URL environment variable**
+ ```bash
+ # Should point to your Solr instance
+ export SOLR_URL=http://localhost:8983/solr/
+ ```
+
+3. **Verify network connectivity**
+ ```bash
+ # Test from the MCP server container
+ docker run --rm curlimages/curl:latest \
+ curl -v http://host.docker.internal:8983/solr/admin/info/system
+ ```
+
+4. **Linux users: Add host networking**
+ ```bash
+ docker run -i --rm \
+ --add-host=host.docker.internal:host-gateway \
+ solr-mcp:0.0.1-SNAPSHOT
+ ```
+
+### Collection not found
+
+**Symptoms:**
+- "Collection not found" errors
+- 404 responses from Solr
+
+**Solutions:**
+
+1. **List available collections**
+ ```bash
+ curl "http://localhost:8983/solr/admin/collections?action=LIST"
+ ```
+
+2. **Create missing collection**
+ ```bash
+ docker compose up -d # Creates sample collections
+ # or manually:
+ curl
"http://localhost:8983/solr/admin/collections?action=CREATE&name=books&numShards=1"
+ ```
+
+## Docker Build Issues
+
+### Cannot find docker executable
+
+**Symptoms:**
+```
+Cannot run program "docker": error=2, No such file or directory
+```
+
+**Solutions:**
+
+1. **Verify Docker is installed**
+ ```bash
+ which docker
+ docker --version
+ ```
+
+2. **Set DOCKER_EXECUTABLE environment variable**
+ ```bash
+ export DOCKER_EXECUTABLE=/usr/local/bin/docker
+ ./gradlew jibDockerBuild
+ ```
+
+3. **macOS**: Check Docker Desktop is running
+4. **Linux**: Ensure docker is in PATH
+
+### Jib authentication errors
+
+**Symptoms:**
+- "Unauthorized" when pushing to registry
+- "Access denied" errors
+
+**Solutions:**
+
+1. **Docker Hub**
+ ```bash
+ docker login
+ # Enter username and password
+ ```
+
+2. **GitHub Container Registry**
+ ```bash
+ export GITHUB_TOKEN=your_token
+ echo $GITHUB_TOKEN | docker login ghcr.io -u YOUR_USERNAME --password-stdin
+ ```
+
+3. **Check credentials in ~/.docker/config.json**
+
+### Multi-platform build issues
+
+**Symptoms:**
+- Platform mismatch errors
+- "no matching manifest" errors
+
+**Solution:**
+Jib automatically builds for the local platform or the first specified
platform. For multi-platform publishing, use separate builds or Docker Buildx.
+
+## Claude Desktop Integration
+
+### Server not appearing in Claude Desktop
+
+**Symptoms:**
+- MCP server doesn't show up in Claude Desktop
+- No tools available
+
+**Solutions:**
+
+1. **Verify configuration file location**
+ - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
+ - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
+
+2. **Check JSON syntax**
+ ```bash
+ # Validate JSON
+ cat ~/Library/Application\ Support/Claude/claude_desktop_config.json | jq .
+ ```
+
+3. **Verify JAR path is absolute**
+ ```json
+ {
+ "mcpServers": {
+ "solr-search-mcp": {
+ "command": "java",
+ "args": ["-jar", "/absolute/path/to/solr-mcp-0.0.1-SNAPSHOT.jar"]
+ }
+ }
+ }
+ ```
+
+4. **Check logs**
+ - macOS: `~/Library/Logs/Claude/`
+ - Windows: `%APPDATA%\Claude\logs\`
+
+5. **Restart Claude Desktop** after configuration changes
+
+### Tools not working / timeout errors
+
+**Symptoms:**
+- Tool calls timeout
+- No response from server
+- Connection errors
+
+**Solutions:**
+
+1. **Test server manually**
+ ```bash
+ # STDIO mode - should start without errors
+ java -jar build/libs/solr-mcp-0.0.1-SNAPSHOT.jar
+
+ # HTTP mode
+ curl http://localhost:8080/actuator/health
+ ```
+
+2. **Check environment variables**
+ ```json
+ {
+ "mcpServers": {
+ "solr-search-mcp": {
+ "env": {
+ "SOLR_URL": "http://localhost:8983/solr/"
+ }
+ }
+ }
+ }
+ ```
+
+3. **Verify Solr is accessible** from the MCP server
+
+### STDIO output corruption
+
+**Symptoms:**
+- Garbled output
+- Protocol errors
+- JSON parse errors
+
+**Solutions:**
+
+1. **Ensure clean stdout** - No debug logging to stdout
+2. **Check for System.out.println()** in code
+3. **Redirect logging to file** instead of stdout
+4. **Use Docker image** built with Jib (clean stdout guaranteed)
+
+## Build and Test Issues
+
+### Tests failing
+
+**Symptoms:**
+- Test failures during `./gradlew build`
+- Integration test errors
+
+**Solutions:**
+
+1. **Ensure Solr is running** for integration tests
+ ```bash
+ docker compose up -d
+ ```
+
+2. **Check Docker is available** for Docker integration tests
+ ```bash
+ docker info
+ ```
+
+3. **Run specific test** to isolate issue
+ ```bash
+ ./gradlew test --tests SearchServiceTest
+ ```
+
+4. **Check test logs** in `build/reports/tests/test/index.html`
+
+5. **Clean and rebuild**
+ ```bash
+ ./gradlew clean build
+ ```
+
+### Spotless formatting errors
+
+**Symptoms:**
+```
+Task :spotlessJavaCheck FAILED
+The following files had format violations:
+```
+
+**Solution:**
+```bash
+./gradlew spotlessApply
+```
+
+### Gradle build cache issues
+
+**Symptoms:**
+- Stale build outputs
+- Unexpected behavior after changes
+
+**Solution:**
+```bash
+# Clean Gradle cache
+./gradlew clean --no-build-cache
+
+# Nuclear option: delete .gradle directory
+rm -rf .gradle
+./gradlew clean build
+```
+
+## MCP Inspector Issues
+
+### Cannot connect to HTTP server
+
+**Symptoms:**
+- MCP Inspector shows connection errors
+- CORS errors in browser console
+
+**Solutions:**
+
+1. **Verify server is running in HTTP mode**
+ ```bash
+ ./gradlew bootRun --args='--spring.profiles.active=http'
+ ```
+
+2. **Check port is correct**
+ ```bash
+ # Should return health status
+ curl http://localhost:8080/actuator/health
+ ```
+
+3. **Configure MCP endpoint** in Inspector
+ - URL: `http://localhost:8080/mcp`
+ - Transport: Streamable HTTP
+
+## Performance Issues
+
+### Slow responses
+
+**Symptoms:**
+- Slow tool execution
+- Timeouts
+
+**Solutions:**
+
+1. **Check Solr performance**
+ ```bash
+ curl "http://localhost:8983/solr/admin/metrics"
+ ```
+
+2. **Optimize Solr queries**
+ - Add filter queries
+ - Limit rows returned
+ - Use appropriate fields
+
+3. **Check resource usage**
+ ```bash
+ # Docker stats
+ docker stats
+
+ # Java heap
+ jstat -gc <pid>
+ ```
+
+4. **Increase timeouts** if needed
+
+### Memory issues
+
+**Symptoms:**
+- OutOfMemoryError
+- Container crashes
+
+**Solutions:**
+
+1. **Increase JVM heap**
+ ```bash
+ export JAVA_OPTS="-Xmx2g -Xms512m"
+ java $JAVA_OPTS -jar build/libs/solr-mcp-0.0.1-SNAPSHOT.jar
+ ```
+
+2. **Docker container limits**
+ ```bash
+ docker run -m 2g --rm solr-mcp:0.0.1-SNAPSHOT
+ ```
+
+3. **Check for memory leaks**
+ - Use Java Flight Recorder
+ - Analyze heap dumps
+
+## Common Error Messages
+
+### "build-info.properties not found"
+
+**Cause:** Project not built with Gradle
+
+**Solution:**
+```bash
+./gradlew build
+```
+
+### "Failed to read output of 'docker info'"
+
+**Cause:** Docker not accessible to Gradle
+
+**Solution:** See "Cannot find docker executable" above
+
+### "No matching manifest for linux/amd64"
+
+**Cause:** Docker image not available for your platform
+
+**Solution:**
+```bash
+# Build for your platform
+./gradlew jibDockerBuild
+```
+
+### "Port 8080 already in use"
+
+**Cause:** Another service using port 8080
+
+**Solution:**
+```bash
+# Find and kill process using port 8080
+lsof -ti:8080 | xargs kill -9
+
+# Or change port
+java -Dserver.port=8081 -jar build/libs/solr-mcp-0.0.1-SNAPSHOT.jar
+```
+
+## Getting Help
+
+If you're still having issues:
+
+1. **Check existing issues**: https://github.com/apache/solr-mcp/issues
+2. **Enable debug logging**:
+ ```bash
+ export LOGGING_LEVEL_ORG_APACHE_SOLR_MCP=DEBUG
+ ./gradlew bootRun
+ ```
+3. **Collect information**:
+ - Error messages and stack traces
+ - Environment (OS, Java version, Docker version)
+ - Steps to reproduce
+ - Logs from server and Solr
+4. **Open an issue** with collected information
+
+## Logs and Diagnostics
+
+### Server Logs
+
+```bash
+# STDIO mode - logs to stderr
+./gradlew bootRun 2>&1 | tee server.log
+
+# HTTP mode - Spring Boot logging
+./gradlew bootRun --args='--spring.profiles.active=http'
+```
+
+### Solr Logs
+
+```bash
+# Docker Compose
+docker compose logs solr
+
+# Follow logs
+docker compose logs -f solr
+```
+
+### Docker Logs
+
+```bash
+# Container logs
+docker logs <container_id>
+
+# Follow logs
+docker logs -f <container_id>
+```
+
+### Actuator Endpoints
+
+```bash
+# Health check
+curl http://localhost:8080/actuator/health
+
+# Build info
+curl http://localhost:8080/actuator/info
+
+# All endpoints
+curl http://localhost:8080/actuator
+```