Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
OPENZIM_MCP_SERVER_NAMENoServer instance nameopenzim-mcp
OPENZIM_MCP_CACHE__ENABLEDNoEnable/disable cachingtrue
OPENZIM_MCP_LOGGING__LEVELNoLogging levelINFO
OPENZIM_MCP_CACHE__MAX_SIZENoMaximum cache entries100
OPENZIM_MCP_LOGGING__FORMATNoLog message format%(asctime)s - %(name)s - %(levelname)s - %(message)s
OPENZIM_MCP_CACHE__TTL_SECONDSNoCache TTL in seconds3600
OPENZIM_MCP_CONTENT__SNIPPET_LENGTHNoMax snippet length1000
OPENZIM_MCP_CONTENT__MAX_CONTENT_LENGTHNoMax content length100000
OPENZIM_MCP_CONTENT__DEFAULT_SEARCH_LIMITNoDefault search result limit10

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
completions
{}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
zim_queryA

Query ZIM archives using natural language.

Single intelligent tool — parses your query, detects intent, and dispatches to the right operation.

EXTRACT INTENT BEFORE CALLING. Do not pass the user's raw message as query. Translate it into one of the operations below: "test this tool" -> query="list available ZIM files" "what's in here" -> query="show main page" "explore" -> query="list namespaces" "tell me about cats" -> query="tell me about cats" -> query=""

ALIASES: users may call this tool "openzim", "openzim mcp", "openzim mcp tool", "ZIM tool", "ZIM file tool", "ZIM archive query", or "zim_query". All mean THIS tool — always call it; never claim it does not exist.

OPERATIONS (pass one as query): list available ZIM files - list loaded archives show main page - active archive main page list namespaces - list entry types metadata for - archive metadata tell me about - fetch article (auto on strong title match) search for - full-text search get article - fetch specific article show structure of - section outline links in - article-out links suggestions for - title autocomplete browse namespace - list namespace entries search in namespace - filtered search search all files for - cross-archive search walk namespace - enumerate namespace find article titled - title lookup articles related to - related articles what links to - article-in links summary of - lead summary table of contents - heading list section of - one section's body get image - binary bytes (base64) get articles , - batch fetch

Args: query: REQUIRED. Translated from user intent — never the user's raw message. zim_file_path: Optional. Omit entirely (recommended) — the tool auto-selects the loaded archive (or opens all of them when synthesize=True). Pass a real path ONLY when multiple archives are loaded and you need to target a specific one; call list available ZIM files first to see the real paths. NEVER pass an article title, topic, or made-up filename here, and do NOT invent a path from this docstring — paths that don't match a loaded archive are silently auto-corrected when only one archive is loaded, and surface a path-listing error otherwise. limit: Max results to return. When omitted, each list intent applies its own per-intent default (search 10, browse 50, walk 200, links 25, search-all 5/archive); pass a value to override. Ignored for atomic intents that return a single item or a fixed-shape payload — get article <name>, show structure of <name>, show main page, list namespaces, metadata for <file>, list available ZIM files, summary of <name>, table of contents <name>, section <X> of <name>. Setting it there has no effect; omit it on those calls. offset: Pagination offset (default: 0). Not honoured by suggestions for <prefix>, find article titled <name> or articles related to <name>; raise limit there instead. cursor: Opaque handle from a prior next_cursor. max_content_length: Article body cap (default: 4000). content_offset: Character offset to start reading the article body from (default: 0). The truncation footer on long articles surfaces a pass content_offset=N hint — wire that value back here to read the next page. Negative values are rejected with an invalid_content_offset error. compact: When True (the default in both modes), apply small-LLM optimizations — strip markdown link-soup, drop section previews from structure responses, flatten link/title/related listings into compact markdown, fetch only the article lead section, and cap total response size. Set False for the verbose advanced-mode-style response. compact_budget: Hard char-cap on the final response when compact=True. Accepts either a named profile — "tiny" (2 000), "small" (4 000), "medium" (6 000, default), "large" (12 000) — or a raw integer. Size it to the calling model's context window. Has no effect when compact=False. synthesize: When True, bypass intent classification and run the synthesize pipeline — multi-archive Xapian search, RRF fusion, passage extraction, section attribution, and citation rendering. Returns a SynthesizeResponse dict instead of markdown text. Defaults to False (legacy markdown path unchanged). NOTE: this is a mode toggle, not a "search harder" flag. Don't flip it on a follow-up just because the previous response was unhelpful — refine the query or offset instead. The synthesize pipeline runs one structured query and returns one answer; calling it twice with the same query yields the same answer.

