Three supported ways to install apple-docs. Pick the one that matches your intent. Every path ends with a verification block — run it before declaring the install done.
| Path | When to use | Output |
|---|---|---|
| Dev install | Hacking on the source, running tests, contributing | Linked apple-docs and apple-docs-mcp binaries on ~/.bun/bin |
| Standalone binary | CLI / personal MCP server with no Bun runtime on the host | One executable file |
| Production self-host | Publicly reachable MCP HTTP server behind Caddy and cloudflared | launchd-managed Bun servers + Caddy + cloudflared |
All three require Bun only for build or install. The standalone
binary and the production launchd plists run Bun internally; operators
do not need it on their interactive PATH afterwards.
Note
Linux feature parity. SF Symbol pre-rendering needs the macOS
SF Symbols system bundle, so apple-docs sync on Linux produces an
empty resources/symbols/ directory. Linux installs should use the
snapshot path (apple-docs setup) — every published snapshot ships
the full pre-rendered SVG matrix and works offline. For the two
render endpoints that use host tools (PNG symbols via rsvg-convert,
real font-text glyphs via HarfBuzz's hb-view), see
Self-hosting → Linux host packages.
- macOS 13+ on Apple Silicon or Intel, or Linux x64 / arm64 with Bun 1.1+.
git,curl,unzip.- For the production path:
caddy(brew install caddyon macOS, package manager on Linux),cloudflared, and a Cloudflare account with a Tunnel configured.
Install Bun if it is not on PATH:
curl -fsSL https://bun.sh/install | bash
# Or via Homebrew: brew install oven-sh/bun/bunConfirm: bun --version reports 1.0 or later.
For working on the source. A single one-shot script installs every
runtime and test prerequisite, then links the CLI binaries onto
~/.bun/bin.
git clone https://github.com/g-cqd/apple-docs.git
cd apple-docs
bun run dev:setupbun run dev:setup is idempotent. It runs:
| Step | What it installs | How |
|---|---|---|
bun install |
npm dependencies | Bun's package manager |
bun link |
apple-docs and apple-docs-mcp on ~/.bun/bin |
Bun's link symlinks |
| 7zip CLI | Unblocks the archive tests | brew install sevenzip on macOS; manual apt, dnf, or pacman on Linux |
Python fontTools + brotli |
Unblocks the font-subset tests (brotli is fontTools' WOFF2 codec) | pip3 install --user fontTools brotli |
| Playwright Chromium | Unblocks the browser worker test | bunx playwright install chromium |
bun link installs two binaries at ~/.bun/bin:
apple-docs— full CLI (search / read / browse / sync / mcp / web).apple-docs-mcp— back-compatible alias forapple-docs mcp start.
Make sure ~/.bun/bin is on your interactive PATH. Bun's installer
appends it to ~/.bashrc or ~/.zshrc; reload your shell or source
the file.
Populate the corpus:
# Fast path: install the latest snapshot.
apple-docs setup
# OR full crawl from scratch.
apple-docs sync --use-git-authRun the test suite:
bun run ci # lint + typecheck + tests
bun run audit # adds knip + jscpd + file-size + coverageLive documentation preview:
bun run docs:dev # serves docs/ for local editing
bun run docs:build # static site at docs/.vitepress/dist/
bun run docs:preview # serves the built site for verificationA single-file Bun-compiled executable. Use this for personal CLI or MCP use when a full Bun toolchain on the host is undesirable.
Build it from a dev checkout, or download one from a GitHub release — every snapshot release ships them:
# From a dev checkout:
bun run build:cli # current host: dist/apple-docs
bun run build:cli:all # cross-compile: darwin-arm64 + linux-x64 + linux-arm64Move the binary onto your PATH:
install dist/apple-docs /usr/local/bin/apple-docs
apple-docs setupThe binary embeds everything except the corpus. APPLE_DOCS_HOME
points it at a data directory (default ~/.apple-docs).
Semantic search works here too: the embedder is pure JavaScript over the
model files setup fetches into the corpus, so it needs no native
addon — the compiled binary gets the same search cascade as a Bun install.
Verify:
apple-docs --help
apple-docs search NavigationStack --json
apple-docs status --jsonRuns the reference deployment topology: Bun web and MCP servers under launchd, Caddy as the loopback reverse proxy, cloudflared as the public tunnel.
The full deployment reference is Self-hosting; this section is the install-time checklist.
git clone https://github.com/g-cqd/apple-docs.git
cd apple-docs
bun installDo not run bun link for a production install. Production uses the
ops/bin/*.sh shims, which locate Bun via $BUN_BIN, ~/.bun/bin,
and Homebrew prefixes. Linking is unnecessary and adds a version-drift
maintenance path between a user-installed ~/.bun/bin/apple-docs and
the launchd-managed Bun process.
cp ops/.env.example ops/.env
$EDITOR ops/.envSet at minimum (variable names match ops/.env.example exactly):
REPO_DIR— absolute path to this checkout.DATA_DIR— corpus location (apple-docs setupwrites here).WEB_PORTandMCP_PORT— Caddy's loopback listeners (default3030/3031).WEB_BACKEND_PORTandMCP_BACKEND_PORT— Bun's loopback listeners behind Caddy (default3130/3131).PUBLIC_WEB_HOST,PUBLIC_MCP_HOST— your public hostnames.CLOUDFLARE_API_TOKEN,CLOUDFLARE_ZONE_ID— optional, only for edge cache purges after a deploy.
See ops/.env.example for the full list with comments.
ops/bin/render-all.sh
ops/bin/install-daemons.sh # one-time: sudoers + launchd plistsinstall-daemons.sh is the only step that requires sudo. It writes a
sudoers drop-in so subsequent launchctl operations do not prompt.
ops/bin/apple-docs setup
# OR
ops/bin/apple-docs syncops/bin/apple-docs-ops service start allVerify with the block below.
Configure cloudflared per ops/cloudflared/README.md (one tunnel per
public host). Once the tunnel is up, public hosts resolve to Caddy on
the loopback ports, and Caddy forwards to the Bun upstreams.
# Local liveness (Caddy loopback ports).
curl -sf http://127.0.0.1:${WEB_PORT:-3030}/healthz
curl -sf http://127.0.0.1:${MCP_PORT:-3031}/readyz | jq
# Internal Bun upstream (bypasses Caddy — useful if Caddy is the suspect).
curl -sf http://127.0.0.1:${MCP_BACKEND_PORT:-3131}/readyz | jq
# Public reach (via cloudflared).
curl -sf https://${PUBLIC_MCP_HOST}/readyz | jq
# Smoke test the install end-to-end.
ops/bin/smoke-test.shUse the public instance you stood up, or the project's reference
instance at https://apple-docs-mcp.everest.mt/mcp:
# Claude Code, HTTP transport.
claude mcp add -s user --transport http apple-docs https://<public-host>/mcp
# Codex CLI (uses the mcp-remote stdio bridge).
codex mcp add apple-docs -- bunx mcp-remote https://<public-host>/mcp
# Print installer snippets for other clients.
apple-docs mcp install --http https://<public-host>/mcpDev install:
bun unlink # removes ~/.bun/bin/apple-docs symlinks
rm -rf ~/.apple-docs # removes the corpusStandalone:
rm /usr/local/bin/apple-docs
rm -rf ~/.apple-docsProduction:
ops/bin/apple-docs-ops service stop all
sudo launchctl unload /Library/LaunchDaemons/com.apple-docs.*.plist
sudo rm /Library/LaunchDaemons/com.apple-docs.*.plist
sudo rm /etc/sudoers.d/apple-docs
rm -rf "$DATA_DIR"