Skip to main content
Glama
gbrlpzz

zig-docs-mcp

by gbrlpzz

zig-docs-mcp

Local, open-source MCP server + agent skills that serve always-fresh official Zig documentation for the latest release, a curated high-performance lightweight-software guidance corpus, and a safe, dry-run-first auto-update for an out-of-date local Zig toolchain.

zig-docs-mcp
├── zigdocs                 MCP server (stdio, local, no accounts)
├── guidance/               curated performance guidance (12 topics)
├── skills/zig-docs         agent skill: operating rules for Zig work
└── skills/zig-docs-mcp     agent skill: Python integration (`zdoc` singleton)

Zig changes fast, and answers from training memory go stale between minor releases — 0.16 replaced the entire I/O layer and moved Dir from std.fs to std.Io. This server fetches official docs and released std sources per call (with short-TTL revalidation), so every answer cites the version it came from. When your local compiler falls behind the docs, the server says so and offers a gated upgrade. It never mutates your system without explicit confirmation.


Table of contents

  1. Why

  2. How it stays fresh

  3. Requirements

  4. Install the server

  5. Connect an MCP client

  6. Prime Agent integration

  7. MCP tool reference

  8. Toolchain auto-update

  9. Guidance corpus

  10. Configuration

  11. Development

  12. Troubleshooting

  13. License


Why

  • Docs rot fast. Zig's std library layout moves between minor releases. Serving the latest release's real sources is the only honest source of API truth. zig_std resolves symbols by walking actual re-exports in the released tree — not a scraped snapshot.

  • Performance advice should be mechanical. The bundled corpus explains allocation strategy, data layout, comptime, binary size, startup latency, SIMD, concurrency, and benchmarking — grounded in how hardware and the runtime actually behave (cache lines, syscalls, page faults), not vibes.

  • A behind compiler quietly invalidates everything. zig_version_status compares your toolchain against the upstream index on every check, and zig_update offers a concrete, reviewable upgrade plan.

  • Everything is local-first. The server runs on your machine over stdio. No accounts, no tokens, no telemetry. Network goes only to ziglang.org for docs, release notes, and source tarballs.

