GroupDocs.Search MCP server lets AI agents like Claude, Cursor, and Copilot index a folder of documents and search it by content — PDF, Word, Excel, PowerPoint, email archives with their attachments, and 80+ formats in all — locally on your machine, then quote the passages that match. Nothing is uploaded, and the index stays on disk for the next question. Run it with one command:
docker run --rm -i -v $(pwd)/documents:/data \
ghcr.io/groupdocs-search/search-net-mcp:latest
On Linux, add --user "$(id -u):$(id -g)" before the image name — the container runs as a non-root user, and without it the index cannot be written into a folder you own (why).
Note
This product ships via Docker only. The packed .NET tool is 280.9 MiB — the GroupDocs.Search engine is about 200 MiB with its ONNX and SkiaSharp natives — which is over nuget.org’s 250 MB package limit, so this product ships via Docker only, and there is no dnx command for it. Every command in these pages reflects that. Details: MCP server for .NET.
Then ask your agent, in plain language:
Index the contracts folder, then tell me which contracts mention a termination penalty and quote the clause.
The pattern behind every scenario — captured from the server, file names shortened:
user agent Search MCP server
| "Which contracts mention a termination penalty?" |
|---------------->| |
| |-- add_to_index ------------------------->| reads the
| | {"documentsPath":"contracts", | files once,
| | "indexName":"contracts"} | stores text
| |<- "5 document(s) added, 5 in the index" --|
| |-- search ------------------------------->|
| | {"query":"termination AND penalty"} |
| |<- {"documentsFound":3, "documents":[ ... | which files
| | "contracts/acme-...-agreement.pdf", |
| | "contracts/globex-...-agreement.docx",|
| | "contracts/initech-nda.docx" ]} |
| |-- get_text_fragments ------------------->|
| | {"query":"\"termination penalty\""} |
| |<- === contracts/acme-...-agreement.pdf ===| the passages
| | ...a termination penalty of three |
| | monthly fees applies... |
|<- "Two contracts carry one: Acme (3 monthly fees, 12.3), |
| Globex (50% of the remaining fees). Initech excludes it."|
Indexing is the one slow step. After it, each question costs a search and a fragments call, however large the folder — and the answer cites the file and the passage, so you can check it.
Grounded answers without a vector database
You do not need embeddings to ask questions about a folder of documents. An agent with full-text search finds the files, reads only the matching passages, and reformulates when a query misses — research on agentic retrieval has measured keyword tools in an agent loop reaching most of the answer quality of an embedding pipeline (arXiv 2602.23368). What you give up is matching by meaning: the agent has to try the words the documents use. What you gain is a local index with no model calls, results you can explain, and an index that stays current with one call.
Embedding pipeline Agentic full-text search
------------------------------------- -------------------------------------
split, embed, store in a vector store add_to_index: a local full-text index
embed the question, take top-k chunks agent searches, refines, searches again
paste the chunks into the prompt get_text_fragments: quoted passages
re-embed when documents change update_index re-reads what changed
needs an embedding model and a store no model calls, no network at runtime
matches meaning; ranking is opaque matches words; every hit is explainable
The query language in one table
Quote phrases. Put content: in front of a date range. The rest is what you would guess:
Query
Finds
"termination penalty"
the exact phrase — unquoted words separated by spaces match nothing
termination AND penalty · renewal OR renews
both words / either word, anywhere in the document
+--------------+ +----------------------+ +--------------------+
| AI client | stdio | Search MCP server | reads | documents |
| Claude, VS |<------>| Docker container, |<-------| /data: contracts/, |
| Code, Cursor | JSON- | GroupDocs.Search | | mail/, reports/ |
| | RPC | engine in-process | reads/ +--------------------+
+--------------+ | | writes +--------------------+
| |<------>| index store |
+----------------------+ | /data/.groupdocs- |
| search-index/<name>|
nothing listens on a port; no network at runtime +--------------------+
The server uses MCP’s local stdio transport: your AI client starts the container as a child process and talks to it over standard input/output. No inbound ports, no external endpoints, no telemetry. Unlike the other GroupDocs MCP servers it keeps state — the index — inside the folder you mount, so it survives restarts. What stays local and what reaches your model provider: On-premise architecture.