MCP Lucene Server
Description
MCP Lucene Server is a Model Context Protocol (MCP) server that exposes Apache Lucene's full-text search capabilities through a conversational interface. It allows AI assistants (like Claude) to help users search, index, and manage document collections without requiring…
About
MCP Lucene Server is a Model Context Protocol (MCP) server that exposes Apache Lucene's full-text search capabilities through a conversational interface. It allows AI assistants (like Claude) to help users search, index, and manage document collections without requiring technical knowledge of Lucene or search engines.
Details
- Author
- mirkosertic
- Categories
- Search, Database, Other
Jump to
Setup
Install MCP Lucene Server in your MCP client (Claude Desktop, Cursor, Windsurf, and others).
Repository: https://github.com/mirkosertic/MCPLuceneServer
Follow the installation instructions in the repository README, then restart your MCP client.
A Model Context Protocol (MCP) server that exposes Apache Lucene fulltext search capabilities with automatic document crawling and indexing. This server supports both STDIO transport (for Claude Desktop integration) and HTTP transport (for web-based clients and remote access).
- Automatically indexes PDFs, Microsoft Office, and OpenOffice documents
- Multi-threaded crawling for fast indexing
- Real-time directory monitoring for automatic updates
- Incremental indexing with full reconciliation (skips unchanged files, removes orphans)
- Simple keyword search (no Lucene syntax needed) and full Lucene query syntax search
- Field-specific filtering (by author, language, file type, etc.)
- Structured passages with quality metadata for LLM consumption
- Paginated results with filter suggestions
- Optional pure KNN embedding-based semantic search using multilingual-e5 embeddings with Late Chunking
- Finds semantically related documents even without exact keyword matches
- RequiresVECTOR_MODELto be configured. SeeSEMANTICSEARCH.mdfor details.
- Deep query analysis and profiling (profileQuerytool)
- Understand why queries return certain results and how scoring works
- Filter impact analysis showing document reduction per filter
- Document scoring explanations with BM25 breakdown
- Term statistics (IDF, rarity, document frequency)
- Actionable optimization recommendations
- LLM-optimized structured output for easy interpretation
- Automatic language detection
- Author, title, creation date extraction
- File type and size information
- SHA-256 content hashing for change detection
- Load additional metadata from PostgreSQL, MySQL, or any JDBC-compatible database at index time
- JSON-based metadata with explicit field types (keyword, text, int, long, date)
- Multi-value field support, automatic facet registration
- Background sync job for incremental metadata updates (configurable interval)
- All DB-sourced fields prefixed withdbmeta_to avoid schema collisions
- Automatic removal of broken/invalid characters (replacement chars, control chars, zero-width chars)
- Whitespace normalization (multiple spaces collapsed to single space)
- Ensures clean, readable search results and passages
- Batch processing for efficient indexing
- NRT (Near Real-Time) search with dynamic optimization
- Configurable thread pools for parallel processing
- Progress notifications during bulk operations
- Dual transport support: STDIO (default) and HTTP
- STDIO transport for seamless Claude Desktop integration
- HTTP transport for web-based clients and remote access
- Comprehensive MCP tools for search and crawler control
- Flexible configuration via YAML and system properties
- Cross-platform notifications (macOS Notification Center, Windows Toast, Linux notify-send)
- Documentation
- Quick Start
- MCP Tools
- Search Tools
- Semantic Search Tools
- Debug Tools
- Crawler Tools
- Index Info Tools
- Observability Tools
- Admin Tools
- Running for Development
- Debugging with MCP Inspector
- Adding Documents to the Index
- PIPELINE.md— Analyzer chains, query pipeline, and tokenization details
- SEMANTICSEARCH.md— Semantic search architecture: Late Chunking, Block Join indexing, KNN scoring, and configuration
- ONNX.md— ONNX model export, optimization and INT8 quantization guide for e5-base and e5-large
Get up and running with MCP Lucene Server in three steps.
- Java 25 or later- Required to run the server
- Maven 3.9+ (only if building from source)
Option A: Download Pre-built JAR (Recommended)
- Go to theActions tab
- Click on the most recent successful workflow run
- Scroll down to "Artifacts" and downloadluceneserver-X.X.X-SNAPSHOT
- Extract the ZIP file to get the JAR
For tagged releases, you can also download from theReleases page.
This creates an executable JAR attarget/luceneserver-0.0.1-SNAPSHOT.jar.
Option C: Use Docker (Only HTTP-Transport is available)
docker run -v ./lucene-data-dir:/userdata -p 9000:9000 -it mirkosertic42/mcpluceneserver:main
This starts a Docker container with the server listening on port 9000. All configuration data including the index files is stored in the./lucene-data-dirdirectory on the host machine. Please note that the Lucene indexer can only access files that are visible to the Docker container, so all files must be placed in the./lucene-data-dirdirectory or a subdirectory of it. JVM settings can be adjusted by theJAVA_OPTSenvironment variable, which can be modified using the Docker CLI or a Docker Compose file. The default maximum JVM Heap size(-Xmx) is 2GB.
To enablesemantic search, set theVECTOR_MODELenvironment variable:
docker run -v ./lucene-data-dir:/userdata -p 9000:9000 \ -e VECTOR_MODEL=e5-base \ -e JAVA_OPTS="-Xmx4g" \ -it mirkosertic42/mcpluceneserver:main
Locate your Claude Desktop configuration file:
- macOS:~/Library/Application Support/Claude/claude_desktop_config.json
- Windows:%APPDATA%\Claude\claude_desktop_config.json
- Linux:~/.config/Claude/claude_desktop_config.json
Add the Lucene MCP server to themcpServerssection:
{ "mcpServers": { "lucene-search": { "command": "java", "args": [ "--enable-native-access=ALL-UNNAMED", "-Xmx2g", "-Dspring.profiles.active=deployed", "-jar", "/absolute/path/to/luceneserver-0.0.1-SNAPSHOT.jar" ] } } }
Important:Replace/absolute/path/to/luceneserver-0.0.1-SNAPSHOT.jarwith the actual absolute path to your JAR file.
The-Dspring.profiles.active=deployedflag is required for clean STDIO communication (disables console logging and startup banner).
- Restart Claude Desktopto load the new configuration
- Verifythe server is running in Claude Desktop's developer settings
- Tell Claudeto add your documents:
"Add /Users/yourname/Documents as a crawlable directory and start crawling"
That's it! The configuration is saved to~/.mcplucene/config.yamland persists across restarts. You can now search your documents through Claude.
- "Search for machine learning papers"
- "Find all PDFs by John Doe"
- "What documents mention quarterly reports?"
Tools are organized into groups. UseLUCENE_TOOLS_INCLUDEandLUCENE_TOOLS_EXCLUDEto control which tools are exposed (seeTool Exposure Configuration).
Search the Lucene fulltext index using plain text keyword search. Special characters are treated as literals — no Lucene syntax knowledge required. Uses BM25 with German and English stemming.
- query(optional): Plain text search query. Can benullor""to match all documents (useful with filters).
- filters(optional): Array of structured filters for precise field-level filtering (seeStructured Filtersbelow)
- page(optional): Page number, 0-based (default: 0)
- pageSize(optional): Results per page (default: 10, max: 100)
- sortBy(optional): Sort field -_score(default),modified_date,created_date,file_size, or anydbmeta_metadata field (INT/LONG/DATE/KEYWORD) registered from JDBC enrichment
- sortOrder(optional): Sort order -ascordesc(default:desc)
Search the Lucene fulltext index using full Lucene query syntax. Supports Boolean operators, wildcards, proximity queries, and field-specific queries. Uses BM25 with German and English stemming.
- query(optional): The search query using Lucene query syntax. Can benullor""to match all documents (useful with filters).
- filters(optional): Array of structured filters for precise field-level filtering (seeStructured Filtersbelow)
- page(optional): Page number, 0-based (default: 0)
- pageSize(optional): Results per page (default: 10, max: 100)
- sortBy(optional): Sort field -_score(default),modified_date,created_date,file_size, or anydbmeta_metadata field (INT/LONG/DATE/KEYWORD) registered from JDBC enrichment
- sortOrder(optional): Sort order -ascordesc(default:desc)
By default, results are sorted by relevance score (most relevant first). You can sort by metadata fields:
// Most recently modified documents { "query": "contract", "sortBy": "modified_date", "sortOrder": "desc" } // Oldest documents first { "query": "contract", "sortBy": "created_date", "sortOrder": "asc" } // Smallest files (for quick review) { "query": "summary", "sortBy": "file_size", "sortOrder": "asc" } // Combine sorting with filters { "query": "", "sortBy": "modified_date", "sortOrder": "desc", "filters": [ { "field": "file_extension", "value": "pdf" }, { "field": "modified_date", "operator": "range", "from": "2024-01-01" } ] }
Note:When sorting by metadata fields, relevance scores are still computed and used as a secondary sort criterion for tie-breaking.
Thefiltersarray accepts objects with these fields:
- Faceted(DrillSideways):language,file_extension,file_type,author
- String (exact match):file_path,content_hash
- Numeric/date (range):file_size,created_date,modified_date,indexed_date
Date format:ISO-8601 —"2024-01-15","2024-01-15T10:30:00", or"2024-01-15T10:30:00Z"
- Filters ondifferentfields use AND logic
- Multipleeqfilters orinvalues on thesamefaceted field use OR logic (DrillSideways)
- not/not_infilters are applied as MUST_NOT clauses
This server is designed to work with AI assistants like Claude. Instead of using traditional Lucene synonym files, the AI generates context-appropriate synonyms automatically by constructing OR queries.
Why this is better than traditional synonyms:
- Context-aware: The AI understands your intent and picks relevant synonyms (e.g., "contract" in legal context vs. "contract" in construction)
- No maintenance: No need to maintain static synonym configuration files
- Domain-adaptive: Works across legal, technical, medical, or casual language automatically
- Multilingual: Generates synonyms in any language without configuration
When you ask Claude to "find documents about cars", it automatically searches for(car OR automobile OR vehicle)- giving you better results than a static synonym list.
The server uses a multi-analyzer indexing pipeline and multi-field weighted query pipeline for comprehensive search:
- Unicode normalization— NFKC normalization, diacritic folding, ligature expansion via ICUFoldingFilter
- Leading wildcard optimization—content_reversedfield stores reversed tokens for efficientvertrag-style queries
- Case-insensitive wildcards— wildcard/prefix terms are automatically lowercased
- OpenNLP lemmatization— dictionary-based lemmatization for German and English, including irregular forms (ran→run, ging→gehen, paid→pay, analyses→analysis)
- Dual-language indexing— both German and English lemma fields indexed for all documents, enabling mixed-language matching
- German umlaut transliteration—content_translit_deshadow field maps digraphs (Mueller→Müller)
- Automatic phrase expansion— exact phrases auto-expand to include proximity matches (see below)
- Adaptive prefix scoring— BM25 scoring for specific prefixes (>= 4 chars)
SeePIPELINE.mdfor complete analyzer chain documentation, concrete examples, and query pipeline details.
The AI assistant compensates for remaining limitations (no synonym expansion, no phonetic matching) by expanding queries intelligently.
-
Generate Synonyms Yourself:Use OR to combine related terms:
- Instead of:contract
- Use:(contract OR agreement OR deal)
Use Wildcards for Variations:Handle different word forms:
- Instead of:contract
- Use:contract(matches contracts, contracting, contracted)
Leverage Facets:Use the returned facet values to discover exact terms in the index:
- Checkfacets.authorto find exact author names
- Checkfacets.languageto see available languages
- Use these exact values for filtering
(contract OR agreement) AND (sign OR execut) AND author:"John Doe"
Supported Query Syntax (extendedSearch):
- Simple terms:hello world(implicit AND between terms)
- Phrase queries:"exact phrase"(preserves word order)
- Boolean operators:term1 AND term2,term1 OR term2,NOT term
- Trailing wildcard:contractmatches contracts, contracting, contracted
- Leading wildcard:vertragefficiently finds Arbeitsvertrag, Kaufvertrag (optimised via reverse token field)
- Infix wildcard:vertragfinds both Vertragsbedingungen and Arbeitsvertrag
- Single char wildcard:te?tmatches test, text
- Fuzzy search:term~2finds terms within Levenshtein edit distance 2 (default: 2)
- Proximity search:"term1 term2"~5finds terms within 5 words of each other
- Field-specific search:title:hello content:world
- Grouping:(contract OR agreement) AND signed
- Range queries:modified_date:[1609459200000 TO 1640995200000](timestamps in milliseconds)
Multi-word phrase queries are automatically expanded:"Domain Design"becomes("Domain Design")^2.0 OR ("Domain Design"~3). Exact matches rank highest (2.0x boost), while near-matches (within 3 words) also surface at lower scores. Single-word phrases and user-specified slop are not expanded.
SeePIPELINE.mdfor detailed examples and configuration.
Prefix queries with >= 4 characters (vertrag,design) use real BM25 scoring, ranking shorter/more frequent terms higher than long compounds. Shorter prefixes (ver) use constant scoring for performance. This balances ranking quality with speed automatically.
SeePIPELINE.mdfor scoring examples and technical details.
Use wildcards for German compounds:vertragfinds Arbeitsvertrag,vertragfinds Vertragsbedingungen. Leading wildcards are optimized via thecontent_reversedfield.
OpenNLP lemmatization handles morphological variants automatically. German: "Haus" finds "Häuser", "gehen" finds "ging". English: "run" finds "ran", "pay" finds "paid". Exact matches always rank highest.
All documents indexed with both German and English lemma fields, enabling mixed-language matching. German docs with English technical terms ("Recommendation Engines") match singular queries ("Recommendation Engine") via the English lemmatizer, and vice versa.
Thecontent_translit_defield maps ASCII digraphs to umlauts: "Mueller" matches "Müller", "Kaese" matches "Käse".
SeePIPELINE.mdfor complete analyzer chains, concrete token examples, and query pipeline details.
- Paginated document results, each containing apassagesarray with highlighted text and quality metadata
- Document-level relevance scores
- facets: Facet values and counts from the result set (uses DrillSideways when facet filters are active, showing alternative values)
- activeFilters: Mirrors the inputfilterswith amatchCountfor each filter (count from facets, or -1 for range/non-faceted filters)
- Search execution time in milliseconds (searchTimeMs)
// Browse all English PDFs { "query": null, "filters": [ { "field": "language", "value": "en" }, { "field": "file_extension", "value": "pdf" } ]} // Date range filter { "query": "contract*", "filters": [ { "field": "modified_date", "operator": "range", "from": "2024-01-01", "to": "2025-12-31" } ]} // Multiple values with exclusion { "query": "report", "filters": [ { "field": "file_extension", "operator": "in", "values": ["pdf", "docx"] }, { "field": "language", "operator": "not", "value": "unknown" } ]}
Semantic Search Tools (group:semantic)
Semantic search tools requireVECTOR_MODELto be configured (e.g.,VECTOR_MODEL=e5-base).
Pure KNN embedding-based semantic search. Finds semantically related documents even without exact keyword matches. Results are ordered by cosine similarity. RequiresVECTOR_MODELto be configured.
- query(required): Natural language query — the server computes an embedding and finds the nearest document chunks.
- filters(optional): Array of structured filters (same format assimpleSearch/extendedSearch)
- page(optional): Page number, 0-based (default: 0)
- pageSize(optional): Results per page (default: 10, max: 100)
- similarityThreshold(optional): Minimum cosine similarity score to include a result (0.0–1.0, default: 0.70). Lower = more results (broader match); higher = fewer results (closer match).
UseprofileSemanticSearchto tunesimilarityThresholdfor your corpus.
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.