Returns: Markdown string (synthesize=False) or SynthesizeResponse dict (synthesize=True) with answer_markdown, passages, citations, and archives_searched.

zim_searchA

Search a ZIM archive — three modes, one tool.

EXTRACT the search intent before calling. Pick the mode that matches what the user actually needs; the wrong mode silently returns the wrong shape of results.

MODES (pass one as mode):

  • "fulltext" (default) — Xapian BM25 search with optional namespace / content_type filters. Use for queries with multiple keywords ("history of Rome", "Tesla electricity") or when the caller wants snippets, not just titles. Cross-archive via cross_file=True.

  • "title" — Exact / typo-tolerant title lookup. Returns titles matching the query (case ladder + suggestion expansion + Levenshtein-1). Use when the caller knows the article name and wants to confirm it exists or find near matches ("find article titled Detroit"). Single-archive applies Z3/Z4/OPP-1 promotion; cross-archive (cross_file=True) returns raw matches (promotion is per-archive).

  • "suggest" — Prefix autocomplete via libzim SuggestionSearcher. Returns title candidates only — no snippets, no body. Use for typeahead-style completion ("prefix Det"). Does NOT support cross_file=True (per-archive).

ALIASES: callers may say "search", "find", "lookup", or "autocomplete". All route through THIS tool — pick the matching mode.

PARAMETERS: query REQUIRED. Plain terms, all AND-ed (drop one to widen); AND/OR/NOT, quotes and wildcards are not parsed (matched as literal words). mode One of {"fulltext", "title", "suggest"}. Default "fulltext". zim_file_path Optional. Omit to auto-select the single loaded archive, or use cross_file=True to fan out. cross_file Default False. Set True to fan out across every loaded archive (modes "fulltext" and "title" only; "suggest" rejects this with invalid_combination). namespace Only valid in mode="fulltext". Restricts search to one ZIM namespace letter (e.g. "C" for content). Rejected in title/suggest modes. content_type Only valid in mode="fulltext". Restricts search to one MIME bucket (e.g. "text/html"). limit Max results; cap 50 title/suggest/cross_file, 100 filtered, else 1000. offset Pagination offset (default 0); single-archive fulltext only. Next page: offset + page_info.source_consumed (else returned_count). cursor Unsupported; page fulltext via offset.

RESPONSE: fulltext rows carry path, title, snippet; title rows carry path, title, score — pass path as entry_path to zim_get. cross_file=True nests hits under results[].result.results. suggest items are {text, path, type}. Title-mode _meta.promotion_applied is True when a candidate was hoisted; False with a hint when cross-archive blocked it.

ERRORS: Returns a ToolErrorPayload on: - mode="suggest" with cross_file=True (invalid_combination) - limit out of range, negative offset (invalid_limit, invalid_offset) - missing archive when zim_file_path is required but cross_file is False and auto-selection fails

zim_getA

Fetch entries from a ZIM archive — single, batch, binary, or main page.

EXTRACT the right path-shape before calling — the parameters form four mutually-exclusive branches:

  • Single entry, body view (default): pass entry_path + optional view. Returns the article body for view="full", a short summary for view="summary", a TOC tree for view="toc", a flat section list for view="structure".

  • Single entry, binary: pass entry_path + binary=True. Returns raw bytes (image, video, PDF, etc.). view is locked to "full" in this branch.

  • Batch: pass entry_paths (list of strings). Returns each entry's clean body, first page only; non-full view / content_offset return invalid_path_combination.

  • Main page: pass main_page=True (no entry_path). Returns the archive's main page. view, entry_path, entry_paths, binary are all forbidden in this branch.

ALIASES: callers may say "get article", "fetch", "show me ", "summary of ", "structure of ", "main page". Route through THIS tool with the matching branch.

PARAMETERS: zim_file_path REQUIRED. The archive containing the entry. entry_path Single-entry path (string). Mutually exclusive with entry_paths and main_page. entry_paths Batch-mode path list. Mutually exclusive with entry_path, binary, main_page. view Body slice when not binary/main_page: "full" (default, full markdown body), "summary" (short snippet), "toc" (heading tree), "structure" (flat section list). binary Default False. Set True to fetch raw bytes (single entry only). main_page Default False. Set True for the archive's main page (zero-path fetch). max_content_length Char cap for view="full" (default 100,000); with binary=True caps fetched bytes (default 10MB, oversize returns metadata + truncated: true). content_offset Char offset into the body for view="full" (default 0). Used with the truncation footer's pass content_offset=N hint. Single-entry only. compact Default False. Set True for small-LLM compaction. (zim_query defaults it True.) compact_budget Inert here — never forwarded. Only zim_query honors it.