How it stays fresh

  • Cached responses revalidate against ziglang.org when older than 6 hours (force=true revalidates immediately). Revalidation uses conditional GETs (ETag / Last-Modified), so it is cheap.

  • Offline-safe: if the network is down, cached content is served with a stale flag instead of failing. (The very first run needs network once.)

  • Std sources come from the official per-release src tarball — the canonical content even when GitHub release tags lag (0.16.0 was not tagged on GitHub when this was built). The tarball is downloaded once per version and only lib/std/** is extracted.

  • The channel parameter selects stable (latest release, the default) or master (nightly), so you can preview next-release changes.

Cache layout (~/.cache/zig-docs-mcp/, override with ZIG_DOCS_MCP_CACHE):

~/.cache/zig-docs-mcp/
├── http/                    upstream bodies + ETag/Last-Modified metadata
├── langref-0.16.0.json      parsed reference sections (per version)
├── notes-0.16.0.json        release-notes digest
├── zig-0.16.0-src.tar.xz    source tarball cache
└── src/0.16.0/lib/std/      extracted std sources (550 files)

Requirements

  • Python ≥ 3.10 and uv

  • macOS or Linux (auto-update supports Homebrew and standalone installs; Windows gets a working plan printout but no tarball strategy yet)

  • Network access to ziglang.org for first fetches and revalidation

Install the server

git clone https://github.com/gbrlpzz/zig-docs-mcp
cd zig-docs-mcp
uv tool install .          # installs the `zigdocs` command on your PATH
zigdocs --help             # verify

Prefer not to install? Run it straight from the clone:

uv run --project ~/zig-docs-mcp zigdocs

Connect an MCP client

Any MCP client that speaks stdio. Point it at the zigdocs command:

{
  "mcpServers": {
    "zig-docs": {
      "command": "zigdocs"
    }
  }
}

Without a global install, use the clone directly:

{
  "mcpServers": {
    "zig-docs": {
      "command": "uv",
      "args": ["run", "--project", "/path/to/zig-docs-mcp", "zigdocs"]
    }
  }
}

Prime Agent integration

Two skills ship in this repo. Symlink them and restart the session (or run /reload):

ln -sfn ~/zig-docs-mcp/skills/zig-docs     ~/.agents/skills/zig-docs
ln -sfn ~/zig-docs-mcp/skills/zig-docs-mcp ~/.agents/skills/zig-docs-mcp

Then, from the agent kernel:

from zig_docs_mcp import zdoc

await zdoc.zig_version_status()                       # local vs latest upstream
await zdoc.zig_update()                               # dry-run upgrade plan
await zdoc.zig_update(dry_run=False, confirm=True)    # apply after user agrees
await zdoc.zig_langref(section="Errors")              # fresh language reference
await zdoc.zig_std(symbol="std.heap.ArenaAllocator")  # std docs from released source
await zdoc.zig_changelog()                            # what changed in the release
await zdoc.perf_guidance(topic="allocation-strategy") # curated guidance
await zdoc.zig_search(query="vectorization")          # search everything at once

Calls return their result as a JSON string (full-topic guidance reads return raw markdown); parse with json.loads(...) when you need fields like version or docs. Arguments are keyword-only. The server command is resolved in order: ZIG_DOCS_MCP_CMD, a zigdocs on PATH, then uv run --project against ZIG_DOCS_MCP_REPO (default ~/zig-docs-mcp).

skills/zig-docs/SKILL.md contains the operating rules the agent follows: version-gate first, docs before code, cite the doc version, and never apply an update without the user's explicit go-ahead.

MCP tool reference

zig_version_status

Compares the local zig version with the latest upstream release.

{
 "local_version": "0.16.0",
 "local_path": "/opt/homebrew/bin/zig",
 "latest_stable": "0.16.0",
 "master": "0.17.0-dev.1818+7051f8e73",
 "up_to_date": true
}

When the local toolchain is older, the response adds behind and a suggestion pointing at zig_update (illustrative example):

{
 "local_version": "0.15.2",
 "latest_stable": "0.16.0",
 "up_to_date": false,
 "behind": "local 0.15.2 < latest 0.16.0",
 "suggestion": "Call the zig_update tool (dry-run first) to upgrade the local toolchain to the latest stable release."
}

zig_update

Upgrades the local toolchain. Dry-run is the default — it prints the exact plan and changes nothing. Applying requires dry_run=false, confirm=true. See Toolchain auto-update.

zig_langref

Official Language Reference, fetched fresh for the channel version.

  • section="Errors" → full section text (code blocks preserved):

### Error Set Type
An error set is like an enum. However, each error name across the entire
compilation gets assigned an unsigned integer greater than 0. ...
  • query="vector" → ranked section hits:

[{"section_id": "Vectors", "title": "Vectors§"},
 {"section_id": "Builtin-Functions", "title": "Builtin Functions§"}]
  • no arguments → the list of all section ids.

zig_std

Standard-library docs from the exact released source. Symbol resolution walks real re-exports (std.zigheap.zigheap/ArenaAllocator.zig), follows @import aliases, and returns the /// docs plus the declaration text from that release:

{
 "symbol": "std.ArrayList",
 "version_source": "0.16.0",
 "file": "lib/std/std.zig",
 "line": 49,
 "declaration": "pub fn ArrayList(comptime T: type) type {\n    return array_list.Aligned(T, null);\n}",
 "docs": "A contiguous, growable list of items in memory. This is a wrapper around a\nslice of `T` values. ..."
}

If a name is not a plain top-level declaration in the walked namespace (layouts move between releases), the tool falls back to a corpus-wide search of top-level declarations, best match first — e.g. std.fs.Dir on 0.16 correctly surfaces lib/std/Io/Dir.zig. query="arena" searches std doc comments directly.

zig_changelog

Release-notes digest for the current channel version: section titles plus a short summary each. Useful right after a release lands (zig_changelog(force=true)).

perf_guidance

Curated guidance for high-performance lightweight software. No arguments lists topics; topic="allocation-strategy" returns the full guide (raw markdown with Principle / Mechanics / Zig idiom / Anti-patterns / Rules of thumb); query=... searches across all guides.

Unified search across langref, std doc comments, and guidance:

{"query": "vectorization", "langref": [...], "guidance": [...], "std": [...], "std_version": "0.16.0"}

scope narrows it: all (default) | langref | std | guidance.

Toolchain auto-update

zig_update picks a strategy automatically:

  1. Homebrew-managed zig (binary resolves inside the brew prefix) → brew upgrade zig:

{
 "mode": "dry-run (nothing changed). Re-run with confirm=true to apply.",
 "target_version": "0.16.0",
 "current": "0.16.0",
 "strategy": "homebrew",
 "command": ["brew", "upgrade", "zig"],
 "note": "Homebrew formula may lag the newest release slightly."
}
  1. Standalone install (official tarball, any other location) → downloads the platform tarball from the upstream index, extracts to ~/.local/opt/zig-<version>, and shims ~/.local/bin/zig:

{
 "strategy": "standalone-tarball",
 "download": "https://ziglang.org/download/0.16.0/zig-aarch64-macos-0.16.0.tar.xz",
 "install_dir": "~/.local/opt/zig-0.16.0",
 "steps": ["download ...", "extract ...", "symlink ~/.local/bin/zig -> .../zig/zig"],
 "activation": "~/.local/bin is first on PATH; new zig takes effect immediately"
}

If ~/.local/bin is not first on PATH, the plan says so explicitly — the old compiler would still win, and the tool tells you how to fix the order.

Safety rules:

  • Default is a dry-run. Nothing is downloaded, moved, or linked.

  • Applying requires dry_run=false, confirm=true together.

  • Agents using this server are instructed to show the plan and get the user's explicit go-ahead before confirming.

Guidance corpus

Twelve topics in guidance/, shipped inside the wheel and served by perf_guidance. Principles are universal; snippets are Zig 0.16-era; exact API truth always comes from zig_std, never from the corpus.

Topic

One-line summary

allocation-strategy

Match allocator to lifetime; arena bump-pointer cost vs general allocator bookkeeping; hidden allocations.

data-oriented-design

SoA vs AoS byte math on 64-byte cache lines; hot/cold splitting; MultiArrayList.

comptime-over-runtime

Comptime results become rodata/immediates; runtime tables cost dirty pages.

zero-copy-parsing

Slices are 16 bytes; allocate-per-token costs an allocation, a memcpy, and cache lines per token.

binary-size

Size = reachability; strip, panic modes, dep hygiene; smaller text = fewer startup page faults.

startup-latency

No init_array, lazy text page faults, lazy init, no work before argv.

memory-layout

Padding math, field ordering, packed structs, @sizeOf comptime asserts.

simd-and-vectorization

Auto-vectorization blockers, lane-wise accumulate + single reduce, @select vs branches.

concurrency-and-io

MESI cost of shared writes, futex parking, syscall batching, false-sharing padding.

error-handling-cost

Errors are u16 values; try is a predicted branch; no unwinding.

benchmarking-methodology

Release builds, warmup, min/median over mean, sink to defeat DCE, counters.

dependency-lightweightness

Std-first; deps add linked code and build fragility; vendor tiny utilities.

Configuration

Variable

Meaning

Default

ZIG_DOCS_MCP_CACHE

cache directory

~/.cache/zig-docs-mcp

ZIG_DOCS_MCP_CMD

full server command line (skill override)

ZIG_DOCS_MCP_REPO

repo dir for the uv run fallback

~/zig-docs-mcp

Development

make sync    # deps
make test    # unit tests (offline; std-source tests skip without warm cache)
make e2e     # spawns the real server over stdio, calls every tool
make fmt     # ruff format + check

The e2e suite needs network on first run (it warms the cache). Unit tests that exercise symbol resolution run against the warm std-source cache and are skipped cleanly when it is absent.

Troubleshooting

  • zigdocs server not found (Prime Agent skill): install with uv tool install . from the clone, or set ZIG_DOCS_MCP_REPO to the clone path, or set ZIG_DOCS_MCP_CMD to a full command line.

  • First run fails while offline: the cache starts empty; fetch once while online. After that, stale-cache fallback keeps every tool working.

  • Results look stale after a new release: pass force=true (the 6-hour TTL otherwise applies).

  • zig version still old after an update: a new shell is needed, and ~/.local/bin must precede the previous install directory on PATH. The dry-run plan states the exact situation for your machine.

  • Homebrew zig lags the newest release: brew formulas trail releases; use the standalone strategy (remove the brew formula, install standalone) if you need day-one versions.

License

MIT — see LICENSE.

-
license - not tested
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • DevDocs.io keyless docs index + entry search + content (Angular, MDN, Rust, etc.).

  • Provide your AI coding tools with token-efficient access to up-to-date technical documentation for…

  • Scrape, crawl, map & search the web. Open-source, self-hostable Rust crawler & search for AI agents.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/gbrlpzz/zig-docs-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server