Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ Using a different client, or want STDIO/HTTP/Docker options? See the per-client
| `index-json-documents` | Index documents from a JSON string into a collection |
| `index-csv-documents` | Index documents from a CSV string into a collection |
| `index-xml-documents` | Index documents from an XML string into a collection |
| `index-markdown-documents` | Index a markdown document into a collection, extracting front matter, title, headings, and body text |
| `index-markdown-documents` | Index markdown documents into a collection (one array element per document), extracting front matter, title, headings, and body text |
| `create-collection` | Create a collection (configSet, numShards, replicationFactor optional — default `_default`, `1`, `1`) |
| `list-collections` | List all available Solr collections |
| `get-collection-stats` | Get statistics and metrics for a collection |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import io.micrometer.observation.annotation.Observed;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
Expand Down Expand Up @@ -400,7 +401,8 @@ public String indexXmlDocuments(@McpToolParam(description = "Solr collection to
}

/**
* Indexes a document from a markdown string into a specified Solr collection.
* Indexes markdown documents into a specified Solr collection, one array
* element per document.
*
* <p>
* This method serves as the primary entry point for markdown document indexing
Expand Down Expand Up @@ -447,9 +449,8 @@ public String indexXmlDocuments(@McpToolParam(description = "Solr collection to
*
* @param collection
* the name of the Solr collection to index documents into
* @param markdown
* markdown string to index, optionally starting with YAML front
* matter
* @param documents
* the markdown documents, one string per document matter
* @throws IOException
* if there are critical errors in Solr communication
* @throws SolrServerException
Expand All @@ -461,14 +462,21 @@ public String indexXmlDocuments(@McpToolParam(description = "Solr collection to
@McpTool(
name = "index-markdown-documents",
annotations = @McpTool.McpAnnotations(idempotentHint = true),
description = "Index a document from markdown String into Solr collection, extracting front matter, title, headings, and body text. "
description = "Index markdown documents into Solr collection, one array element per document, extracting front matter, title, headings, and body text from each. "
+ "Pass many documents in one call rather than one call per document. "
+ "Do NOT use for JSON/CSV/XML input; use index-json-documents, index-csv-documents, or index-xml-documents instead. "
+ "Only convert source content to markdown when there is no dedicated tool for the source format, and supply a stable 'id' in the YAML front matter when doing so.")
public String indexMarkdownDocuments(@McpToolParam(description = "Solr collection to index into") String collection,
@McpToolParam(
description = "Markdown string to index, optionally starting with YAML front matter") String markdown)
description = "Markdown documents to index, one string per document, each optionally starting with YAML front matter") List<String> documents)
throws IOException, SolrServerException {
List<SolrInputDocument> schemalessDoc = indexingDocumentCreator.createSchemalessDocumentsFromMarkdown(markdown);
if (documents == null) {
throw new IllegalArgumentException("documents cannot be null");
}
List<SolrInputDocument> schemalessDoc = new ArrayList<>();
for (String markdown : documents) {
schemalessDoc.addAll(indexingDocumentCreator.createSchemalessDocumentsFromMarkdown(markdown));
}
int successCount = indexDocuments(collection, schemalessDoc);
return "Successfully indexed " + successCount + " of " + schemalessDoc.size() + " documents into collection '"
+ collection + "'";
Expand Down Expand Up @@ -620,7 +628,7 @@ private static IndexTool resolveIndexTool(String format) {
case "json" -> new IndexTool("index-json-documents", "json");
case "csv" -> new IndexTool("index-csv-documents", "csv");
case "xml" -> new IndexTool("index-xml-documents", "xml");
case "markdown", "md" -> new IndexTool("index-markdown-documents", "markdown");
case "markdown", "md" -> new IndexTool("index-markdown-documents", "documents");
default ->
throw new IllegalArgumentException("format must be one of json/csv/xml/markdown, got: " + format);
};
Expand Down Expand Up @@ -691,7 +699,7 @@ public String indexDataPrompt(

Next step suggestion: once data is indexed, the `search-collection` prompt drives
searching it.
""".formatted(indexTool.paramName(), collection, collection, sampleSection, indexTool.name(),
""".formatted(format.trim().toLowerCase(), collection, collection, sampleSection, indexTool.name(),
collection, indexTool.paramName(), collection);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ void indexMarkdownDocumentAndFindItById() throws Exception {
""";

CallToolResult indexResult = mcpClient.callTool(new CallToolRequest("index-markdown-documents",
Map.of("collection", COLLECTION, "markdown", markdown)));
Map.of("collection", COLLECTION, "documents", List.of(markdown))));

assertNotNull(indexResult);
assertNotError(indexResult);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,20 @@ private List<SolrInputDocument> createMockDocuments(int count) {
return docs;
}

@Test
void indexMarkdownDocuments_IndexesEachElementAsItsOwnDocument() throws Exception {
when(indexingDocumentCreator.createSchemalessDocumentsFromMarkdown("# One")).thenReturn(createMockDocuments(1));
when(indexingDocumentCreator.createSchemalessDocumentsFromMarkdown("# Two")).thenReturn(createMockDocuments(1));
when(solrClient.add(eq("test_collection"), any(Collection.class))).thenReturn(null);

String result = indexingService.indexMarkdownDocuments("test_collection", List.of("# One", "# Two"));

assertTrue(result.contains("2 of 2"), result);
verify(indexingDocumentCreator).createSchemalessDocumentsFromMarkdown("# One");
verify(indexingDocumentCreator).createSchemalessDocumentsFromMarkdown("# Two");
verify(solrClient, times(1)).add(eq("test_collection"), any(Collection.class));
}

@Test
void indexDataPrompt_jsonPath_referencesIndexJsonDocuments() {
String sample = """
Expand Down