FOR AI AGENTS
Don't scrape HTML — read JSON.
All structured content on this site is compiled into static JSON at build time, served at /en/api/*.json (English) and /api/*.json (Chinese).
Any agent (Claude Code / Codex / Hermes / OpenClaw / your own) fetches it directly over HTTP GET — CORS wide open, no token.
There's also a zero-dependency CLI, npx zhanglu-net.
How it fits together
Content lives in the repo as markdown / JSON and is compiled to static files at build time. The endpoints are the single source of truth; the CLI is just a thin wrapper over them — so all four paths below return the same data. The only question is what you have on hand.
Source content
src/content/**.md · src/data/*.json
│
pnpm build (Astro)
Static JSON endpoints — source of truth
/api/*.json (Chinese) · /en/api/*.json (English)
Discovery: /en/llms.txt → /en/api/index.json
│
HTTP GET (CORS open · no token)
curl + jq
scripts / CI
fewest deps
CLI
npx zhanglu-net
nicest by hand
browser fetch
frontend / extension
no preflight
Claude Code
/zhanglu skill
plain language
↓ same data ↓
your agent
Which one to pick
curl + jq
curl -s https://zhanglu.net/en/api/skills.json | jq You are an agent, or writing a script / CI job. Recommended if you can make HTTP calls directly — no extra Node process in the way.
CLI (npx)
npx zhanglu-net --lang en list skills You are browsing by hand in a terminal, or want the filtering / search / body-only (--md) helpers for free. Needs Node 18+.
browser / any language fetch
fetch('https://zhanglu.net/en/api/skills.json') Building a web page, an extension, or a client in any language. CORS is wide open, no preflight, no proxy needed.
Claude Code skill
ask "what is Zhang Lu working on" You use Claude Code. Install the /zhanglu skill and trigger it in plain language; it calls the CLI for you.
When in doubt, use curl — the endpoints are always there; the CLI is only convenience.
Get started in 30 seconds
CURL
curl -s https://zhanglu.net/en/api/index.json | jq
curl -s https://zhanglu.net/en/api/skills.json \
| jq '.items[] | select(.featured) | .name'
curl -s https://zhanglu.net/en/api/skills/boss.json \
| jq -r .body_md CLI
npx zhanglu-net --lang en endpoints
npx zhanglu-net --lang en list skills --featured
npx zhanglu-net --lang en get skill boss --md
npx zhanglu-net --lang en search "brand judgment"
npx zhanglu-net --lang en about --json Endpoints
All endpoints are statically generated at build time, with Content-Type application/json and Access-Control-Allow-Origin: *.
Missing paths return a real 404, so status codes are reliable.
Bilingual: the paths below return English. Drop the
/en prefix for Chinese — e.g.
/api/projects.json.
Every response carries a lang field so you can confirm what you got.
Note the articles' external links still point to Chinese-language originals.
{ "lang": "en", "counts": { "skills": 42 }, "endpoints": { … } } { "count": 14, "items": [{ "slug", "title", "tech": [], "year", "loc", "persona", … }] } { …list fields, "body_md": "## What it is\n…" } { "count": 12, "items": [{ "title", "source", "url", "date", "summary" }] } { "count": 4, "items": [{ "slug", "title", "tagline", "url", "kind", "year" }] } { "count": 42, "items": [{ "slug", "name", "description", "source", "featured" }] } { …list fields, "body_md": "This skill comes from…" } { "count": 3, "items": [{ "slug", "title", "week", "date_range", "summary" }] } { …list fields, "body_md": "## Three products…" } { "name": "Zhang Lu", "tagline", "bio", "tags": [], "permalink" } { "links": [{ "label", "url", "handle", "icon" }] } { "items": [{ "type", "slug", "title", "text", "url" }] } CLI
A thin wrapper over the endpoints. Zero runtime dependencies, Node 18+, a single 542-line file. For the full npm / npx guide, see the npm / CLI page.
"Official" here means: this package is maintained by the author of this site, and its source
lives in the cli/ directory of this very repo — changed and shipped
alongside the endpoints. The version shown on this page is read from
cli/package.json at build time, same source as npm.
Verify it yourself (don't trust me, trust the registry)
npm view zhanglu-net repository.url # → github.com/zhanglunet/zhanglu.net
npm view zhanglu-net dependencies # → empty (zero deps)
npm view zhanglu-net version # → should match this page
⚠️ The package name is zhanglu-net (with -net).
The zhanglu package on npm is an empty placeholder someone else published in 2021 — unrelated to this site. Don't install that one.
Three ways to run it
| Mode | Command | Install? | When to use it |
|---|---|---|---|
| npx | npx zhanglu-net <cmd> | No | The default choice. Always pulls the latest version; simplest for occasional use. Costs a few seconds on first download. |
| global install | npm i -g zhanglu-net zhanglu-net <cmd> | Once | You'll use it often. No download latency; works offline once installed (data still needs the network). Upgrade with npm up -g. |
| from source | node cli/bin/zhanglu-net.mjs <cmd> | clone the repo | Air-gapped / no npm access, or you want to modify it. Zero deps — no install step after cloning. |
All three behave identically — same commands, same flags. The command table below applies to any of them.
Commands
list <kind> List skills / projects / articles / presentations / weekly get <kind> <slug> Read a single skill / project / article / presentation / weekly search <keyword> Search a keyword across all content about Author bio + tags social Public social links endpoints Print the manifest Common flags
--lang <zh|en> Which language's data to fetch (default zh) --json Output raw JSON (what agents usually want) --md On get, output body_md only --featured Only featured items --source <s> Filter by source (list skills/articles) --status <s> Filter by status (list projects) --type <t> Search one type: skill|project|article|presentation|weekly|about --since <date> Filter by date (list articles) --limit <N> At most N items --base <url> Override the site root (default https://zhanglu.net) Environment variables
ZHANGLU_BASE_URL Switch base; use http://localhost:4321 for local dev NO_COLOR=1 Turn off ANSI colors Claude Code integration
There's a /zhanglu skill, triggered by phrases like "look up Zhang Lu's skills", "X on zhanglu", "what projects is Zhang Lu working on". The skill calls npx zhanglu-net automatically.
Other agent integrations
CODEX / OPENAI FUNCTION CALLING
Register endpoints as tools. Each endpoint is one GET. Feed the returned JSON straight to the model.
HERMES / OPENCLAW
Any agent framework with HTTP tools can call these directly. Add /api/index.json to the system prompt and the agent finds its next step on its own.
MCP SERVER
Not shipped yet. If MCP users beyond Claude Code grow, I'll wrap an MCP server on a Cloudflare Worker, reusing the existing endpoints.
Browser-side (JS)
CORS wide open — fetch('https://zhanglu.net/api/skills.json') works directly, no preflight.
Access & permissions
No application, no token. Here is this site's explicit stance toward crawlers and agents — stated machine-readably in /robots.txt.
User-agent: * · Allow: /
Everything is allowed. No AI crawler is blocked — ClaudeBot, GPTBot, CCBot and friends are welcome.
Content-Signal: search=yes, ai-input=yes, ai-train=no
- search=yes — indexing, links and short excerpts are welcome.
- ai-input=yes — real-time reading, grounding / RAG and citing in generated answers are welcome. This is exactly what
/api/is for. - ai-train=no — training or fine-tuning models on this content is not granted.
Following the Content Signals Policy. In one line: read me, cite me, don't train on me.
When citing, please link back to the source page (every record carries a permalink).
There is no hard rate limit — the endpoints are static files — but please don't use them for load testing.