diff --git a/.github/workflows/atr-release.yml b/.github/workflows/atr-release.yml
index bbb2b86b..15cb8e45 100644
--- a/.github/workflows/atr-release.yml
+++ b/.github/workflows/atr-release.yml
@@ -29,7 +29,7 @@
# 3. Request ATR onboarding from dev@tooling.apache.org
#
# STATUS: Workflow is ready but prerequisites are not met
-# See: dev-docs/ATR_TESTING_GUIDE.md for complete implementation path
+# See: docs/development/ATR_TESTING_GUIDE.md for complete implementation path
#
# WHEN TO USE:
# -----------
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4c957e08..55cb6fa9 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -4,21 +4,21 @@ Thank you for your interest in contributing to the Solr MCP Server! This documen
## Developer documentation
-To avoid duplication, the environment setup, build/run/test workflows, and detailed developer guides live in the dev-docs folder:
+To avoid duplication, the environment setup, build/run/test workflows, and detailed developer guides live in the [docs/development](docs/development) 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
+- [Development Guide](docs/development/DEVELOPMENT.md) -- build, run, test, IDE, CI
+- [Architecture](docs/development/ARCHITECTURE.md) -- project structure and design decisions
+- [Deployment](docs/development/DEPLOYMENT.md) -- Docker, HTTP vs STDIO
+- [Troubleshooting](docs/development/TROUBLESHOOTING.md) -- common issues and solutions
-If you're ready to contribute code, see Submitting Changes below.
+If you're ready to contribute code, see [Submitting Changes](#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
+- [Commands and details](docs/development/DEVELOPMENT.md#common-gradle-tasks)
+- [Build system overview](docs/development/DEVELOPMENT.md#build-system)
### Coding Standards
@@ -32,11 +32,11 @@ We use Spotless for code formatting and style enforcement. CI enforces `spotless
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
+- [Testing overview](docs/development/DEVELOPMENT.md#testing)
+- [Unit tests](docs/development/DEVELOPMENT.md#unit-tests)
+- [Integration tests](docs/development/DEVELOPMENT.md#integration-tests)
+- [Docker image tests](docs/development/DEVELOPMENT.md#docker-integration-tests)
+- [Coverage reports](docs/development/DEVELOPMENT.md#testing)
## Publishing to Maven Local
@@ -131,21 +131,28 @@ test: add integration tests for collection service
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
+- [Adding new MCP tools](docs/development/DEVELOPMENT.md#adding-a-new-mcp-tool)
+- [Adding a new document format](docs/development/DEVELOPMENT.md#adding-a-new-document-format)
+- [Project structure and architecture](docs/development/ARCHITECTURE.md)
+- [Dependencies and version catalogs](docs/development/DEVELOPMENT.md#build-system)
+- [Documentation practices](docs/development/DEVELOPMENT.md#modifying-configuration)
+
+## Security Setup (HTTP Mode)
+
+For OAuth2 configuration with supported providers:
+
+- [Auth0 Setup Guide](docs/development/AUTH0_SETUP.md)
+- [Keycloak Setup Guide](docs/development/keycloak.md)
## 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
+- **Slack:** [`#solr-mcp`](https://the-asf.slack.com/archives/C09TVG3BM1P) in the `the-asf` workspace
+- **Issues:** [GitHub Issues](https://github.com/apache/solr-mcp/issues) for bugs or feature requests
+- **Mailing lists:** Shared with Apache Solr -- see [mailing lists](https://solr.apache.org/community.html#mailing-lists-chat)
## Code of Conduct
-Be respectful, inclusive, and professional. We're all here to build something great together.
+As an Apache project, we follow the [Apache Code of Conduct](https://www.apache.org/foundation/policies/conduct).
## License
diff --git a/README.md b/README.md
index 7bc57401..e1dff42e 100644
--- a/README.md
+++ b/README.md
@@ -1,380 +1,449 @@
[](https://github.com/apache/solr-mcp)
-# Solr MCP Server
-
-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
-- ๐ Create collections with configurable shards, replicas, and configsets
-- ๐ Manage collections and view statistics
-- ๐ง Inspect schema
-- ๐ Transports: STDIO (Claude Desktop) and HTTP (MCP Inspector)
-- ๐ OAuth2 security with Auth0 (HTTP mode only)
-- ๐ณ 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:
- - **STDIO mode (default)**:
- - Gradle:
- ```bash
- ./gradlew bootRun
- ```
- - JAR:
- ```bash
- ./gradlew build
- java -jar build/libs/solr-mcp-1.0.0-SNAPSHOT.jar
- ```
- - Docker:
- ```bash
- docker run -i --rm ghcr.io/apache/solr-mcp:latest
- ```
- - **HTTP mode**:
- - Gradle:
- ```bash
- PROFILES=http ./gradlew bootRun
- ```
- - JAR:
- ```bash
- PROFILES=http java -jar build/libs/solr-mcp-1.0.0-SNAPSHOT.jar
- ```
- - Docker:
- ```bash
- docker run -p 8080:8080 --rm -e PROFILES=http ghcr.io/apache/solr-mcp:latest
- ```
-
-For more options (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.
-
-**STDIO mode (default)**
-
-Using Docker:
+# Apache Solr MCP Server
+
+Search, index, and manage [Apache Solr](https://solr.apache.org/) collections using **natural language** -- no need to hand-craft Solr queries, build filter expressions, or memorize the admin API.
+
+Instead of writing:
+
+```
+q=title:"star wars" AND genre_s:"sci-fi"&fq=year_i:[2000 TO *]&facet=true&facet.field=genre_s&sort=score desc&rows=10
+```
+
+Just ask your AI assistant:
+
+> *"Find sci-fi movies with 'star wars' in the title released after 2000, show me the genre breakdown, and sort by relevance."*
+
+The Solr MCP Server implements the [Model Context Protocol (MCP)](https://spec.modelcontextprotocol.io/) to expose Solr operations as tools that any MCP-compatible AI client can invoke.
+
+**[Website](https://solr.apache.org/mcp)** ยท
+**[Quick Start](https://solr.apache.org/mcp/quick-start.html)** ยท
+**[Client Setup](https://solr.apache.org/mcp/clients/claude-desktop.html)** ยท
+**[Features](https://solr.apache.org/mcp/features.html)**
+
+## Features
+
+### MCP Tools
+
+| Tool | Description |
+|------|-------------|
+| `search` | Full-text search with filtering, faceting, sorting, and pagination |
+| `index-json-documents` | Index documents from a JSON array |
+| `index-csv-documents` | Index documents from CSV (first row = headers) |
+| `index-xml-documents` | Index documents from XML |
+| `list-collections` | List all Solr collections |
+| `get-collection-stats` | Collection metrics: index stats, query performance, cache hit ratios |
+| `check-health` | Health check with status, document count, and responsiveness |
+| `create-collection` | Create a collection with configurable shards, replicas, and configset |
+| `get-schema` | Retrieve field definitions, field types, dynamic fields, copy fields |
+
+### MCP Resources
+
+| Resource URI | Description |
+|---|---|
+| `solr://collections` | List of all Solr collections in the cluster |
+| `solr://{collection}/schema` | Schema definition for a collection (supports autocompletion) |
+
+### Platform
+
+- **Transports**: STDIO (Claude Desktop, Claude Code) and HTTP (remote access, multi-client)
+- **Security**: OAuth2 with JWT validation (Auth0, Keycloak, Okta) in HTTP mode
+- **Observability**: OpenTelemetry traces, Prometheus metrics, structured logs via LGTM stack
+- **Docker**: Multi-platform images (amd64 + arm64) built with Jib
+
+## Quick Start
+
+Get from zero to a working Claude + Solr integration in under 2 minutes.
+
+**Prerequisites:** Java 25+, [Docker](https://docs.docker.com/get-docker/) and Docker Compose, an MCP client (e.g., [Claude Desktop](https://claude.ai/download))
+
+### 1. Start Solr with sample data
+
+```bash
+git clone https://github.com/apache/solr-mcp.git
+cd solr-mcp
+docker compose up -d
+```
+
+This starts Solr in SolrCloud mode with two sample collections: **films** (1,100+ movies) and **books** (empty, ready for indexing). Wait ~30 seconds, then verify at http://localhost:8983/solr/.
+
+### 2. Build the server
+
+```bash
+./gradlew build
+```
+
+### 3. Configure Claude Desktop
+
+Add to your config file (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows):
+
```json
{
"mcpServers": {
"solr-mcp": {
- "command": "docker",
- "args": ["run", "-i", "--rm", "ghcr.io/apache/solr-mcp:latest"],
- "env": {
- "SOLR_URL": "http://localhost:8983/solr/"
- }
+ "command": "java",
+ "args": ["-jar", "/absolute/path/to/solr-mcp/build/libs/solr-mcp-1.0.0-SNAPSHOT.jar"],
+ "env": { "SOLR_URL": "http://localhost:8983/solr/" }
}
}
}
```
-Using JAR:
+Restart Claude Desktop.
+
+### 4. Try it out
+
+- *"Search the films collection for movies directed by Steven Spielberg"*
+- *"What collections are available in Solr?"*
+- *"Show me the schema for the films collection"*
+- *"Index this JSON into the books collection: [{"id": "1", "title": "The Great Gatsby", "author": "F. Scott Fitzgerald"}]"*
+
+> For more clients (Claude Code, VS Code, Cursor, JetBrains), see **[Adding to AI Clients](https://solr.apache.org/mcp/clients/claude-desktop.html)** on the website.
+
+## Adding to AI Clients
+
+
+Claude Desktop
+
+#### STDIO Mode (recommended)
+
+**JAR:**
```json
{
- "mcpServers": {
- "solr-mcp": {
- "command": "java",
- "args": [
- "-jar",
- "/absolute/path/to/solr-mcp-1.0.0-SNAPSHOT.jar"
- ],
- "env": {
- "SOLR_URL": "http://localhost:8983/solr/"
- }
- }
+ "mcpServers": {
+ "solr-mcp": {
+ "command": "java",
+ "args": ["-jar", "/absolute/path/to/solr-mcp-1.0.0-SNAPSHOT.jar"],
+ "env": { "SOLR_URL": "http://localhost:8983/solr/" }
}
+ }
}
```
-**HTTP mode**
-
-Using Docker:
+**Docker (local image):**
```json
{
- "mcpServers": {
- "solr-mcp": {
- "command": "docker",
- "args": [
- "run",
- "-p",
- "8080:8080",
- "--rm",
- "ghcr.io/apache/solr-mcp:latest"
- ],
- "env": {
- "PROFILES": "http",
- "SOLR_URL": "http://localhost:8983/solr/"
- }
- }
+ "mcpServers": {
+ "solr-mcp": {
+ "command": "docker",
+ "args": ["run", "-i", "--rm",
+ "-e", "SOLR_URL=http://host.docker.internal:8983/solr/",
+ "solr-mcp:latest"]
}
+ }
}
```
-Using JAR:
+Build the local image first: `./gradlew jibDockerBuild`
+
+**Linux users:** add `--add-host=host.docker.internal:host-gateway` to Docker args.
+
+#### HTTP Mode
+
+Start the server first (`PROFILES=http ./gradlew bootRun`), then:
```json
{
- "mcpServers": {
- "solr-mcp": {
- "command": "java",
- "args": [
- "-jar",
- "/absolute/path/to/solr-mcp-1.0.0-SNAPSHOT.jar"
- ],
- "env": {
- "PROFILES": "http",
- "SOLR_URL": "http://localhost:8983/solr/"
- }
+ "mcpServers": {
+ "solr-mcp": {
+ "command": "npx",
+ "args": ["mcp-remote", "http://localhost:8080/mcp"]
}
}
}
```
-**Connecting to a running HTTP server**
+
-If you already have the MCP server running in HTTP mode (via Gradle, JAR, or Docker), you can connect Claude Desktop to
-it using `mcp-remote`:
+
+Claude Code
-Running via Gradle:
+#### STDIO Mode (recommended)
+
+**CLI:**
```bash
-PROFILES=http ./gradlew bootRun
+# JAR
+claude mcp add --transport stdio \
+ -e SOLR_URL=http://localhost:8983/solr/ \
+ solr-mcp -- java -jar /absolute/path/to/solr-mcp-1.0.0-SNAPSHOT.jar
+
+# Docker (local image)
+claude mcp add --transport stdio solr-mcp -- \
+ docker run -i --rm -e SOLR_URL=http://host.docker.internal:8983/solr/ \
+ solr-mcp:latest
```
-Running locally (JAR):
+**`.mcp.json`:**
-```bash
-PROFILES=http java -jar build/libs/solr-mcp-1.0.0-SNAPSHOT.jar
+```json
+{
+ "mcpServers": {
+ "solr-mcp": {
+ "type": "stdio",
+ "command": "java",
+ "args": ["-jar", "/absolute/path/to/solr-mcp-1.0.0-SNAPSHOT.jar"],
+ "env": { "SOLR_URL": "http://localhost:8983/solr/" }
+ }
+ }
+}
```
-Running via Docker:
+#### HTTP Mode
+
+Start the server first, then:
```bash
-docker run -p 8080:8080 --rm -e PROFILES=http ghcr.io/apache/solr-mcp:latest
+claude mcp add --transport http solr-mcp http://localhost:8080/mcp
```
-Then add to your `claude_desktop_config.json`:
+Or in `.mcp.json`:
```json
{
- "mcpServers": {
- "solr-mcp-http": {
- "command": "npx",
- "args": [
- "mcp-remote",
- "http://localhost:8080/mcp"
- ]
- }
+ "mcpServers": {
+ "solr-mcp": {
+ "type": "http",
+ "url": "http://localhost:8080/mcp"
}
+ }
}
```
-More configuration options: see the **Building Docker images** section below.
+
-### Claude Code
+
+VS Code / GitHub Copilot
-Add Solr MCP to [Claude Code](https://docs.anthropic.com/en/docs/claude-code) using the CLI or by adding a `.mcp.json` file to your project root.
+Create `.vscode/mcp.json` in your project root:
-**STDIO mode (default)**
+#### STDIO Mode
-Using Docker (CLI):
-```bash
-claude mcp add --transport stdio solr-mcp -- docker run -i --rm ghcr.io/apache/solr-mcp:latest
-```
+**JAR:**
-Using JAR (CLI):
-```bash
-claude mcp add --transport stdio -e SOLR_URL=http://localhost:8983/solr/ solr-mcp -- java -jar /absolute/path/to/solr-mcp-1.0.0-SNAPSHOT.jar
+```json
+{
+ "servers": {
+ "solr-mcp": {
+ "type": "stdio",
+ "command": "java",
+ "args": ["-jar", "/absolute/path/to/solr-mcp-1.0.0-SNAPSHOT.jar"],
+ "env": { "SOLR_URL": "http://localhost:8983/solr/" }
+ }
+ }
+}
```
-Or add to your project's `.mcp.json`:
+**Docker (local image):**
-Using Docker:
```json
{
- "mcpServers": {
+ "servers": {
"solr-mcp": {
"type": "stdio",
"command": "docker",
- "args": ["run", "-i", "--rm", "ghcr.io/apache/solr-mcp:latest"],
- "env": {
- "SOLR_URL": "http://localhost:8983/solr/"
- }
+ "args": ["run", "-i", "--rm",
+ "-e", "SOLR_URL=http://host.docker.internal:8983/solr/",
+ "solr-mcp:latest"]
}
}
}
```
-Using JAR:
+#### HTTP Mode
+
```json
{
- "mcpServers": {
+ "servers": {
"solr-mcp": {
- "type": "stdio",
- "command": "java",
- "args": ["-jar", "/absolute/path/to/solr-mcp-1.0.0-SNAPSHOT.jar"],
- "env": {
- "SOLR_URL": "http://localhost:8983/solr/"
- }
+ "type": "sse",
+ "url": "http://localhost:8080/mcp"
}
}
}
```
-**HTTP mode**
+After adding the configuration, Solr MCP tools are available in GitHub Copilot Chat (Agent mode).
-Start the server first (pick one):
-```bash
-# Gradle
-PROFILES=http ./gradlew bootRun
+
-# JAR
-PROFILES=http java -jar build/libs/solr-mcp-1.0.0-SNAPSHOT.jar
+
+Cursor
-# Docker
-docker run -p 8080:8080 --rm -e PROFILES=http ghcr.io/apache/solr-mcp:latest
-```
+Create `.cursor/mcp.json` in your project root:
-Then add to Claude Code:
-```bash
-claude mcp add --transport http solr-mcp http://localhost:8080/mcp
-```
+#### STDIO Mode
+
+**JAR:**
-Or add to `.mcp.json`:
```json
{
"mcpServers": {
"solr-mcp": {
- "type": "http",
- "url": "http://localhost:8080/mcp"
+ "command": "java",
+ "args": ["-jar", "/absolute/path/to/solr-mcp-1.0.0-SNAPSHOT.jar"],
+ "env": { "SOLR_URL": "http://localhost:8983/solr/" }
}
}
}
```
-## Security (OAuth2)
+**Docker (local image):**
-The Solr MCP server supports OAuth2 authentication when running in HTTP mode, providing secure access control for your
-MCP tools.
+```json
+{
+ "mcpServers": {
+ "solr-mcp": {
+ "command": "docker",
+ "args": ["run", "-i", "--rm",
+ "-e", "SOLR_URL=http://host.docker.internal:8983/solr/",
+ "solr-mcp:latest"]
+ }
+ }
+}
+```
-### Features
+#### HTTP Mode
-- **OAuth2 Resource Server**: JWT token validation using Auth0 (or any OAuth2 provider)
-- **HTTP Mode Only**: Security is only active when using the `http` profile
-- **CORS Support**: Enabled for MCP Inspector compatibility
-- **Machine-to-Machine**: Uses Client Credentials flow for service authentication
+```json
+{
+ "mcpServers": {
+ "solr-mcp": {
+ "url": "http://localhost:8080/mcp"
+ }
+ }
+}
+```
-### Quick Setup
+Or use **Cursor Settings > Features > MCP Servers > Add New MCP Server**.
-1. **Configure Auth0** (see detailed guide: [security-docs/AUTH0_SETUP.md](security-docs/AUTH0_SETUP.md))
- - Create an Auth0 Application (Machine to Machine)
- - Create an Auth0 API with your audience identifier
- - Note your Domain, Client ID, Client Secret, and Audience
+
-2. **Set Environment Variable**:
- ```bash
- export OAUTH2_ISSUER_URI=https://your-tenant.auth0.com/
- export PROFILES=http
- ```
+
+JetBrains IDEs
-3. **Run the Server**:
- ```bash
- ./gradlew bootRun
- ```
+Create `.junie/mcp.json` in your project root:
-4. **Get Access Token** (using convenience script):
- ```bash
- ./scripts/get-auth0-token.sh --domain your-tenant.auth0.com \
- --client-id YOUR_CLIENT_ID \
- --client-secret YOUR_CLIENT_SECRET \
- --audience https://solr-mcp-api
- ```
+#### STDIO Mode
-5. **Use the Token**:
- ```bash
- curl -H "Authorization: Bearer YOUR_TOKEN" \
- http://localhost:8080/mcp
- ```
+**JAR:**
-For complete setup instructions, see [security-docs/AUTH0_SETUP.md](security-docs/AUTH0_SETUP.md)
+```json
+{
+ "mcpServers": {
+ "solr-mcp": {
+ "command": "java",
+ "args": ["-jar", "/absolute/path/to/solr-mcp-1.0.0-SNAPSHOT.jar"],
+ "env": { "SOLR_URL": "http://localhost:8983/solr/" }
+ }
+ }
+}
+```
-## Available MCP tools
+**Docker (local image):**
-### Search
+```json
+{
+ "mcpServers": {
+ "solr-mcp": {
+ "command": "docker",
+ "args": ["run", "-i", "--rm",
+ "-e", "SOLR_URL=http://host.docker.internal:8983/solr/",
+ "solr-mcp:latest"]
+ }
+ }
+}
+```
-| Tool | Description |
-|------|-------------|
-| `search` | Full-text search with filtering, faceting, sorting, and pagination |
+#### HTTP Mode
-### Indexing
+```json
+{
+ "mcpServers": {
+ "solr-mcp": {
+ "url": "http://localhost:8080/mcp"
+ }
+ }
+}
+```
-| Tool | Description |
-|------|-------------|
-| `index-json-documents` | Index documents from a JSON string into a Solr collection |
-| `index-csv-documents` | Index documents from a CSV string into a Solr collection |
-| `index-xml-documents` | Index documents from an XML string into a Solr collection |
+Or use **Settings > Tools > AI Assistant > MCP Servers > Add**.
-### Collections
+
-| Tool | Description |
-|------|-------------|
-| `create-collection` | Create a new Solr collection (configSet, numShards, replicationFactor optional โ default to `_default`, `1`, `1`) |
-| `list-collections` | List all available Solr collections |
-| `get-collection-stats` | Get statistics and metrics for a collection |
-| `check-health` | Check the health status of a collection |
+
+MCP Inspector
-### Schema
+```bash
+npx @modelcontextprotocol/inspector
+```
-| Tool | Description |
-|------|-------------|
-| `get-schema` | Retrieve schema information for a collection |
+**HTTP:** connect to `http://localhost:8080/mcp`
-## Available MCP Resources
+**STDIO:** command `java`, arguments `-jar /absolute/path/to/solr-mcp-1.0.0-SNAPSHOT.jar`
-MCP Resources provide a way to expose data that can be read by MCP clients. The Solr MCP Server provides the following resources:
+
-| Resource URI | Description |
-|--------------|-------------|
-| `solr://collections` | List of all Solr collections available in the cluster |
-| `solr://{collection}/schema` | Schema definition for a specific collection (supports autocompletion) |
+## Configuration
-### Resource Autocompletion
+| Variable | Description | Default |
+|----------|-------------|---------|
+| `SOLR_URL` | Solr base URL | `http://localhost:8983/solr/` |
+| `PROFILES` | Transport mode: `stdio` or `http` | `stdio` |
+| `SECURITY_ENABLED` | Enable OAuth2 authentication (HTTP only) | `false` |
+| `OAUTH2_ISSUER_URI` | OAuth2 issuer URL (Auth0, Keycloak, Okta) | -- |
+| `OTEL_SAMPLING_PROBABILITY` | Tracing sampling rate (0.0--1.0) | `1.0` |
+| `OTEL_TRACES_URL` | OTLP collector endpoint | `http://localhost:4317` |
-The `solr://{collection}/schema` resource supports autocompletion for the `{collection}` parameter. MCP clients can use the completion API to get a list of available collection names.
+## Example Prompts
-
+**Searching:**
+- *"Find sci-fi movies released after 2000 and show the genre breakdown"*
+- *"Search films for movies with 'war' in the title, sorted by year"*
+- *"Show me the top 5 most recent films"*
-
+**Indexing:**
+- *"Index this JSON into the books collection: [{"id": "1", "title": "1984", "author": "George Orwell"}]"*
+- *"Create a new collection called products"*
-## Screenshots
+**Managing:**
+- *"What collections are available?"*
+- *"Is the films collection healthy?"*
+- *"Show me the schema for the films collection"*
+- *"How many documents are in the films collection?"*
-- Claude Desktop (STDIO):
+## Running the Server
- 
+### STDIO mode (default)
-- MCP Inspector (HTTP):
+```bash
+# JAR
+./gradlew build
+java -jar build/libs/solr-mcp-1.0.0-SNAPSHOT.jar
- 
+# Gradle (development)
+./gradlew bootRun
-- MCP Inspector (HTTP with OAuth2 - Success):
+# Docker (local image โ build first with ./gradlew jibDockerBuild)
+docker run -i --rm -e SOLR_URL=http://host.docker.internal:8983/solr/ solr-mcp:latest
+```
- 
+### HTTP mode
-- MCP Inspector (HTTP with OAuth2 - Failure):
+```bash
+# JAR
+PROFILES=http java -jar build/libs/solr-mcp-1.0.0-SNAPSHOT.jar
- 
+# Gradle (development)
+PROFILES=http ./gradlew bootRun
-- MCP Inspector (STDIO):
+# Docker (local image)
+docker run -p 8080:8080 --rm -e PROFILES=http -e SOLR_URL=http://host.docker.internal:8983/solr/ solr-mcp:latest
+```
- 
+The MCP endpoint is available at `http://localhost:8080/mcp`. Verify with `curl http://localhost:8080/actuator/health`.
## Building Docker images
@@ -432,52 +501,23 @@ docker run -p 8080:8080 --rm \
to start regardless of the runtime `PROFILES` value, breaking stdio. So
we ship one native image per transport.
-### Claude Desktop (native, STDIO)
-
-```json
-{
- "mcpServers": {
- "solr-mcp": {
- "command": "docker",
- "args": [
- "run", "-i", "--rm",
- "-e", "SOLR_URL=http://host.docker.internal:8983/solr/",
- "solr-mcp:latest-native"
- ]
- }
- }
-}
-```
-
See [docs/specs/graalvm-native-image.md](docs/specs/graalvm-native-image.md) for the native image design and known risks.
-## Documentation
+## Community
-- [Auth0 Setup (OAuth2 configuration)](security-docs/AUTH0_SETUP.md)
-- [GraalVM native image spec](docs/specs/graalvm-native-image.md)
+- **Website:** https://solr.apache.org/mcp
+- **Slack:** [`#solr-mcp`](https://the-asf.slack.com/archives/C09TVG3BM1P) in the `the-asf` workspace
+- **Mailing lists:** Shared with Apache Solr -- see [mailing lists](https://solr.apache.org/community.html#mailing-lists-chat)
+- **Issues:** https://github.com/apache/solr-mcp/issues
## Contributing
-We welcome contributions!
-
-- Start here: [CONTRIBUTING.md](CONTRIBUTING.md)
-
-## Support
-
-- Issues: https://github.com/apache/solr-mcp/issues
-- Discussions: https://github.com/apache/solr-mcp/discussions
+We welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for build instructions, testing, and PR guidelines.
## License
-Apache License 2.0 โ see LICENSE
+Apache License 2.0 -- see [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0)
## Acknowledgments
-Built with:
-
-- Spring AI MCP โ https://spring.io/projects/spring-ai
-- Apache Solr โ https://solr.apache.org/
-- Jib โ https://github.com/GoogleContainerTools/jib
-- Paketo Cloud Native Buildpacks โ https://paketo.io/
-- Testcontainers โ https://www.testcontainers.org/
-- Spring AI MCP Security โ https://github.com/spring-ai-community/mcp-security
\ No newline at end of file
+Built with [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/), and [Spring AI MCP Security](https://github.com/spring-ai-community/mcp-security).
diff --git a/TESTING_DISTRIBUTED_TRACING.md b/TESTING_DISTRIBUTED_TRACING.md
deleted file mode 100644
index 07af83b6..00000000
--- a/TESTING_DISTRIBUTED_TRACING.md
+++ /dev/null
@@ -1,174 +0,0 @@
-# Distributed Tracing Test Implementation - Complete โ
-
-## Summary
-
-Successfully implemented comprehensive distributed tracing tests for Spring Boot 3.5 using SimpleTracer from micrometer-tracing-test. All distributed tracing unit tests are passing.
-
-## Test Results
-
-### DistributedTracingTest โ
-**Status:** All 6 tests passing
-**Execution time:** ~6 seconds
-**Coverage:**
-- โ
`shouldCreateSpanForSearchServiceMethod()` - Verifies spans are created for @Observed methods
-- โ
`shouldIncludeSpanAttributes()` - Verifies span attributes/tags are set
-- โ
`shouldCreateSpanHierarchy()` - Verifies span creation
-- โ
`shouldSetCorrectSpanKind()` - Verifies span kinds
-- โ
`shouldIncludeServiceNameInResource()` - Verifies service name in spans
-- โ
`shouldRecordSpanDuration()` - Verifies span timing (start/end timestamps)
-
-## Key Implementation Details
-
-### 1. Test Configuration: OpenTelemetryTestConfiguration.java
-
-```java
-@TestConfiguration
-public class OpenTelemetryTestConfiguration {
- @Bean
- @Primary
- public SimpleTracer simpleTracer() {
- return new SimpleTracer();
- }
-}
-```
-
-**How it works:**
-- Provides SimpleTracer as @Primary bean to replace OpenTelemetry tracer
-- Spring Boot's observability auto-configuration connects this to the ObservationRegistry
-- No external infrastructure required for testing
-
-### 2. Test Approach
-
-**Spring Boot 3.5 Observability Stack:**
-```
-@Observed annotation โ Micrometer Observation API โ Micrometer Tracing โ SimpleTracer
-```
-
-**Key API differences:**
-- Method: `tracer.getSpans()` (not `getFinishedSpans()`)
-- Return type: `Deque` (not `List`)
-- Span name format: `"search-service#search"` (kebab-case: `class-name#method-name`)
-
-### 3. Dependencies Added
-
-**Main dependencies** (build.gradle.kts):
-```kotlin
-implementation("io.micrometer:micrometer-tracing-bridge-otel")
-implementation("org.springframework.boot:spring-boot-starter-aop")
-```
-
-**Test dependencies** (libs.versions.toml):
-```kotlin
-micrometer-tracing-test = { module = "io.micrometer:micrometer-tracing-test" }
-awaitility = { module = "org.awaitility:awaitility", version.ref = "awaitility" }
-```
-
-### 4. Test Properties
-
-```properties
-# Disable OTLP export in tests - we're using SimpleTracer instead
-management.otlp.tracing.endpoint=
-management.opentelemetry.logging.export.otlp.enabled=false
-
-# Ensure 100% sampling for tests
-management.tracing.sampling.probability=1.0
-
-# Enable @Observed annotation support
-management.observations.annotations.enabled=true
-```
-
-## Known Issues
-
-### OtlpExportIntegrationTest โ ๏ธ
-**Status:** Disabled
-**Reason:** Jetty HTTP client ClassNotFoundException with LgtmStackContainer
-**Impact:** Low - core distributed tracing functionality is fully tested
-
-The testcontainers-grafana module requires `org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP` which is not properly resolved with the current Jetty BOM configuration. This integration test can be addressed separately or replaced with an alternative approach.
-
-**Workaround options:**
-1. Use a different HTTP client library (Apache HttpClient, OkHttp)
-2. Upgrade to testcontainers-grafana version that doesn't require Jetty
-3. Test OTLP export manually with LGTM Stack container
-4. Use different testing approach (MockWebServer, WireMock)
-
-## Files Modified
-
-### Test Files
-- `src/test/java/org/apache/solr/mcp/server/observability/DistributedTracingTest.java` - 6 comprehensive tests
-- `src/test/java/org/apache/solr/mcp/server/observability/OpenTelemetryTestConfiguration.java` - SimpleTracer configuration
-- `src/test/java/org/apache/solr/mcp/server/observability/OtlpExportIntegrationTest.java` - Disabled (Jetty issue)
-- `src/test/java/org/apache/solr/mcp/server/observability/LgtmAssertions.java` - LGTM Stack query helpers (ready for use)
-- `src/test/java/org/apache/solr/mcp/server/observability/TraceAssertions.java` - Span assertion utilities
-
-### Configuration Files
-- `build.gradle.kts` - Added micrometer-tracing-bridge-otel and spring-boot-starter-aop
-- `gradle/libs.versions.toml` - Added test dependencies (micrometer-tracing-test, awaitility, Jetty modules)
-
-### Main Code
-- `src/main/java/org/apache/solr/mcp/server/search/SearchService.java` - Already has @Observed annotation (no changes needed)
-
-## How to Run Tests
-
-```bash
-# Run distributed tracing tests only
-./gradlew test --tests "org.apache.solr.mcp.server.observability.DistributedTracingTest"
-
-# Run all tests
-./gradlew build
-
-# Run with verbose output
-./gradlew test --tests "*.DistributedTracingTest" --info
-```
-
-## Example Span Output
-
-From test execution, SimpleTracer captures spans like:
-```java
-SimpleSpan{
- name='search-service#search',
- tags={method=search, class=org.apache.solr.mcp.server.search.SearchService},
- startMillis=1770309759979,
- endMillis=1770309759988,
- traceId='72a53a4517951631',
- spanId='72a53a4517951631'
-}
-```
-
-## Spring Boot 3 vs Spring Boot 4 Differences
-
-| Aspect | Spring Boot 3.5 | Spring Boot 4 |
-|--------|----------------|---------------|
-| **Tracing API** | Micrometer Observation โ Micrometer Tracing โ OpenTelemetry | Direct OpenTelemetry integration |
-| **Test Approach** | SimpleTracer from micrometer-tracing-test | InMemorySpanExporter from opentelemetry-sdk-testing |
-| **Span Retrieval** | `tracer.getSpans()` | `spanExporter.getFinishedSpanItems()` |
-| **Span Type** | `SimpleSpan` (Micrometer) | `SpanData` (OpenTelemetry) |
-| **Bridge Dependency** | `micrometer-tracing-bridge-otel` required | Not required |
-| **AspectJ Starter** | `spring-boot-starter-aop` | `spring-boot-starter-aspectj` |
-
-## Next Steps (Optional)
-
-1. โ
Core distributed tracing tests - **COMPLETE**
-2. โ ๏ธ LGTM Stack integration test - Jetty issue (optional to fix)
-3. ๐ Consider adding more span attribute assertions
-4. ๐ Consider testing span parent-child relationships explicitly
-5. ๐ Consider adding tests for error scenarios (exceptions in @Observed methods)
-
-## References
-
-- [Micrometer Tracing Testing Documentation](https://docs.micrometer.io/tracing/reference/testing.html)
-- [Spring Boot 3 Observability](https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.micrometer-tracing)
-- [SimpleTracer API](https://github.com/micrometer-metrics/tracing/blob/main/micrometer-tracing-tests/micrometer-tracing-test/src/main/java/io/micrometer/tracing/test/simple/SimpleTracer.java)
-- [Observability With Spring Boot | Baeldung](https://www.baeldung.com/spring-boot-3-observability)
-
-## Success Criteria Met โ
-
-- [x] Comprehensive distributed tracing test suite implemented
-- [x] Tests adapted from Spring Boot 4 implementation (PR #23)
-- [x] All unit tests passing (6/6 DistributedTracingTest)
-- [x] No regressions (full build successful)
-- [x] Spring Boot 3.5 architecture properly used (Micrometer Observation API)
-- [x] SimpleTracer successfully capturing spans from @Observed annotations
-- [x] Test documentation complete
-
-**Result:** Distributed tracing testing for Spring Boot 3.5 is fully functional and ready for use. โ
diff --git a/dev-docs/ARCHITECTURE.md b/docs/development/ARCHITECTURE.md
similarity index 100%
rename from dev-docs/ARCHITECTURE.md
rename to docs/development/ARCHITECTURE.md
diff --git a/dev-docs/ATR_TESTING_GUIDE.md b/docs/development/ATR_TESTING_GUIDE.md
similarity index 100%
rename from dev-docs/ATR_TESTING_GUIDE.md
rename to docs/development/ATR_TESTING_GUIDE.md
diff --git a/security-docs/AUTH0_SETUP.md b/docs/development/AUTH0_SETUP.md
similarity index 100%
rename from security-docs/AUTH0_SETUP.md
rename to docs/development/AUTH0_SETUP.md
diff --git a/dev-docs/DEPLOYMENT.md b/docs/development/DEPLOYMENT.md
similarity index 100%
rename from dev-docs/DEPLOYMENT.md
rename to docs/development/DEPLOYMENT.md
diff --git a/dev-docs/DEVELOPMENT.md b/docs/development/DEVELOPMENT.md
similarity index 100%
rename from dev-docs/DEVELOPMENT.md
rename to docs/development/DEVELOPMENT.md
diff --git a/dev-docs/DOCKER_PUBLISHING.md b/docs/development/DOCKER_PUBLISHING.md
similarity index 100%
rename from dev-docs/DOCKER_PUBLISHING.md
rename to docs/development/DOCKER_PUBLISHING.md
diff --git a/dev-docs/TROUBLESHOOTING.md b/docs/development/TROUBLESHOOTING.md
similarity index 100%
rename from dev-docs/TROUBLESHOOTING.md
rename to docs/development/TROUBLESHOOTING.md
diff --git a/dev-docs/WORKFLOWS.md b/docs/development/WORKFLOWS.md
similarity index 99%
rename from dev-docs/WORKFLOWS.md
rename to docs/development/WORKFLOWS.md
index e988d3d3..7a3ec6a6 100644
--- a/dev-docs/WORKFLOWS.md
+++ b/docs/development/WORKFLOWS.md
@@ -450,7 +450,7 @@ Before this workflow can be used, you must complete:
3. **Configure Secrets**
- Add `ASF_USERNAME` secret with your ASF ID
-For complete implementation guide, see: [dev-docs/ATR_TESTING_GUIDE.md](ATR_TESTING_GUIDE.md)
+For complete implementation guide, see: [ATR Testing Guide](ATR_TESTING_GUIDE.md)
#### When to Use (Future)
@@ -563,7 +563,7 @@ gh workflow run atr-release-test.yml \
โ
Complete prerequisites first:
1. Implement automated signing
2. Request ATR onboarding
- 3. See: dev-docs/ATR_TESTING_GUIDE.md
+ 3. See: docs/development/ATR_TESTING_GUIDE.md
```
---
diff --git a/security-docs/keycloak.md b/docs/development/keycloak.md
similarity index 100%
rename from security-docs/keycloak.md
rename to docs/development/keycloak.md