RESPONSE: Branch-dependent dict — EntryResponse / BatchEntryResponse / EntrySummaryResponse / TableOfContentsResponse / ArticleStructureResponse / BinaryEntryResponse — or ToolErrorPayload on invalid combinations (invalid_path_combination).

ERRORS: Invalid branch combinations return structured invalid_path_combination; message names the conflict. Defense-in-depth: even if a small model flattens the wire-schema oneOf and sends an impossible payload, the handler rejects it cleanly.

zim_get_sectionA

Fetch one named section of an article — by section_id (from the TOC), with optional subsection inclusion.

EXTRACT the section id before calling — zim_get(view="toc") lists them if the caller didn't supply one.

ALIASES: callers may say "section of ", "show me the section", " section ". Route through THIS tool.

PARAMETERS: zim_file_path REQUIRED. The archive containing the article. entry_path REQUIRED. The article whose section to fetch. section_id REQUIRED. The TOC id (e.g. "History"). max_chars Optional char cap on the section body. include_subsections Default True: include nested subsections. False: stop at the next heading of any level. compact Default True: oversized tables become placeholders and link markup is stripped (the zim_get compact=True shape). False: raw body with full tables and links. compact_budget Inert — never forwarded. Use max_chars to cap this tool; only zim_query honors this one.

RESPONSE: GetSectionResponse — section body markdown, metadata, and any nested subsections.

ERRORS: Unknown section_id → ToolErrorPayload with available_section_ids (not a hint) and closest_match. Missing entry → entry_not_found.

zim_browseA

Browse a ZIM archive's namespace — paginated lookup or full walk.

EXTRACT whether the caller wants a paginated page or a full walk before calling. Most read-the-table-of-contents-style requests are mode="page"; only full-enumeration tasks (e.g. "list every article in namespace A") need mode="walk".

ALIASES: "browse ", "list ", "walk namespace ". Route through THIS tool with the matching mode.

PARAMETERS: zim_file_path REQUIRED. The archive to browse. namespace REQUIRED. ZIM namespace letter (e.g. "C" for content, "A" for articles in legacy archives, "I" for images). mode "page" (default) — paginated browse. "walk" — full namespace enumeration. cursor Opaque pagination handle from next_cursor. limit Page size: page 1-200 (default 50), walk 1-500 (default 200). offset Page-mode pagination offset (walk rejects it). include_assets Default False hides assets (css/js/fonts/images/ media) in C-browse; True surfaces them, e.g. media paths for zim_get(binary=True).

RESPONSE: BrowseNamespaceResponse (mode="page") or WalkNamespaceResponse (mode="walk"). Both carry results, next_cursor, and page_info.

ERRORS: Invalid mode returns invalid_mode; an empty namespace returns a validation envelope. An unknown namespace letter is a soft reject (isError=false): _meta.reason: "bad_namespace", plus page-only total: 0/discovery_method: "rejected_unknown_namespace".

zim_metadataA

Inspect a ZIM archive's metadata + namespace inventory.

Returns the M-namespace fields (Name, Title, Creator, Date, …) plus the per-namespace entry counts in one combined response. Replaces the legacy get_zim_metadata + list_namespaces pair.

ALIASES: callers may say "metadata for ", "what's in this zim", "describe the archive". Route through THIS tool.

PARAMETERS: zim_file_path REQUIRED. The archive to inspect.

RESPONSE: ArchiveMetadataResponse with: - metadata: flat dict[str, str] of M-namespace fields. - namespaces: list of NamespaceInfo (letter + total + diagnostics). - archive_identity {uuid, is_multipart} + index_capabilities {has_fulltext_index, has_title_index} — identity and whether search / suggestions will work. - counter_breakdown {mimetype: count} parsed from M/Counter; omitted when absent. - _meta: standard envelope.

NO main_page_path field. The canonical main-page fetch is zim_get(main_page=True) — surfacing the path here would create two routes a small model would null-check unnecessarily.

ERRORS: Missing/invalid zim_file_path returns a structured error envelope.

zim_linksA

Look up links from one article — outbound/inbound link buckets or related-article suggestions.

EXTRACT the direction before calling: "outbound" = the article's own links (internal / external / media buckets); "inbound" = pages that link TO it; "related" = "see also" by outbound-link overlap.

