diff --git a/solr/solr-ref-guide/modules/getting-started/getting-started-nav.adoc b/solr/solr-ref-guide/modules/getting-started/getting-started-nav.adoc
index 095f679f93b6..03436f75d2e2 100644
--- a/solr/solr-ref-guide/modules/getting-started/getting-started-nav.adoc
+++ b/solr/solr-ref-guide/modules/getting-started/getting-started-nav.adoc
@@ -35,6 +35,7 @@
** xref:tutorial-solrcloud.adoc[]
** xref:tutorial-opennlp.adoc[]
** xref:tutorial-aws.adoc[]
+** xref:tutorial-solr-mcp.adoc[]
* xref:solr-admin-ui.adoc[]
* xref:about-this-guide.adoc[]
diff --git a/solr/solr-ref-guide/modules/getting-started/pages/tutorial-solr-mcp.adoc b/solr/solr-ref-guide/modules/getting-started/pages/tutorial-solr-mcp.adoc
new file mode 100644
index 000000000000..ac45613a9506
--- /dev/null
+++ b/solr/solr-ref-guide/modules/getting-started/pages/tutorial-solr-mcp.adoc
@@ -0,0 +1,1403 @@
+= Solr MCP Server -- User Guide
+:toc: left
+:toclevels: 3
+:sectnums:
+:sectnumlevels: 3
+:experimental:
+:icons: font
+:source-highlighter: rouge
+:imagesdir: ../images
+// 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.
+
+Search, index, and manage https://solr.apache.org/[Apache Solr] collections using *natural language* -- no need to hand-craft Solr queries, build filter expressions, or memorize the admin API.
+
+Instead of writing:
+
+[,text]
+----
+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 makes this possible by exposing Solr operations -- searching, indexing, collection management, and schema introspection -- as tools that any MCP-compatible AI client can invoke.
+
+TIP: Visit the https://solr.apache.org/mcp[Solr MCP Server website] for features, community, and downloads.
+The source code is at https://github.com/apache/solr-mcp[github.com/apache/solr-mcp].
+
+== Quick Start
+
+Get from zero to a working Claude + Solr integration in under 2 minutes.
+
+=== Prerequisites
+
+* https://docs.docker.com/get-docker/[Docker] and Docker Compose
+* An MCP client (e.g., https://claude.ai/download[Claude Desktop])
+
+=== Step 1: Start Solr with Sample Data
+
+[,console]
+----
+$ git clone https://github.com/apache/solr-mcp.git
+$ cd solr-mcp
+$ docker compose up -d
+----
+
+This starts Solr in SolrCloud mode with ZooKeeper and creates two sample collections pre-loaded with data:
+
+* *films* -- 1,100+ movie records with titles, directors, genres, and release dates
+* *books* -- empty collection ready for indexing
+
+Wait ~30 seconds for Solr to fully initialize.
+Verify at http://localhost:8983/solr/.
+
+=== Step 2: Configure Your MCP Client
+
+Add the following to your Claude Desktop configuration file:
+
+* *macOS*: `~/Library/Application Support/Claude/claude_desktop_config.json`
+* *Windows*: `%APPDATA%\Claude\claude_desktop_config.json`
+
+[,json]
+----
+{
+ "mcpServers": {
+ "solr-mcp": {
+ "command": "docker",
+ "args": ["run", "-i", "--rm",
+ "-e", "SOLR_URL=http://host.docker.internal:8983/solr/",
+ "ghcr.io/apache/solr-mcp:latest"]
+ }
+ }
+}
+----
+
+Restart Claude Desktop.
+
+=== Step 3: Try It Out
+
+Ask Claude:
+
+* _"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"}]"_
+
+image::claude-stdio.png[Claude Desktop STDIO]
+
+== Overview
+
+=== What is MCP?
+
+The https://spec.modelcontextprotocol.io/[Model Context Protocol (MCP)] is an open standard that lets AI assistants -- like Claude, GitHub Copilot, and Cursor -- call external *tools* and read external *resources* in a structured way.
+Think of it as a USB-C port for AI: one protocol, many capabilities.
+
+=== Why MCP for Solr?
+
+Apache Solr is a powerful search platform, but using it effectively requires knowledge of its query syntax, filter queries, facet parameters, schema design, and admin APIs.
+This creates a barrier for users who know _what_ they want to find but not _how_ to express it in Solr's language.
+
+MCP removes that barrier.
+With the Solr MCP Server, an AI assistant can:
+
+* *Search* -- translate natural language questions into optimized Solr queries with filters, facets, sorting, and pagination
+* *Index* -- accept data in any format (JSON, CSV, XML) and handle batch processing, field name sanitization, and commits
+* *Manage* -- create collections, check health, inspect schemas, and view statistics -- all through conversation
+* *Learn the schema* -- read collection schemas to craft better queries without the user needing to know field names or types
+
+The user focuses on intent; the AI handles the Solr details.
+
+=== Architecture
+
+....
+┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────┐
+│ │ │ │ │ │
+│ MCP Clients │ │ Solr MCP Server │ │ Apache Solr │
+│ │ │ │ │ │
+│ · Claude Desktop │◄─────►│ Tools: │◄─────►│ Collections │
+│ · Claude Code │ STDIO │ search │ SolrJ │ Documents │
+│ · GitHub Copilot │ or │ index-json/csv/xml │ │ Schema │
+│ · Cursor │ HTTP │ list-collections │ │ │
+│ · JetBrains AI │ │ get-collection-stats│ │ │
+│ · MCP Inspector │ │ check-health │ │ │
+│ │ │ create-collection │ │ │
+│ │ │ get-schema │ │ │
+└──────────────────────┘ └──────────────────────┘ └──────────────────┘
+ │
+ │ OTLP (optional)
+ ▼
+ ┌──────────────────────┐
+ │ LGTM Stack │
+ │ Grafana · Tempo │
+ │ Loki · Mimir │
+ └──────────────────────┘
+....
+
+=== Transport Modes
+
+[cols="1,2,2",options="header"]
+|===
+| |STDIO |HTTP
+|*How it works* |Communicates via stdin/stdout |REST endpoints on port 8080
+|*Best for* |Claude Desktop, local AI clients |MCP Inspector, remote access, multi-client
+|*Security* |OS-level process isolation |OAuth2 (Auth0, Keycloak, Okta)
+|*Observability* |Not available |OpenTelemetry, Prometheus, Grafana
+|*Network exposure* |None |Requires firewall / TLS in production
+|===
+
+== Features
+
+=== Collections
+
+Manage and monitor your Solr collections.
+
+[cols="1,3",options="header"]
+|===
+|Tool |Description
+|`list-collections` |List all available Solr collections
+|`get-collection-stats` |Get comprehensive metrics: index stats, query performance, cache hit ratios, handler throughput
+|`check-health` |Health check -- returns status, document count, and responsiveness
+|`create-collection` |Create a new collection with configurable shards, replicas, and configset (defaults: `_default`, 1 shard, 1 replica)
+|===
+
+*Example prompts:*
+
+* "List all Solr collections"
+* "How many documents are in the films collection?"
+* "Is the books collection healthy?"
+* "Create a new collection called products"
+
+=== Indexing
+
+Index documents in three formats.
+The server handles batch processing, field name sanitization, and automatic commits.
+
+[cols="1,3",options="header"]
+|===
+|Tool |Description
+|`index-json-documents` |Index documents from a JSON array string
+|`index-csv-documents` |Index documents from a CSV string (first row = headers)
+|`index-xml-documents` |Index documents from an XML string
+|===
+
+==== JSON Example
+
+[,json]
+----
+[
+ {"id": "1", "title": "The Great Gatsby", "author": "F. Scott Fitzgerald", "year_i": 1925},
+ {"id": "2", "title": "To Kill a Mockingbird", "author": "Harper Lee", "year_i": 1960}
+]
+----
+
+==== CSV Example
+
+[,csv]
+----
+id,title,author,year_i
+1,The Great Gatsby,F. Scott Fitzgerald,1925
+2,To Kill a Mockingbird,Harper Lee,1960
+----
+
+==== XML Example
+
+[,xml]
+----
+
+
+ 1
+ The Great Gatsby
+ F. Scott Fitzgerald
+
+
+----
+
+*Batch processing:* Documents are indexed in batches of 1,000 with per-document retry fallback on errors.
+Field names are automatically sanitized for Solr compatibility.
+
+=== Searching
+
+Full-text search with filtering, faceting, sorting, and pagination.
+
+[cols="1,3",options="header"]
+|===
+|Tool |Description
+|`search` |Search a Solr collection with query, filters, facets, sorting, and pagination
+|===
+
+==== Parameters
+
+[cols="1,3,1",options="header"]
+|===
+|Parameter |Description |Required
+|`collection` |Solr collection to query |Yes
+|`query` |Solr query string (`q` parameter). Defaults to `\*:*` |No
+|`filterQueries` |Filter queries (`fq` parameter) |No
+|`facetFields` |Fields to facet on |No
+|`sortClauses` |Sort clauses (list of `\{item, order}` maps) |No
+|`start` |Pagination offset |No
+|`rows` |Number of results to return |No
+|===
+
+==== Dynamic Field Suffixes
+
+Solr's schemaless mode uses field name suffixes to indicate types:
+
+[cols="1,2,2",options="header"]
+|===
+|Suffix |Type |Example
+|`_s` |String (exact match) |`genre_s:"fantasy"`
+|`_t` |Text (tokenized) |`description_t:"adventure"`
+|`_i` |Integer |`year_i:1925`
+|`_l` |Long |`population_l:1000000`
+|`_f` |Float |`rating_f:4.5`
+|`_d` |Double |`price_d:29.99`
+|`_dt` |Date |`published_dt:"2024-01-01T00:00:00Z"`
+|`_b` |Boolean |`inStock_b:true`
+|===
+
+*Example prompts:*
+
+* "Search films for movies with 'war' in the title"
+* "Find all fantasy books sorted by price ascending"
+* "Search films and facet by genre_s"
+* "Show me the top 5 most recent films"
+
+==== Response Format
+
+[,json]
+----
+{
+ "numFound": 42,
+ "start": 0,
+ "maxScore": 1.5,
+ "documents": [
+ {"id": "1", "title": "Star Wars", "genre_s": "sci-fi"}
+ ],
+ "facets": {
+ "genre_s": {"sci-fi": 12, "drama": 8, "comedy": 6}
+ }
+}
+----
+
+=== Schema
+
+Retrieve the complete schema definition for any collection.
+
+[cols="1,3",options="header"]
+|===
+|Tool |Description
+|`get-schema` |Retrieve field definitions, field types, dynamic fields, copy fields, unique key, and schema attributes
+|===
+
+=== MCP Resources
+
+MCP Resources provide read-only data that clients can access directly (without calling a tool).
+
+[cols="2,3",options="header"]
+|===
+|Resource URI |Description
+|`solr://collections` |List of all Solr collections in the cluster
+|`solr://\{collection}/schema` |Schema definition for a specific collection (supports autocompletion)
+|===
+
+The `solr://\{collection}/schema` resource supports *autocompletion* -- MCP clients can query for available collection names when building the URI.
+
+image::mcp-inspector-list-resources.png[MCP Inspector Resources]
+
+image::mcp-inspector-resource-completion.png[MCP Inspector Resource Autocompletion]
+
+== Usage
+
+=== STDIO Mode (Default)
+
+STDIO mode communicates via standard input/output streams.
+This is the recommended mode for local AI client integrations like Claude Desktop.
+
+==== Docker (Recommended)
+
+[,console]
+----
+$ docker run -i --rm \
+ -e SOLR_URL=http://host.docker.internal:8983/solr/ \
+ ghcr.io/apache/solr-mcp:latest
+----
+
+*Linux users* -- add `--add-host=host.docker.internal:host-gateway` to connect to Solr on the host machine:
+
+[,console]
+----
+$ docker run -i --rm \
+ --add-host=host.docker.internal:host-gateway \
+ -e SOLR_URL=http://host.docker.internal:8983/solr/ \
+ ghcr.io/apache/solr-mcp:latest
+----
+
+==== JAR (Build from Source)
+
+[,console]
+----
+$ ./gradlew build
+$ java -jar build/libs/solr-mcp-1.0.0-SNAPSHOT.jar
+----
+
+==== Gradle (Development)
+
+[,console]
+----
+$ ./gradlew bootRun
+----
+
+[[http-mode]]
+=== HTTP Mode
+
+HTTP mode starts a web server on port 8080 with REST endpoints.
+Use this for MCP Inspector, remote access, or multi-client scenarios.
+
+==== Docker
+
+[,console]
+----
+$ docker run -p 8080:8080 --rm \
+ -e PROFILES=http \
+ -e SOLR_URL=http://host.docker.internal:8983/solr/ \
+ ghcr.io/apache/solr-mcp:latest
+----
+
+==== JAR (Build from Source)
+
+[,console]
+----
+$ ./gradlew build
+$ PROFILES=http java -jar build/libs/solr-mcp-1.0.0-SNAPSHOT.jar
+----
+
+==== Gradle (Development)
+
+[,console]
+----
+$ PROFILES=http ./gradlew bootRun
+----
+
+The MCP endpoint is available at `http://localhost:8080/mcp`.
+
+Verify the server is running:
+
+[,console]
+----
+$ curl http://localhost:8080/actuator/health
+----
+
+=== Configuration Reference
+
+[cols="2,3,2",options="header"]
+|===
+|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`
+|===
+
+[[mcp-client-integration]]
+== MCP Client Integration
+
+Configure the Solr MCP Server with your preferred AI client.
+Each section below shows the configuration for STDIO, HTTP, and *secured HTTP* (OAuth2) modes.
+
+NOTE: *Secured HTTP prerequisite:* Before connecting clients to a secured server, start the server with OAuth2 enabled as described in <>.
+You'll need your OAuth2 provider's authorization URL, token URL, and client credentials.
+
+[[claude-desktop]]
+=== Claude Desktop
+
+Edit your Claude Desktop configuration file:
+
+* *macOS*: `~/Library/Application Support/Claude/claude_desktop_config.json`
+* *Windows*: `%APPDATA%\Claude\claude_desktop_config.json`
+
+==== STDIO Mode with Docker
+
+[,json]
+----
+{
+ "mcpServers": {
+ "solr-mcp": {
+ "command": "docker",
+ "args": ["run", "-i", "--rm",
+ "-e", "SOLR_URL=http://host.docker.internal:8983/solr/",
+ "ghcr.io/apache/solr-mcp:latest"]
+ }
+ }
+}
+----
+
+==== STDIO Mode with 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/"
+ }
+ }
+ }
+}
+----
+
+==== HTTP Mode (via mcp-remote)
+
+First start the server in HTTP mode (see <>), then configure Claude Desktop to connect via `mcp-remote`:
+
+[,json]
+----
+{
+ "mcpServers": {
+ "solr-mcp": {
+ "command": "npx",
+ "args": ["mcp-remote", "http://localhost:8080/mcp"]
+ }
+ }
+}
+----
+
+==== Secured HTTP Mode (OAuth2 via mcp-remote)
+
+When OAuth2 is enabled on the server, `mcp-remote` handles the full OAuth2 authorization flow automatically.
+It discovers the authorization server from the MCP server's metadata and opens a browser for user consent.
+
+[,json]
+----
+{
+ "mcpServers": {
+ "solr-mcp": {
+ "command": "npx",
+ "args": [
+ "mcp-remote",
+ "http://localhost:8080/mcp",
+ "--allow-http"
+ ]
+ }
+ }
+}
+----
+
+[NOTE]
+====
+*How it works:* When `mcp-remote` connects to a secured server, the server responds with an OAuth2 challenge. `mcp-remote` then:
+
+. Discovers the authorization server from the server's `/.well-known/oauth-authorization-server` endpoint
+. Opens your browser for login/consent
+. Receives the authorization code via a local callback (default: `http://localhost:3334/oauth/callback`)
+. Exchanges it for an access token and attaches it to all subsequent MCP requests
+
+The `--allow-http` flag is needed when the MCP server is running on `http://` (development).
+In production with HTTPS, omit this flag.
+====
+
+Restart Claude Desktop after any configuration change.
+
+image::claude-stdio.png[Claude Desktop STDIO]
+
+[[claude-code]]
+=== Claude Code
+
+==== STDIO Mode -- CLI
+
+[,console]
+----
+$ # Docker
+$ claude mcp add --transport stdio solr-mcp -- \
+ docker run -i --rm -e SOLR_URL=http://host.docker.internal:8983/solr/ \
+ ghcr.io/apache/solr-mcp:latest
+
+$ # 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
+----
+
+==== STDIO Mode -- `.mcp.json`
+
+Add to your project root:
+
+[,json]
+----
+{
+ "mcpServers": {
+ "solr-mcp": {
+ "type": "stdio",
+ "command": "docker",
+ "args": ["run", "-i", "--rm",
+ "-e", "SOLR_URL=http://host.docker.internal:8983/solr/",
+ "ghcr.io/apache/solr-mcp:latest"]
+ }
+ }
+}
+----
+
+==== HTTP Mode -- CLI
+
+Start the server first, then:
+
+[,console]
+----
+$ claude mcp add --transport http solr-mcp http://localhost:8080/mcp
+----
+
+==== HTTP Mode -- `.mcp.json`
+
+[,json]
+----
+{
+ "mcpServers": {
+ "solr-mcp": {
+ "type": "http",
+ "url": "http://localhost:8080/mcp"
+ }
+ }
+}
+----
+
+==== Secured HTTP Mode (OAuth2)
+
+Claude Code supports OAuth2-secured MCP servers.
+When connecting to a secured server, Claude Code handles the OAuth2 flow automatically -- it opens a browser for authentication and manages token lifecycle.
+
+*CLI:*
+
+[,console]
+----
+$ claude mcp add --transport http solr-mcp http://localhost:8080/mcp
+----
+
+*`.mcp.json`:*
+
+[,json]
+----
+{
+ "mcpServers": {
+ "solr-mcp": {
+ "type": "http",
+ "url": "http://localhost:8080/mcp"
+ }
+ }
+}
+----
+
+TIP: The configuration is the same as unsecured HTTP -- Claude Code detects the OAuth2 challenge from the server and initiates the authorization flow automatically.
+
+[[github-copilot-vs-code]]
+=== GitHub Copilot / VS Code
+
+VS Code supports MCP servers through the built-in MCP support (available in VS Code 1.99+).
+
+==== Workspace Configuration (`.vscode/mcp.json`)
+
+Create `.vscode/mcp.json` in your project root:
+
+*STDIO Mode:*
+
+[,json]
+----
+{
+ "servers": {
+ "solr-mcp": {
+ "type": "stdio",
+ "command": "docker",
+ "args": ["run", "-i", "--rm",
+ "-e", "SOLR_URL=http://host.docker.internal:8983/solr/",
+ "ghcr.io/apache/solr-mcp:latest"]
+ }
+ }
+}
+----
+
+*HTTP Mode (unsecured and secured):*
+
+[,json]
+----
+{
+ "servers": {
+ "solr-mcp": {
+ "type": "sse",
+ "url": "http://localhost:8080/mcp"
+ }
+ }
+}
+----
+
+TIP: The configuration is the same for secured and unsecured HTTP.
+VS Code handles the MCP OAuth2 flow automatically -- when connecting to a secured server, a browser window opens for authentication and the token is managed transparently.
+
+==== User Settings (`settings.json`)
+
+Open VS Code Settings (JSON) and add:
+
+[,json]
+----
+{
+ "mcp": {
+ "servers": {
+ "solr-mcp": {
+ "type": "stdio",
+ "command": "docker",
+ "args": ["run", "-i", "--rm",
+ "-e", "SOLR_URL=http://host.docker.internal:8983/solr/",
+ "ghcr.io/apache/solr-mcp:latest"]
+ }
+ }
+ }
+}
+----
+
+After adding the configuration, the Solr MCP tools will be available to GitHub Copilot Chat in Agent mode.
+
+NOTE: MCP support in VS Code and Copilot is evolving. Check the https://code.visualstudio.com/docs/copilot/chat/mcp-servers[VS Code MCP documentation] for the latest configuration format.
+
+[[cursor]]
+=== Cursor
+
+Cursor supports MCP servers natively.
+Configure via Cursor Settings or a project-level config file.
+
+==== Cursor Settings UI
+
+. Open *Cursor Settings* (gear icon or kbd:[Cmd+,] / kbd:[Ctrl+,])
+. Navigate to *Features* > *MCP Servers*
+. Click *Add New MCP Server*
+. Enter:
+** *Name*: `solr-mcp`
+** *Type*: `command` (for STDIO) or `sse` (for HTTP)
+** *Command*: `docker run -i --rm -e SOLR_URL=http://host.docker.internal:8983/solr/ ghcr.io/apache/solr-mcp:latest`
+
+==== Project Configuration (`.cursor/mcp.json`)
+
+Create `.cursor/mcp.json` in your project root:
+
+*STDIO Mode:*
+
+[,json]
+----
+{
+ "mcpServers": {
+ "solr-mcp": {
+ "command": "docker",
+ "args": ["run", "-i", "--rm",
+ "-e", "SOLR_URL=http://host.docker.internal:8983/solr/",
+ "ghcr.io/apache/solr-mcp:latest"]
+ }
+ }
+}
+----
+
+*HTTP Mode (unsecured and secured):*
+
+[,json]
+----
+{
+ "mcpServers": {
+ "solr-mcp": {
+ "url": "http://localhost:8080/mcp"
+ }
+ }
+}
+----
+
+TIP: The configuration is the same for secured and unsecured HTTP.
+Cursor handles the MCP OAuth2 authorization flow automatically -- it opens a browser for authentication and manages access tokens transparently.
+
+NOTE: MCP support in Cursor is evolving. Check the https://docs.cursor.com/context/model-context-protocol[Cursor MCP documentation] for the latest configuration format.
+
+[[jetbrains-ides]]
+=== JetBrains IDEs
+
+JetBrains IDEs (IntelliJ IDEA, WebStorm, PyCharm, etc.) support MCP servers through the AI Assistant plugin.
+
+==== IDE Settings
+
+. Open *Settings* (kbd:[Cmd+,] / kbd:[Ctrl+Alt+S])
+. Navigate to *Tools* > *AI Assistant* > *MCP Servers*
+. Click *Add* (`+`)
+. Configure:
+** *Name*: `solr-mcp`
+** *Transport*: `STDIO`
+** *Command*: `docker`
+** *Arguments*: `run -i --rm -e SOLR_URL=http://host.docker.internal:8983/solr/ ghcr.io/apache/solr-mcp:latest`
+
+For HTTP mode, select *SSE* transport and enter `http://localhost:8080/mcp` as the URL.
+
+==== Project Configuration
+
+Create a `.junie/mcp.json` file in your project root:
+
+*STDIO Mode:*
+
+[,json]
+----
+{
+ "mcpServers": {
+ "solr-mcp": {
+ "command": "docker",
+ "args": ["run", "-i", "--rm",
+ "-e", "SOLR_URL=http://host.docker.internal:8983/solr/",
+ "ghcr.io/apache/solr-mcp:latest"]
+ }
+ }
+}
+----
+
+*HTTP Mode (unsecured and secured):*
+
+[,json]
+----
+{
+ "mcpServers": {
+ "solr-mcp": {
+ "url": "http://localhost:8080/mcp"
+ }
+ }
+}
+----
+
+TIP: The configuration is the same for secured and unsecured HTTP.
+JetBrains IDEs handle the MCP OAuth2 authorization flow automatically -- the IDE opens a browser for authentication and manages the token lifecycle.
+
+NOTE: MCP support in JetBrains IDEs requires the AI Assistant plugin. Check the https://www.jetbrains.com/help/idea/model-context-protocol.html[JetBrains MCP documentation] for the latest configuration format.
+
+=== How MCP OAuth2 Works with Clients
+
+When a client connects to a secured Solr MCP Server, the following flow occurs:
+
+....
+MCP Client Solr MCP Server OAuth2 Provider
+ │ │ (Auth0 / Keycloak)
+ │ │ │
+ │── Connect to /mcp ──────────►│ │
+ │◄── 401 + OAuth2 metadata ────│ │
+ │ │ │
+ │── Discover auth server ─────────────────────────────────► │
+ │◄── Authorization endpoint ────────────────────────────── │
+ │ │ │
+ │── Open browser for login ───────────────────────────────► │
+ │◄── Authorization code ────────────────────────────────── │
+ │ │ │
+ │── Exchange code for token ──────────────────────────────► │
+ │◄── Access token (JWT) ────────────────────────────────── │
+ │ │ │
+ │── MCP request + Bearer ─────►│ │
+ │ │── Validate JWT ──────────► │
+ │ │◄── Valid ──────────────── │
+ │◄── MCP response ─────────────│ │
+....
+
+The server exposes its OAuth2 metadata at `/.well-known/oauth-authorization-server`, which the client uses to discover authorization and token endpoints.
+Most MCP clients handle this flow transparently -- the URL configuration is the same for both secured and unsecured HTTP servers.
+
+[[security-http-mode]]
+== Security (HTTP Mode)
+
+When running in HTTP mode, the Solr MCP Server supports *OAuth2 authentication* with JWT token validation.
+Security is *disabled by default* and must be explicitly enabled.
+
+=== Overview
+
+* *Protocol*: OAuth2 Resource Server with JWT validation
+* *Supported providers*: Auth0, Keycloak, Okta, or any OAuth2/OIDC provider
+* *STDIO mode*: Security is not applicable (OS-level process isolation)
+* *HTTP mode*: Optional, enabled with `SECURITY_ENABLED=true`
+
+=== Enable Security
+
+[,console]
+----
+$ export PROFILES=http
+$ export SECURITY_ENABLED=true
+$ export OAUTH2_ISSUER_URI=https://your-provider.example.com/
+$ ./gradlew bootRun
+----
+
+Or with Docker:
+
+[,console]
+----
+$ docker run -p 8080:8080 --rm \
+ -e PROFILES=http \
+ -e SECURITY_ENABLED=true \
+ -e OAUTH2_ISSUER_URI=https://your-provider.example.com/ \
+ -e SOLR_URL=http://host.docker.internal:8983/solr/ \
+ ghcr.io/apache/solr-mcp:latest
+----
+
+=== Auth0
+
+==== 1. Create Auth0 Application
+
+. Go to https://manage.auth0.com/[Auth0 Dashboard] > *Applications* > *Create Application*
+. Name: `Solr MCP Server`
+. Type: *Machine to Machine Applications*
+. Note your *Domain*, *Client ID*, and *Client Secret*
+
+==== 2. Create Auth0 API
+
+. Navigate to *Applications* > *APIs* > *Create API*
+. Name: `Solr MCP API`
+. Identifier (audience): `https://solr-mcp-api`
+. Signing Algorithm: *RS256*
+
+==== 3. Configure Callback URLs
+
+In your application settings, add to *Allowed Callback URLs*:
+
+[,text]
+----
+http://localhost:6274/oauth/callback,http://localhost:3334/oauth/callback,http://localhost:8080/login/oauth2/code/auth0
+----
+
+IMPORTANT: Each callback URL serves a different client:
+
+* `http://localhost:6274/oauth/callback` -- MCP Inspector
+* `http://localhost:3334/oauth/callback` -- `mcp-remote` (used by Claude Desktop, VS Code, Cursor, JetBrains for HTTP mode)
+* `http://localhost:8080/login/oauth2/code/auth0` -- Direct server OAuth2 code flow
+
+==== 4. Run the Server
+
+[,console]
+----
+$ export PROFILES=http
+$ export SECURITY_ENABLED=true
+$ export OAUTH2_ISSUER_URI=https://your-tenant.auth0.com/
+$ ./gradlew bootRun
+----
+
+==== 5. Get an Access Token
+
+[,console]
+----
+$ curl --request POST \
+ --url https://your-tenant.auth0.com/oauth/token \
+ --header 'content-type: application/json' \
+ --data '{
+ "client_id": "YOUR_CLIENT_ID",
+ "client_secret": "YOUR_CLIENT_SECRET",
+ "audience": "https://solr-mcp-api",
+ "grant_type": "client_credentials"
+ }'
+----
+
+Or use the convenience script:
+
+[,console]
+----
+$ ./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
+----
+
+==== 6. Use the Token
+
+[,console]
+----
+$ curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
+ http://localhost:8080/mcp
+----
+
+For the full step-by-step guide, see link:../dev-docs/AUTH0_SETUP.md[Auth0 Setup Guide].
+
+=== Keycloak
+
+==== 1. Start Keycloak
+
+[,console]
+----
+$ docker run -d --name keycloak \
+ -p 8180:8080 \
+ -e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
+ -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
+ quay.io/keycloak/keycloak:26.0 start-dev
+----
+
+Access the admin console at `http://localhost:8180` (login: `admin` / `admin`).
+
+==== 2. Create Realm and Client
+
+. Create realm: `solr-mcp`
+. Create client:
+** Client ID: `solr-mcp-client`
+** Client type: OpenID Connect
+** Client authentication: OFF (public client)
+** Valid redirect URIs: `http://localhost:6274/*`, `http://localhost:3334/*`, `http://localhost:8080/*`
+** Web origins: `*`
+
+IMPORTANT: Each redirect URI pattern serves a different client:
+
+* `http://localhost:6274/*` -- MCP Inspector
+* `http://localhost:3334/*` -- `mcp-remote` (used by Claude Desktop, VS Code, Cursor, JetBrains for HTTP mode)
+* `http://localhost:8080/*` -- Direct server OAuth2 code flow
+
+==== 3. Create Test User
+
+. Navigate to *Users* > *Add user*
+. Username: `testuser`, Email verified: ON
+. Set password in *Credentials* tab
+
+==== 4. Run the Server
+
+[,console]
+----
+$ export PROFILES=http
+$ export SECURITY_ENABLED=true
+$ export OAUTH2_ISSUER_URI=http://localhost:8180/realms/solr-mcp
+$ ./gradlew bootRun
+----
+
+==== 5. Get a Token
+
+[,console]
+----
+$ curl -X POST "http://localhost:8180/realms/solr-mcp/protocol/openid-connect/token" \
+ -H "Content-Type: application/x-www-form-urlencoded" \
+ -d "client_id=solr-mcp-client" \
+ -d "username=testuser" \
+ -d "password=yourpassword" \
+ -d "grant_type=password"
+----
+
+==== 6. Call the MCP Server
+
+[,console]
+----
+$ TOKEN=$(curl -s -X POST "http://localhost:8180/realms/solr-mcp/protocol/openid-connect/token" \
+ -d "client_id=solr-mcp-client" \
+ -d "username=testuser" \
+ -d "password=yourpassword" \
+ -d "grant_type=password" | jq -r '.access_token')
+
+$ curl -X POST http://localhost:8080/mcp \
+ -H "Authorization: Bearer $TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{"jsonrpc":"2.0","method":"tools/list","id":1}'
+----
+
+For the full guide including GitHub identity provider setup, role-based access control, and production deployment, see link:../dev-docs/KEYCLOAK_SETUP.md[Keycloak Setup Guide].
+
+[[security-with-mcp-inspector]]
+=== Security with MCP Inspector
+
+When OAuth2 is enabled, configure MCP Inspector with your provider's OAuth settings:
+
+. Start MCP Inspector: `npx @modelcontextprotocol/inspector`
+. Connect to `http://localhost:8080/mcp`
+. Configure OAuth:
+** *Authorization URL*: Your provider's authorize endpoint
+** *Token URL*: Your provider's token endpoint
+** *Client ID*: Your application's Client ID
+** *Redirect URI*: `http://localhost:6274/oauth/callback`
+
+image::mcp-inspector-http-oauth-success.png[MCP Inspector OAuth Success]
+
+image::mcp-inspector-http-oauth-failure.png[MCP Inspector OAuth Failure]
+
+== Building
+
+=== Prerequisites
+
+* Java 25+ (https://adoptium.net/[Eclipse Temurin] recommended)
+* Docker (for integration tests and Docker image builds)
+
+=== Build from Source
+
+[,console]
+----
+$ git clone https://github.com/apache/solr-mcp.git
+$ cd solr-mcp
+
+$ # Full build with tests
+$ ./gradlew build
+
+$ # Build without tests (faster)
+$ ./gradlew assemble
+----
+
+The build produces:
+
+* `build/libs/solr-mcp-1.0.0-SNAPSHOT.jar` -- executable (fat) JAR
+
+=== Build Docker Image
+
+[,console]
+----
+$ # Build to local Docker daemon
+$ ./gradlew jibDockerBuild
+
+$ # Verify
+$ docker images | grep solr-mcp
+----
+
+This creates `solr-mcp:1.0.0-SNAPSHOT` with multi-platform support (amd64 + arm64).
+
+=== Push to Container Registry
+
+[,console]
+----
+$ # Docker Hub
+$ docker login
+$ ./gradlew jib -Djib.to.image=YOUR_USERNAME/solr-mcp:1.0.0-SNAPSHOT
+
+$ # GitHub Container Registry
+$ echo $GITHUB_TOKEN | docker login ghcr.io -u YOUR_USERNAME --password-stdin
+$ ./gradlew jib -Djib.to.image=ghcr.io/YOUR_USERNAME/solr-mcp:1.0.0-SNAPSHOT
+----
+
+=== Code Formatting
+
+Formatting is enforced by https://github.com/diffplug/spotless[Spotless] and runs automatically as part of `./gradlew build`:
+
+[,console]
+----
+$ # Check formatting
+$ ./gradlew spotlessCheck
+
+$ # Auto-fix formatting
+$ ./gradlew spotlessApply
+----
+
+== Debugging with MCP Inspector
+
+The https://github.com/modelcontextprotocol/inspector[MCP Inspector] is a web-based tool for testing and debugging MCP servers.
+It lets you browse available tools, invoke them interactively, and inspect responses.
+
+=== Install
+
+[,console]
+----
+$ npx @modelcontextprotocol/inspector
+----
+
+This starts the Inspector UI at `http://localhost:6274`.
+
+=== Connect via HTTP
+
+. Start the server in HTTP mode:
++
+[,console]
+----
+$ PROFILES=http ./gradlew bootRun
+----
+. In MCP Inspector, enter: `http://localhost:8080/mcp`
+. Click *Connect*
+
+image::mcp-inspector-http.png[MCP Inspector HTTP]
+
+=== Connect via STDIO
+
+. In MCP Inspector, select *STDIO* transport
+. Command: `docker`
+. Arguments: `run -i --rm -e SOLR_URL=http://host.docker.internal:8983/solr/ ghcr.io/apache/solr-mcp:latest`
+. Click *Connect*
+
+image::mcp-inspector-stdio.png[MCP Inspector STDIO]
+
+=== Test Tools
+
+Once connected, you can:
+
+. *Browse tools* -- See all available MCP tools and their parameter schemas
+. *Invoke tools* -- Fill in parameters and execute tools interactively
+. *View responses* -- Inspect JSON responses from each tool call
+. *Browse resources* -- Access MCP resources like `solr://collections`
+
+=== Debug with OAuth2
+
+If security is enabled, configure the Inspector's OAuth settings before connecting:
+
+. Click the *OAuth* settings in the Inspector
+. Enter your provider's Authorization URL, Token URL, Client ID, and Redirect URI
+. Complete the OAuth flow
+. The Inspector will include the Bearer token in all subsequent requests
+
+See <> for provider-specific settings.
+
+== Observability with LGTM Stack
+
+When running in *HTTP mode*, the Solr MCP Server exports telemetry data via OpenTelemetry to the *LGTM stack* (Loki, Grafana, Tempo, Mimir) for full observability.
+
+=== What You Get
+
+[cols="1,1,3",options="header"]
+|===
+|Signal |Backend |What it shows
+|*Traces* |Tempo |Distributed traces for every MCP tool invocation, Solr query, and HTTP request
+|*Metrics* |Mimir/Prometheus |JVM stats, HTTP request rates, Solr query latencies, cache hit ratios
+|*Logs* |Loki |Structured application logs correlated with trace IDs
+|===
+
+=== Start the LGTM Stack
+
+The project's `compose.yaml` includes a Grafana OTEL LGTM all-in-one container:
+
+[,console]
+----
+$ docker compose up -d
+----
+
+This starts:
+
+[cols="1,2,3",options="header"]
+|===
+|Service |URL |Purpose
+|Grafana |http://localhost:3000 |Dashboards and exploration (no auth required)
+|OTLP gRPC |localhost:4317 |Trace/metric/log ingestion (gRPC)
+|OTLP HTTP |localhost:4318 |Trace/metric/log ingestion (HTTP)
+|===
+
+=== Run the Server with Observability
+
+[,console]
+----
+$ PROFILES=http ./gradlew bootRun
+----
+
+The server auto-configures OTLP export when the LGTM stack is running.
+Default configuration:
+
+[,properties]
+----
+management.tracing.sampling.probability=1.0 # 100% sampling (dev)
+otel.exporter.otlp.endpoint=http://localhost:4317
+otel.exporter.otlp.protocol=grpc
+----
+
+=== Explore in Grafana
+
+. Open http://localhost:3000
+. Click *Explore* in the left sidebar
+
+==== View Traces (Tempo)
+
+. Select *Tempo* as the data source
+. Use TraceQL to search:
++
+----
+{.service.name="solr-mcp"}
+----
+. Click on a trace to see the span waterfall -- each MCP tool invocation, Solr query, and HTTP request is a separate span
+
+==== View Logs (Loki)
+
+. Select *Loki* as the data source
+. Use LogQL to search:
++
+----
+{service_name="solr-mcp"} |= "search"
+----
+. Logs are automatically correlated with trace IDs -- click a log line to jump to its trace
+
+==== View Metrics (Prometheus)
+
+. Select *Prometheus* as the data source
+. Example queries:
++
+[,promql]
+----
+# HTTP request rate
+rate(http_server_requests_seconds_count[5m])
+
+# JVM memory usage
+jvm_memory_used_bytes
+
+# Request latency (p99)
+histogram_quantile(0.99, rate(http_server_requests_seconds_bucket[5m]))
+----
+
+=== What Gets Traced
+
+Every MCP tool invocation creates a trace span:
+
+* *Search* operations
+* *Indexing* operations (JSON, CSV, XML)
+* *Collection* operations (list, stats, health, create)
+* *Schema* retrieval
+
+Additionally, all incoming HTTP requests and outgoing Solr calls are automatically traced.
+
+=== Production Configuration
+
+For production, reduce the sampling rate and configure the OTLP endpoint for your collector:
+
+[,console]
+----
+$ export OTEL_SAMPLING_PROBABILITY=0.1 # 10% sampling
+$ export OTEL_TRACES_URL=https://otel-collector.example.com:4317
+$ PROFILES=http java -jar build/libs/solr-mcp-1.0.0-SNAPSHOT.jar
+----
+
+=== Actuator Endpoints
+
+The following health and metrics endpoints are exposed in HTTP mode:
+
+[,console]
+----
+$ curl http://localhost:8080/actuator/health # Health check
+$ curl http://localhost:8080/actuator/info # Build info
+$ curl http://localhost:8080/actuator/metrics # Available metrics
+$ curl http://localhost:8080/actuator/prometheus # Prometheus scrape endpoint
+$ curl http://localhost:8080/actuator/loggers # Logger levels
+----
+
+== Implementation Details
+
+This section covers the technology choices behind the Solr MCP Server.
+It is primarily useful for contributors and anyone looking to understand the internals.
+
+=== Spring AI MCP
+
+The server is built on the https://docs.spring.io/spring-ai/reference/api/mcp/mcp-server-boot.html[Spring AI MCP] framework (Spring Boot 3.5, Spring AI 1.1.4, Java 25+).
+Spring AI MCP provides the MCP protocol implementation, tool registration via `@McpTool` annotations, and transport abstraction (STDIO and HTTP).
+
+The server's MCP tools are plain Spring `@Service` classes.
+Each public method annotated with `@McpTool` becomes a callable tool that AI clients can invoke.
+Spring AI handles serialization, transport, and protocol compliance.
+
+OAuth2 security is provided by the https://github.com/spring-ai-community/mcp-security[Spring AI Community MCP Security] library, which adds `McpServerOAuth2Configurer` for JWT validation and OAuth2 authorization server metadata discovery.
+
+=== Docker Images with Jib
+
+Docker images are built using https://github.com/GoogleContainerTools/jib[Jib] instead of Spring Boot Buildpacks.
+
+*Why Jib?* Spring Boot Buildpacks output build logs to stdout during image creation.
+Since the MCP STDIO protocol communicates over stdout, these extra log lines corrupt the protocol stream and break STDIO-mode connections.
+Jib produces clean images with no stdout pollution, and also provides:
+
+* Faster builds (no Docker daemon required for registry pushes)
+* Reproducible layers (better caching)
+* Multi-platform support (amd64 + arm64)
+
+[,console]
+----
+$ # Build to local Docker daemon
+$ ./gradlew jibDockerBuild
+
+$ # Push directly to a registry (no Docker daemon needed)
+$ ./gradlew jib -Djib.to.image=ghcr.io/YOUR_USERNAME/solr-mcp:1.0.0-SNAPSHOT
+----
+
+=== Testing with Testcontainers
+
+Integration tests use https://www.testcontainers.org/[Testcontainers] to spin up real Solr instances in Docker.
+This ensures tests run against actual Solr behavior rather than mocks.
+
+The Solr version is configurable via system property:
+
+[,console]
+----
+$ ./gradlew test -Dsolr.test.image=solr:9.9-slim # Default
+$ ./gradlew test -Dsolr.test.image=solr:9.4-slim # Solr 9.4
+$ ./gradlew test -Dsolr.test.image=solr:8.11-slim # Solr 8.11
+----
+
+Tested compatible versions: 8.11, 9.4, 9.9.
+
+=== Observability Internals
+
+All service methods are annotated with `@Observed` (Micrometer), which automatically creates trace spans.
+Spring Boot auto-instruments:
+
+* Incoming HTTP requests
+* Outgoing HTTP calls (SolrJ)
+* Scheduled tasks
+
+Actuator endpoints (`/actuator/health`, `/actuator/metrics`, `/actuator/prometheus`) are provided by Spring Boot Actuator and exposed in HTTP mode.
+
+== Community
+
+* *Website:* https://solr.apache.org/mcp
+* *Slack:* https://the-asf.slack.com/archives/C09TVG3BM1P[`#solr-mcp`] in the `the-asf` Slack workspace
+* *Mailing lists:* Shared with Apache Solr -- see https://solr.apache.org/community.html#mailing-lists-chat[mailing lists]
+* *Issues:* https://github.com/apache/solr-mcp/issues[GitHub Issues]
+
+== Contributing
+
+We welcome contributions!
+Here's the quick version:
+
+. Fork and create a feature branch: `git checkout -b feature/your-feature`
+. Make changes, add tests
+. Format: `./gradlew spotlessApply`
+. Build and test: `./gradlew build`
+. Commit using https://www.conventionalcommits.org/[Conventional Commits]: `feat(search): add fuzzy search support`
+. Push and open a Pull Request
+
+For the full contributing guide, development workflows, and architecture details, see:
+
+* link:../CONTRIBUTING.md[CONTRIBUTING.md] -- Pull request process, commit conventions
+* link:../dev-docs/DEVELOPMENT.md[dev-docs/DEVELOPMENT.md] -- Build system, testing, IDE setup
+* link:../dev-docs/ARCHITECTURE.md[dev-docs/ARCHITECTURE.md] -- Project structure, design decisions
+
+== References
+
+=== MCP Protocol
+
+* https://spec.modelcontextprotocol.io/[Model Context Protocol Specification]
+* https://github.com/modelcontextprotocol[MCP GitHub Organization]
+* https://github.com/modelcontextprotocol/inspector[MCP Inspector]
+
+=== Spring AI MCP
+
+* https://docs.spring.io/spring-ai/reference/api/mcp/mcp-server-boot.html[Spring AI MCP Server (Spring Boot)]
+* https://spring.io/projects/spring-ai[Spring AI MCP Project]
+* https://spring.io/blog/2025/04/02/mcp-server-oauth2/[Spring AI MCP OAuth2 Blog Post]
+
+=== MCP Security
+
+* https://github.com/spring-ai-community/mcp-security[Spring AI Community MCP Security]
+* https://docs.spring.io/spring-security/reference/servlet/oauth2/resource-server/jwt.html[Spring Security OAuth2 Resource Server]
+
+=== Apache Solr
+
+* https://solr.apache.org/mcp[Solr MCP Server Website]
+* https://solr.apache.org/guide/[Apache Solr Documentation]
+* https://solr.apache.org/guide/solr/latest/deployment-guide/solrj.html[SolrJ Client Library]
+
+=== Auth Providers
+
+* https://auth0.com/docs[Auth0 Documentation]
+* https://auth0.com/docs/get-started/authentication-and-authorization-flow/client-credentials-flow[Auth0 Client Credentials Flow]
+* https://www.keycloak.org/documentation[Keycloak Documentation]
+
+=== Tools and Libraries
+
+* https://github.com/GoogleContainerTools/jib[Jib (Docker image builder)]
+* https://www.testcontainers.org/[Testcontainers]
+* https://opentelemetry.io/[OpenTelemetry]
+* https://github.com/grafana/docker-otel-lgtm[Grafana LGTM Stack]
+
+'''
+
+_Built with https://spring.io/projects/spring-ai[Spring AI MCP] and https://solr.apache.org/[Apache Solr].
+Licensed under https://www.apache.org/licenses/LICENSE-2.0[Apache License 2.0]._