adityamparikh opened a new issue, #279: URL: https://github.com/apache/solr-mcp/issues/279
## Summary Ship a Solr [Agent Skill](https://agentskills.io/specification) inside the server and serve it to clients over MCP, following the Skills extension ([SEP-2640](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2640-skills-extension.md), status **Final**, merged 2026-09-13). The tools give an agent safe, deterministic operations. They do not teach it how to use Solr well. `docs/FAQ.md` ("LLMs already know Solr. Could a Solr skill replace this MCP server?") concludes the two are complementary. Serving the skill from the server means it versions with the tools it describes and reaches every client through the same connection and auth. This widens the FAQ's "thin skill for query and faceting know-how" to cover indexing, troubleshooting and version differences, so the FAQ should be updated with it. ## What SEP-2640 defines - Each file of a skill directory is an MCP **resource**, conventionally at `skill://<skill-path>/<file>`. The last path segment must equal the skill's `name`. - The server declares the `resources` capability plus `extensions["io.modelcontextprotocol/skills"]`. - Required methods: `skills/list` (paginated; per skill `uri`, verbatim `frontmatter`, and `resources` = `[{uri, digest: sha256, size}]` or `"dynamic"`) and `skills/get` (by `SKILL.md` URI; `-32602` if unknown). `resources/directory/read` is optional behind `directoryRead`. - Hosts load only frontmatter up front and fetch `SKILL.md` and supporting files with `resources/read` when needed. - Limits: 512 files and 16 MiB per skill. The SEP defines no version field (its example puts `metadata.version` in frontmatter) and no resource-template or subscription semantics for skills. - A host must not treat a resource as a skill merely because of its URI scheme; a pointer in server `instructions` is confirmed through `skills/get`. ## Proposed skill: `solr` One skill, `skill://solr/SKILL.md`: the tool surface is one domain and the description must trigger on "anything Solr". ``` solr/ SKILL.md # < 500 lines, < 5000 tokens references/ query-syntax.md schema-design.md indexing.md troubleshooting.md solr-versions.md ``` Frontmatter: `name: solr`, a `description` (<= 1024 chars) that says what it does and when to use it, `license: Apache-2.0`. `SKILL.md` body: when to use; the workflow (discover -> inspect schema/stats -> query -> index -> verify) and which tool answers which question; one line per reference file saying when to open it. ### Ownership: skill vs prompts vs instructions The `search-collection` and `design-schema` prompts already cover text-vs-exact fields, `docValues` for facet/sort, `q` vs `filterQueries`, range syntax and `stored`/`indexed`/`copyField` basics, and `spring.ai.mcp.server.instructions` already states the tool-surface boundaries (#162). The skill must not restate them. Rule: **the skill holds what the prompts and instructions don't** (Solr behaviour behind the tools, error-to-fix mappings, version differences), and the prompts keep their step-by-step task flows. Where a prompt and a reference file overlap, trim the prompt to a pointer in the same PR. ### Only teach what the tools can do `search` takes `collection`, `query`, `filterQueries`, `facetFields`, `sortClauses`, `start`, `rows`. It has no `defType`/`qf`/`mm`, no highlighting and no `df` (open: #209), and there is no copyField tool. Reference files describe only what the shipped tools can express, and gain sections as #209 and similar land. Cluster procedures stay out: #229 places those in a companion `solr-on-kubernetes` skill outside this repo, and `SKILL.md` links rather than duplicates. `SKILL.md` does not copy the instructions' boundary text; instructions are always in context already. ### Format rules - `references/` one level deep from `SKILL.md`. - No `scripts/`: hosts must not run MCP-origin code without explicit approval, and every operation here is already a tool. - `metadata.version` tracks **skill content**, not the server version. Hosts bind approval to the digest set, so a version bump on every server release would re-prompt users when nothing in the skill changed. ## Proposed delivery **Single source of truth:** `src/main/resources/skills/solr/**`, authored as an ordinary Agent Skills directory so the same files can be installed into `~/.claude/skills/` or a plugin for clients that don't speak the extension. ### Phase 1 - plain resources on the pinned SDK (2.0.1), stdio and HTTP One `@McpResource` per file, e.g. `uri = "skill://solr/references/indexing.md"`, with: - `mimeType = "text/markdown"` (Spring AI defaults to `text/plain`); - `annotations` audience set to ASSISTANT (the default is USER; skill files are for the model); - `name`/`description` taken from frontmatter for `SKILL.md`. Static URIs, not `skill://solr/{file}`: the SDK's template matcher compiles each `{var}` to `([^/]+)`, so one template cannot match `references/x.md`, and templates are listed under `resources/templates/list`, not `resources/list`. Spring AI builds stateless resource specifications from `@McpResource`, and `resources/list|read` are registered on the stateless server, so this works under `protocol=stateless` and stdio. Decide whether skill files carry `@PreAuthorize("isAuthenticated()")` like the existing resources in secured HTTP mode. Add a pointer to `skill://solr/SKILL.md` in `spring.ai.mcp.server.instructions` (conflicts with #272 and #210, which edit the same block; under #256 it also triggers an eval re-run). What this gives, accurately: readable resources and an instructions pointer. A host can only use them if it lets the model call `resources/read` itself; a host won't register them as a skill without `skills/*`. Phase 1 is also a no-regret base for Phase 2. Native image: add a resource hint for `skills/**` in `SolrNativeHints`, following its existing resource patterns. ### Phase 2 - `skills/list` / `skills/get` The SEP-conformant path. Constraints, as of 2026-10-23: - MCP Java SDK 2.0.1 has no `skills/*` handlers and no `extensions` on `ServerCapabilities`; 2.1.0 (released 2026-10-16) adds `extensions` (SEP-2133, java-sdk #1064). - The `skills/*` work in flight does not cover our stdio server: java-sdk [#1141](https://github.com/modelcontextprotocol/java-sdk/pull/1141) touches only the stateless server classes, and [#1214](https://github.com/modelcontextprotocol/java-sdk/pull/1214) targets the new 2026-07-28 "modern" server, which so far ships only in v2.2.0-M1 and has no client side. Tracking issue: [#1140](https://github.com/modelcontextprotocol/java-sdk/issues/1140). Neither gives `skills/*` over stdio, and taking #1214 would mean moving HTTP onto the modern server. - The repo pins `mcp-sdk` separately (`gradle/libs.versions.toml`), so bumping to 2.1.0 does not need a Spring AI release; compatibility of Spring AI 2.0.1 with SDK 2.1.0 is not yet checked. - Whether `skills/*` is valid on a 2025-11-25 `initialize` session is not settled: the SEP doesn't forbid it, but its examples are 2026-07-28 shaped. When a viable SDK path exists: generate the `{uri, digest, size}` manifest in a Gradle task from the same files `resources/read` serves, declare the extension, implement the two methods from the manifest. Track as a follow-up issue linked to the java-sdk items. ## Tests - Unit: `skills-ref validate` (the Agent Skills reference validator) or an equivalent check on `skills/solr` - `name` equals directory, description 1-1024 chars, `SKILL.md` < 500 lines. - Unit: every file under `skills/solr/**` has a registered resource, so a new reference file can't be left unserved. - Integration: `resources/list` + `resources/read` of every `skill://solr/...` URI in `McpClientIntegrationTestBase` (http, stdio-jar, Docker stdio). No test reads an MCP resource over the wire today, so add the existing `solr://` resources in the same change. - Native: `dockerIntegrationTest -Pnative` covers stdio via the same base class; native-http runs only `DockerImageHttpIntegrationTest`, so add a resource read there or state the gap. - Phase 2 only: manifest digests match file bytes; file count and size within SEP limits. ## Open questions - Which hosts let the model call `resources/read` on its own, and which render `skill://` resources or honour `audience`? Official client matrix today: mcpc full; ChatGPT, fast-agent, MCP Inspector partial; Claude not listed. - Which Phase 2 route: wait for a stateful-server hook in the SDK, or move to the modern server? - How do we measure that the skill helps? #256 / #264 (tool-selection evals) could add a with/without-skill arm. - Does `@McpResource` need anything in the native image beyond the `skills/**` hint? Needs a native run to answer. RAT is not a question: `**/*.md` is excluded in `buildSrc/.../org.apache.solr.mcp.rat.gradle.kts`, so `SKILL.md` can start with frontmatter. ## Acceptance criteria (Phase 1) - [ ] `skills/solr/SKILL.md` and `references/*` exist and pass format validation. - [ ] Every skill file is readable via `resources/read` at `skill://solr/...` under stdio and http (JVM), and under native stdio. - [ ] Reference content is limited to what shipped tools can do, and overlap with the `search-collection` / `design-schema` prompts is resolved per the ownership rule. - [ ] `spring.ai.mcp.server.instructions` points at `skill://solr/SKILL.md`. - [ ] README section on the skill; `docs/FAQ.md` updated. - [ ] `./gradlew build` passes. - [ ] Phase 2 follow-up issue filed. ## References - SEP-2640: https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2640-skills-extension.md - Extension overview: https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/extensions/skills/overview.mdx - Agent Skills specification: https://agentskills.io/specification - Related: #162, #209, #210, #225, #226, #229, #256, #264, #272; adjacent knowledge delivery: #85 -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
