MCP server for GroupDocs.Search — index documents and run full-text search via AI agents.
Runs on your machine from its package; the steps are below.
At most: creates or changes data: records, files, settings.
Odel charges nothing per call. The publisher may charge for its own service.
Runs locally over stdio
This server isn't hosted — your MCP client launches it from a package registry. Use one of the commands below, or drop the config into your client (e.g. Claude Desktop).
Run
docker run -i --rm ghcr.io/groupdocs-search/search-net-mcp:26.10.0
MCP client config
{
"mcpServers": {
"groupdocs-search": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/groupdocs-search/search-net-mcp:26.10.0"
]
}
}
}MCP server that exposes GroupDocs.Search as AI-callable tools for Claude, Cursor, GitHub Copilot, and other MCP agents. It indexes folders of PDF, Office, email, archive and 70+ other document formats locally, then answers full-text, boolean, phrase, fuzzy and date-range queries over them — documents never leave your machine.
One-click installs pre-fill every supported setting: edit the placeholder host path in the volume mount after install; an empty GROUPDOCS_LICENSE_PATH runs in evaluation mode.
More clients - ready-made configs for Claude Code, Codex CLI, Visual Studio 2022, Cursor, Windsurf, Cline, and JetBrains Rider live in
install/generated/.
This product ships via Docker (GHCR) only. The GroupDocs.Search engine DLL is about 200 MiB and
ships ONNX Runtime natives, so the packed tool (~281 MiB) exceeds NuGet.org's 250 MB limit — dnx and
dotnet tool install are not available for it. When a slimmer engine packs under the limit, the
standard NuGet flow returns (see the revert notes in .github/workflows/publish_prod.yml).
docker run --rm -i \
-v $(pwd)/documents:/data \
ghcr.io/groupdocs-search/search-net-mcp:latest
Images are multi-arch (linux/amd64 + linux/arm64), tagged latest plus an immutable version tag
per release (e.g. :26.10.1). To pin, replace :latest with the version tag — recommended for shared
configs and CI.
The image runs as a non-root user (uid 1654). On Linux a mounted folder keeps its host owner, so a folder
you own is read-only inside the container and indexing fails with "The index folder … is not
writable". Add --user so the container writes as you:
docker run --rm -i --user "$(id -u):$(id -g)" \
-v $(pwd)/documents:/data \
ghcr.io/groupdocs-search/search-net-mcp:latest
MCP client configs (JSON) do not run a shell, so put the numbers in directly — id -u and id -g
print them, typically 1000: "args": ["run", "--rm", "-i", "--user", "1000:1000", "-v", …]. Docker
Desktop on Windows and macOS does not need this.
Search is the one stateful server in the GroupDocs MCP family: an index is a persistent, searchable
copy of your documents' text that survives restarts. By default it is kept in a
.groupdocs-search-index folder inside the documents folder (/data/.groupdocs-search-index in the
container), so the one volume mount above is all you need and the index is never indexed itself.
If the documents folder is read-only, keep the index in its own folder:
docker run --rm -i \
-v /path/to/documents:/data:ro \
-v /path/to/index:/index -e GROUPDOCS_MCP_INDEX_PATH=/index \
ghcr.io/groupdocs-search/search-net-mcp:latest
| Tool | Description |
|---|---|
add_to_index | Indexes a file, a folder (recursively), or the whole storage folder. Creates the index on demand. |
search | Finds the documents that match a query, ranked by relevance, with occurrence counts — returned as JSON |
get_text_fragments | Returns the matching passages with surrounding words, so the agent can quote or answer from them |
update_index | Re-reads changed files, adds new files in indexed folders, drops deleted ones |
remove_from_index | Removes an indexed path (a folder or file passed to add_to_index) from the index; files on disk are untouched |
create_index | Creates or opens a named index (contracts, hr/2026), or recreates it empty |
get_index_info | Reports whether an index exists, its document count, indexed paths, version, and the other indexes — as JSON |
get_license_status | Reports the active licensing mode (evaluation / licensed / metered), the engine version, and — under metered — the consumed quantity and credit. Processes no document. |
Paths are always relative to the documents folder (contracts, reports/2026/q3.pdf), and indexes
are referred to by name, never by filesystem path. Several named indexes can live side by side.
Query syntax (GroupDocs.Search DSL): single words (invoice); phrases in double quotes
("force majeure" — unquoted multi-word input does not match); AND, OR, NOT and parentheses;
? character wildcards (?ffect, princip?(2~4)); daterange(2026-01-01 ~~ 2026-06-30); number
ranges (100 ~~ 500); field prefixes (filename: lease); regular expressions starting with ^; and
fuzzy matching via the fuzzy argument.
Indexable formats include PDF, DOC/DOCX, XLS/XLSX, PPT/PPTX, ODT/ODS/ODP, RTF, TXT, HTML, EPUB, FB2,
EML/EMLX/MSG, PST/OST, ONE and ZIP — including documents inside archives and email attachments.
get_index_info with includeSupportedFormats: true lists the engine's full set.
Copy any of these into Claude Desktop, Cursor, or GitHub Copilot Chat after the server is connected.
The MCP server itself is MIT; the underlying GroupDocs.Search engine requires a license for production use. Without one the server runs in evaluation mode, and the limits are counts, not watermarks — results look complete and are not:
evaluation note while this applies.There are two ways to license the server.
License file — mount your GroupDocs.Search.lic (or GroupDocs.Total.lic) into the container and
point GROUPDOCS_LICENSE_PATH at it. Works offline.
Metered (pay-per-use) — set both GROUPDOCS_METERED_PUBLIC_KEY and
GROUPDOCS_METERED_PRIVATE_KEY. You are billed for what you actually process, which suits AI agents
well because their usage is bursty and hard to predict up front. If both a metered key pair and a
license file are configured, metered wins and the file is ignored.
Metered mode needs outbound connectivity. Usage is reported to GroupDocs servers, so air-gapped or firewalled deployments must allow that egress — or use a license file instead.
Call the get_license_status tool at any time to see which mode is active, and — under metered —
the consumed quantity and remaining credit. It processes no document and changes nothing.
The metered private key is a secret. MCP client configs are plain files on disk, and a project-scoped
.mcp.json is committed by convention, so prefer, in order:
launchctl setenv, or launch the client
from a terminal.${VAR}; VS Code uses
${env:VAR} and ${input:...}).~/.claude.json) is acceptable for a single
developer..mcp.json.For Docker, forward the values without writing them into any file — the names alone, so the keys never appear in the command line:
docker run --rm -i \
-e GROUPDOCS_METERED_PUBLIC_KEY -e GROUPDOCS_METERED_PRIVATE_KEY \
-v /path/to/documents:/data \
ghcr.io/groupdocs-search/search-net-mcp:latest
| Variable | Description | Default |
|---|---|---|
GROUPDOCS_MCP_STORAGE_PATH | Folder with the documents to index; tool paths are relative to it | ./Files (/data in the image) |
GROUPDOCS_MCP_OUTPUT_PATH | (Optional) writable folder; indexes go under it when GROUPDOCS_MCP_INDEX_PATH is not set | GROUPDOCS_MCP_STORAGE_PATH |
GROUPDOCS_MCP_INDEX_PATH | (Optional) folder that holds the indexes, one sub-folder per index name | <output or storage>/.groupdocs-search-index |
GROUPDOCS_LICENSE_PATH | Path to a GroupDocs license file, as seen inside the container. Ignored when metered keys are set | (evaluation mode) |
GROUPDOCS_METERED_PUBLIC_KEY | Metered (pay-per-use) public key. Needs the private key too; takes precedence over GROUPDOCS_LICENSE_PATH | (unset) |
GROUPDOCS_METERED_PRIVATE_KEY | Metered private key. Secret — pass it from the environment, never from a committed config | (unset) |
Indexes written by GroupDocs.Search 22.7–26.8 are converted to the 26.10 format the first time they are
opened; the original is kept next to it as <name>.pre-26.10-backup.
{
"mcpServers": {
"groupdocs-search": {
"command": "docker",
"args": ["run", "--rm", "-i", "-v", "/path/to/documents:/data", "ghcr.io/groupdocs-search/search-net-mcp:latest"]
}
}
}
To use a license, add
"-v", "/path/to/license-folder:/license", "-e", "GROUPDOCS_LICENSE_PATH=/license/GroupDocs.Total.lic"before the image name. To pin a version, replace:latestwith the release tag.
Use the Install in VS Code button above, or add to .vscode/mcp.json
(also in install/generated/vscode-mcp.json):
{
"inputs": [
{
"type": "promptString",
"id": "storage_path",
"description": "Folder with the documents to index.",
"password": false
}
],
"servers": {
"groupdocs-search": {
"command": "docker",
"args": ["run", "--rm", "-i", "-v", "${input:storage_path}:/data", "ghcr.io/groupdocs-search/search-net-mcp:latest"]
}
}
}
cd docker
docker compose up
Edit docker/docker-compose.yml to point volumes at your local documents folder.
Step-by-step deployment guides and a published-image integration test suite live in the companion repo GroupDocs.Search.Mcp.Tests:
MIT — see LICENSE