A lot of business knowledge lives in email, and the part you need is usually in an attachment: the quotation, the signed amendment, the revised schedule. GroupDocs.Search.Mcp, running locally in Docker, opens email files and archives (PST, OST, MSG, EML) and indexes every message and every attachment, so Claude Desktop, Cursor or Copilot can search an archive in place and say exactly which attachment a match came from:
Index the mail folder. Which message mentions a price increase, and what exactly does it say?
The step-by-step version with config and troubleshooting is in the documentation: How to search email archives and attachments with an AI agent, locally.
Why is email hard for an agent?
Because an archive is a container of containers. A PST holds folders, folders hold messages, messages hold attachments, and attachments are Word files, PDFs and spreadsheets in their own right. An agent with file tools sees one large binary file. Exporting the archive to loose files first works, but it is slow, it duplicates sensitive data onto disk, and it has to be redone when the archive changes. And a model cannot read a PST at all.
The search engine handles the nesting itself. Each message and each attachment becomes a searchable item, and a result records both where the container is and where inside it the match was found.
What does a match inside an attachment look like?
Here is what the server returned in our test with three EML messages. The phrase “price increase” appears only inside the Word quotation attached to one of them; the message body just says “please find the updated quotation attached”.
-> add_to_index {"documentsPath":"mail","indexName":"mail"}
<- Indexed 'mail' into index 'mail': 3 document(s) added, 3 in the index.
-> search {"query":"\"price increase\"","indexName":"mail"}
<- { "documentsFound": 1, "documents": [
{ "filePath": "mail/2026-09-18-re-q3-pricing.eml",
"innerPath": "quotation-Q-2026-118.docx",
"occurrences": 1 } ] }
-> get_text_fragments {"query":"\"price increase\"","indexName":"mail"}
<- === mail/2026-09-18-re-q3-pricing.eml → quotation-Q-2026-118.docx
(1 occurrence(s)) ===
…Due to raw material costs we announce a price increase
of 6 percent from 2026-11-01.…
filePath is the message; innerPath is the attachment. The agent can answer “the Re: Q3 pricing message from Contoso, in the attached quotation Q-2026-118: a 6 percent increase from 1 November”, and every part of that sentence is traceable.
mail/2026-09-18-re-q3-pricing.eml <- filePath
|- body: "please find the updated quotation attached"
'- attachment: quotation-Q-2026-118.docx <- innerPath
"...we announce a price increase of 6 percent..."
Questions that work on mail
The usual query language applies, and a few patterns are especially useful for correspondence. All of these were checked against the same test mailbox:
- “Which message from Fabrikam mentions a delivery delay?”:
fabrikam AND delay. Sender addresses are indexed with the message, socontosoalso found an invoice whose body never names the company. - “Find every email that mentions order 77812”:
77812. Whole numbers are words. - “Which invoices fall due in October?”:
invoice AND content: daterange(2026-10-01 ~~ 2026-10-31). That matches dates written in the message text, here “due on 2026-10-22”. Thecontent:prefix matters: without it, a date range also matches the dates the engine records for each file.
Why local matters more for mail than for anything else
Email is where the sensitive material is: personal data, negotiations, HR threads, legal advice. Search tools that need the mailbox uploaded or synced to a service are a non-starter for many teams. Here the archive is mounted read-only into a container on the machine, indexed there, and searched there. The only text that leaves is what the agent quotes into its answer, and with a locally hosted model, not even that.
For a tighter setup, mount the archive read-only and give the index its own volume:
docker run --rm -i \
-v /srv/mail:/data:ro \
-v /srv/mail-index:/index -e GROUPDOCS_MCP_INDEX_PATH=/index \
ghcr.io/groupdocs-search/search-net-mcp:latest
Scoping a large archive
An archive of tens of thousands of messages indexes fine with a license, but it pays to be deliberate. Index by folder or by year as separate paths (mail/2025, mail/2026), so a year can be removed or rebuilt on its own, since the engine removes whole indexed paths rather than single files. Keep mail in its own index, separate from contracts or reports, so a question about correspondence does not wade through everything else. And when the archive grows, update_index picks up new messages without re-reading the old ones.
Honest limits
- In evaluation mode an index holds at most 100 documents and a search returns at most 10, and every message and attachment counts, so a real archive needs a license. Call
get_license_statusfirst. - A large PST takes time to index: every message and attachment is opened. Index once, then
update_index. - Scanned attachments without a text layer are indexed by their file properties only; there is no OCR.
- Docker only; on Linux add
--user "$(id -u):$(id -g)"unless you use the read-only setup above.
FAQ
Can I search a PST file with AI without Outlook? Yes. The engine reads PST, OST, MSG and EML directly; Outlook is not involved, and nothing is exported.
Does it search inside email attachments?
Yes. Attachments are indexed as items of their message, and a match inside one comes back with innerPath naming the attachment.
Is my mailbox uploaded anywhere? No. It is read inside a local container; only the passages the agent quotes reach your model provider.
Go deeper
- Documentation, canonical how-to: How to search email archives and attachments with an AI agent, locally
- Documentation hub: GroupDocs.Search MCP Server
- Start here: Do you need a vector database to ask questions about a folder of documents?
- Related: Why an AI agent should not read 300 contracts to answer one question
- Related: Grounded answers from your files: quote the passage, not the model’s memory
- Related: grep can’t read PDF: give your coding agent a document index
- Related: Project memory for AI agents: one index per project, kept current
- On-premise and security model: 3 architectures for AI document processing, and the one that keeps files inside your network
- Questions: GroupDocs Search forum
- Source: GroupDocs.Search.Mcp on GitHub