Serve to agents (MCP)¶
ingestlib mcp exposes your corpus to any MCP
client — Claude Desktop, Claude Code, Cursor — as tools. An agent can then
run the whole loop against your self-hosted stack: ingest documents, search
with citations, extract fields, keep a folder in sync — nothing leaving your
machine.
It's an interface over the same functions the CLI and library use — install the extra and point a client at it.
The tools¶
| Tool | Does | Modifies corpus |
|---|---|---|
search |
hybrid retrieval + rerank → cited chunks; with sources, also queries your SQL databases |
— |
extract |
fill a JSON-Schema you provide, with provenance | — |
classify |
document type + confidence | — |
list_documents |
what's stored (id, path, namespace, pages, category) | — |
get_document |
one document's full record + persisted extractions | — |
collections |
the classify collections and their document counts | — |
describe_schema |
LLM-generated table hints for a SQL source | — |
verify |
audit durability (registry vs the vector & blob stores) | — |
registry_status |
registry revision + document count | — |
doctor |
health-check the configured stack | — |
ingest |
add a document | ✎ |
sync |
reconcile a folder (new/replace/move/prune) | ✎ |
remove |
erase a document from all three stores | ✎ |
reindex |
rebuild the vector store from the registry | ✎ |
recollect |
re-sort the corpus after a classify-rules change | ✎ |
registry_init · registry_backup · registry_restore |
manage the registry DB | ✎ |
Read tools are always available; the ✎ (write) tools are hidden when you run
--read-only. Your MCP client also asks for approval before each call.
Local clients — stdio¶
stdio is the default and needs no token. Point your client's MCP config at the command:
{
"mcpServers": {
"ingestlib": {
"command": "ingestlib",
"args": ["mcp"],
"env": { "INGESTLIB_CONFIG": "/path/to/your/config.yaml" }
}
}
}
(That's the Claude Desktop / Cursor shape — a command the client launches and
talks to over stdio.) Now ask the agent things like "what does my corpus say
about X?" (→ search) or "pull the totals from invoice.pdf" (→ extract).
Remote — streamable HTTP (with auth)¶
For an agent on another machine, run the HTTP transport. Because it's reachable over the network and can modify your corpus, it's guarded:
- It requires a bearer token — set
MCP_TOKENin.env(any strong random string); the server refuses to start HTTP without one. - It binds
127.0.0.1by default — pass--host 0.0.0.0to expose it, and only behind a reverse proxy with TLS.
Clients send Authorization: Bearer <MCP_TOKEN>. Add --read-only to expose
only the read tools on a shared endpoint.
The HTTP server also answers GET /health with 200 ok and no token — a
liveness probe for containers and load balancers (the Docker
deployment uses it).
Extract over MCP¶
extract's schema is defined by the agent as a JSON Schema — no Python
class needed. The server turns it into a validated model and runs the real
extraction:
{
"type": "object",
"properties": {
"invoice_number": { "type": "string" },
"total": { "type": "number", "description": "grand total in dollars" }
},
"required": ["invoice_number"]
}
Each returned field reports its pages, whether it was grounded in the source,
and an honest confidence — same guarantees as extract().
Query databases over MCP¶
search takes the same sources argument as retrieve(), so an agent can
query the SQL databases you declared in sources.yaml — read-only, with each
result carrying the exact SQL in its provenance. Because
structured retrieval is read-only, search stays a
read tool, available even under --read-only.
Configuration¶
Everything is optional (defaults shown):
# config.yaml
mcp:
read_only: false # true → only the read tools
host: 127.0.0.1 # streamable-http bind address
port: 8000
The server uses your existing stack (vector store, providers, artifacts), so
ingestlib doctor verifies it just like the rest of the pipeline.
Next: Reference → CLI for every ingestlib mcp flag.