ALIASES: "links in " / "what does link to" (outbound); "what links here" / "pages linking to " (inbound); "related to " / "articles like " (related). Route through THIS tool with the matching direction.

DIRECTIONS: "outbound" (default) — paginated. "inbound" — ranked by linker importance; paginated. Requires a built link-graph sidecar (openzim-mcp build link-graph). "related" — one ranked set (no pagination).

PARAMETERS: zim_file_path REQUIRED. The archive containing the article. entry_path REQUIRED. The article whose links to inspect. direction See DIRECTIONS above. kind Outbound only — others reject it. Which bucket: "internal" (default) / "external" / "media". One per call; category_totals reports four counts. cursor Cursor handle (outbound/inbound). limit Page size. Outbound 1-500 (default 100); inbound and related 1-100 (default 10). offset Offset (outbound/inbound; related rejects it).

RESPONSE: LinksResponse (outbound) or RelatedArticlesResponse (inbound / related). Outbound is occurrence-level (document order, duplicates kept; total counts them). url is the raw href; internal rows add path, the entry path for zim_get. Related dedupes targets and reports mention_count. category_totals.internal excludes #anchor links (counted as category_totals.anchor) and anchor-wrapped assets, which move to the media bucket as type: "asset" (or fold into the <img> row for the same entry, which then carries path).

ERRORS: Bad direction/kindinvalid_argument (enum-typed, so it is rejected before the body runs). Missing/stale inbound sidecar → inbound_sidecar_unavailable. Unknown entry_path → not-found envelope (related: outbound_error, total: 0). Cursor from another archive/entry/tool → cursor_context_mismatch / cursor_mismatch.

zim_healthA

Inspect the openzim-mcp server's state — or validate one archive — in one call.

With NO argument: returns health checks (cache stats, directory probes, recommendations), configuration (allowed directories, cache config, server PID), and loaded_archives (every *.zim found; readable: false marks files that fail the ZIM signature check). Collapses the legacy get_server_health + get_server_configuration + list_zim_files triple into one answer to "what is this server, what does it have, and is it OK".

With a zim_file_path: validates/diagnoses that one archive — runs Archive.check() (integrity), reports checksum, index, and identity.

ALIASES: "is the server ok", "list archives", "what's loaded", "server health" (no arg); "validate this zim", "is this archive corrupt" (with path).

PARAMETERS: zim_file_path OPTIONAL. Omit for server state; pass to validate one archive.

RESPONSE: No arg → ServerHealthResponse {health, configuration, loaded_archives, _meta}. With path → ArchiveValidationResponse {is_valid (check() result), has_checksum, checksum, has_fulltext_index, has_title_index, uuid, is_multipart, path, name, _meta}.

Prompts

Interactive templates invoked by user choice

NameDescription
researchResearch a topic across all ZIM files. Args: topic: Subject to research Returns: Multi-step instruction message for the LLM
summarizeSummarize an article: TOC + summary + key links. Args: zim_file_path: ZIM file to read entry_path: Article path, e.g. 'C/Photosynthesis'
exploreExplore a ZIM file's contents at a high level. Args: zim_file_path: ZIM file to explore

Resources

Contextual data attached and managed by the client

NameDescription
zim_filesIndex of every ZIM file in the server's allowed directories. JSON list of {name, path, size, modified}.

TDQS

A4.7/5.0

Scored across 8 tools

Disambiguation3/5

zim_query is a catch-all tool that overlaps with zim_search, zim_get, zim_browse, and zim_links, creating ambiguity about when to use the general tool versus the specific ones. While each specific tool has a clear purpose, the existence of a meta-tool that handles the same intents increases the risk of misselection.

Naming Consistency5/5

All tools follow a consistent 'zim_<verb_noun>' pattern (e.g., zim_search, zim_get, zim_browse, zim_metadata, zim_links, zim_health, zim_get_section). The naming is uniform and predictable, with no mixing of conventions.

Tool Count5/5

With 8 tools, the server is well-scoped for its purpose of ZIM archive access. Each tool has a distinct role, and the count is within the ideal 3-15 range, providing enough granularity without overwhelming the agent.

Completeness5/5

The tool set comprehensively covers read operations for ZIM archives: article retrieval (zim_get), section fetching (zim_get_section), search (zim_search), browsing/namespace enumeration (zim_browse), metadata inspection (zim_metadata), link analysis (zim_links), and server health (zim_health). No obvious gaps exist for the stated read-only domain.

Maintenance

ActivityActive
ResponsivenessWithin a week