CLI reference

openzim-mcp is three commands sharing one binary: the server itself, plus two build-time helpers. --help only documents the server — the subcommands are dispatched before argparse sees them, so openzim-mcp --help will not list them. This page is the only complete listing.

Source of truth: openzim_mcp/main.py, openzim_mcp/cli/build.py, and openzim_mcp/ml/cli/download.py.

openzim-mcp — run the server#

openzim-mcp [--mode {simple,advanced}] [--transport {stdio,http,sse}]
            [--host HOST] [--port PORT] [--version]
            DIRECTORY [DIRECTORY ...]
ArgumentDefaultNotes
DIRECTORY(required, one or more)Directories containing .zim files. These become the allowed-directory set — the only paths the server will ever read
--modesimplesimple exposes only zim_query; advanced exposes all 8 tools. Env: OPENZIM_MCP_TOOL_MODE
--transportstdiostdio for local MCP clients, http for the streamable-HTTP service, sse deprecated and removed in 4.0.0. Env: OPENZIM_MCP_TRANSPORT
--host127.0.0.1HTTP/SSE bind address. Env: OPENZIM_MCP_HOST
--port8000HTTP/SSE bind port. Env: OPENZIM_MCP_PORT
--versionPrints openzim-mcp <version> and exits

A flag always wins over its environment variable; leaving the flag off falls back to the variable, then to the default. Every other setting is environment-only — see Configuration.

openzim-mcp --version
# openzim-mcp <version>

# Two archive directories, advanced surface, over HTTP
openzim-mcp --mode advanced --transport http --host 127.0.0.1 --port 8000 \
            /srv/zim /mnt/archives

zim_links(direction="inbound") — “what links here” — needs a pre-built sidecar. Nothing builds it for you: without it the tool returns an inbound_sidecar_unavailable envelope.

openzim-mcp build link-graph ARCHIVE [--output PATH] [--force] [--quiet]
ArgumentDefaultNotes
ARCHIVE(required)Path to the .zim file
--output<archive>.zim.linkgraph.sqliteWrite the sidecar somewhere else. The server looks beside the archive, so a relocated sidecar needs the same path at read time
--forceoffOverwrite an existing sidecar. Required when rebuilding, because the old file is still there
--quietoffSuppress the …walked N/M entries progress lines, which go to stderr

The build walks every entry in the archive once. Peak memory scales with article count: the builder interns every node path in an in-memory id map and materialises the full node list for insertion, which the code notes reaches GB scale on a full Wikipedia build. That matters on a memory-limited container. The write is atomic: it builds to a temporary file and moves it into place, so an interrupted run cannot leave a half-written sidecar for the server to load.

Exit codes (scriptable):

CodeMeaning
0Built. The success line names the sidecar path, node count, edge count and bytes written
1Expected, actionable failure: archive missing, not a file, not a valid ZIM, sidecar already exists (pass --force), or the sidecar path is unwritable
2Anything else, plus argparse usage errors
openzim-mcp build link-graph /srv/zim/wikipedia_en.zim
# built /srv/zim/wikipedia_en.zim.linkgraph.sqlite: <nodes> nodes, <edges> edges, <n> bytes

# Rebuild every sidecar after upgrading across a schema bump
for z in /srv/zim/*.zim; do
  openzim-mcp build link-graph --force --quiet "$z" || echo "FAILED: $z"
done

v3.0.0 invalidated every sidecar built by 2.x. Edge targets are now stored under the path the archive can actually serve rather than the raw percent-encoded href, so the schema version was bumped and older files are rejected on load. Rebuild with --force.

openzim-mcp download-models — pre-stage the reranker#

Only relevant with the optional [reranker] extra. It fetches the cross-encoder once, so the server never pays a first-call download — which it otherwise refuses to do at all, since allow_model_download defaults to false.

openzim-mcp download-models [--reranker-model-id ID]
ArgumentDefaultNotes
--reranker-model-idBAAI/bge-reranker-baseStage a different model. Must match OPENZIM_MCP_ML__RERANKER__MODEL_ID at serve time, or the server will not find what you staged

Exit codes are 0 on success and when no ML extra is installed (it prints a note and does nothing — so it is safe in an unconditional provisioning script), 1 when staging fails.

See Search reranking for the full picture.

What has no CLI#

There is no command to clear the cache, warm it, validate a config file, or list archives. zim_health reports cache statistics, the effective configuration and the loaded archives, but nothing on any surface clears or warms the cache — restart the server for that. Configuration is environment-only; there is no config-file flag.

These commands ship inside the server binary, so openzim-mcp --version names the release this page describes. Older binaries keep working, but only the current major line is supported — see SECURITY.md for the policy.

Documentation for v3.2.4 · Edit this page on GitHub ↗