zig-docs-mcp
Provides tools for retrieving official Zig documentation and standard library references from the latest release, checking local Zig toolchain versions against upstream, generating dry-run upgrade plans, and performing toolchain updates—all with caching and offline support.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@zig-docs-mcpHow do I list files in a directory with std.Io in Zig 0.16?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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
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_stdresolves 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_statuscompares your toolchain against the upstream index on every check, andzig_updateoffers 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=truerevalidates 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
staleflag instead of failing. (The very first run needs network once.)Std sources come from the official per-release
srctarball — 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 onlylib/std/**is extracted.The
channelparameter selectsstable(latest release, the default) ormaster(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 # verifyPrefer not to install? Run it straight from the clone:
uv run --project ~/zig-docs-mcp zigdocsConnect 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-mcpThen, 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 onceCalls 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.zig → heap.zig → heap/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.
zig_search
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:
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."
}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=truetogether.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 |
| Match allocator to lifetime; arena bump-pointer cost vs general allocator bookkeeping; hidden allocations. |
| SoA vs AoS byte math on 64-byte cache lines; hot/cold splitting; |
| Comptime results become rodata/immediates; runtime tables cost dirty pages. |
| Slices are 16 bytes; allocate-per-token costs an allocation, a memcpy, and cache lines per token. |
| Size = reachability; strip, panic modes, dep hygiene; smaller text = fewer startup page faults. |
| No init_array, lazy text page faults, lazy init, no work before argv. |
| Padding math, field ordering, packed structs, |
| Auto-vectorization blockers, lane-wise accumulate + single reduce, |
| MESI cost of shared writes, futex parking, syscall batching, false-sharing padding. |
| Errors are u16 values; |
| Release builds, warmup, min/median over mean, sink to defeat DCE, counters. |
| Std-first; deps add linked code and build fragility; vendor tiny utilities. |
Configuration
Variable | Meaning | Default |
| cache directory |
|
| full server command line (skill override) | — |
| repo dir for the |
|
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 + checkThe 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 withuv tool install .from the clone, or setZIG_DOCS_MCP_REPOto the clone path, or setZIG_DOCS_MCP_CMDto 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 versionstill old after an update: a new shell is needed, and~/.local/binmust 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.
This server cannot be installed
Maintenance
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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