get_profile
Get profile
Who Sigao Li is: identity, career narrative, contact links, and self-introduction.
lang
com.sigaoli由 sigaoli.com 发布官方发布者v1.0.0更新于 Oct 24, 2026
Read-only access to Sigao Li's profile, CV and case studies. Bilingual (EN/ZH).
只读的远程 MCP 服务器,提供 Sigao Li 的个人简介、简历与项目案例(中英双语)。
Web executable,通过 Streamable HTTP。 远程服务在工作区中配置后即可从网页运行时运行。
把这段提示词粘贴到 Claude Code、Codex、Cursor 等智能体,或 SourceWeft 对话中。智能体会读取该服务器的安装指南,先向你展示发布者、端点和登录方式,经你同意后再把它添加到你的客户端。密钥不会写进任何命令。
阅读 https://sourceweft.com/mcp/com.sigaoli%2Fprofile/install.md,并按其中说明把这个 MCP 服务器接入我的客户端。修改任何配置之前,先告诉我它的发布者、端点和登录方式,等我确认。不要把 API 密钥写进命令或我会提交的文件;问我密钥应从哪里获取。把它添加到你客户端的 mcpServers 配置中。
{
"mcpServers": {
"sigao-li-personal": {
"type": "http",
"url": "https://api.sigaoli.com/mcp"
}
}
}Personal website of Sigao Li — AI Product Manager · Spatial Data Scientist. From maps to models, and the products in between.
Bilingual (English at /, 中文 at /zh/), built with Astro + Tailwind CSS v4 + GSAP,
deployed to GitHub Pages via GitHub Actions. Launched 2026-06-11, replacing the previous
Jekyll (academicpages) site.
docs/)/llms.txt, /llms-full.txt, /resume.json (JSON Resume), /knowledge.json, /.well-known/mcp.json, JSON-LD, and a robots.txt that explicitly welcomes AI crawlers_inbox/ and commit. A pre-commit hook works out the country from the coordinates against Natural Earth polygons, archives the originals outside git, derives masters with a maximum edge of 4096px and the EXIF stripped, asks a vision model for the bilingual caption, and registers everything in photos.json — the map, the counts and the assistant's knowledge all follow from there/privacyAny Playwright suite that waits on Zoe's state must pin the clock (
Date.prototype.getHours = () => 14): between 23:00 and 06:00 she starts the session asleep, sostatenever reachesidleand the run just times out.
When adding a Zoe clip, decide who prewarms it and when at the same time. A clip that is only fetched at playback stalls on a slow connection, and the stage shows nothing until it decodes. Prewarming has been missed three times already. Note
warm()takes the file name (sit-to-loaf), not theZOEkey (sitToLoaf).
The chat panel is rebuilt on every navigation —
transition:persistkeeps Zoe's stage, not the panel. Anything that lives only in panel DOM is gone the moment a visitor clicks a link. The streaming reply, the guidance chip and the unsent draft each had to be given module state plus a path back throughpaint(); the chip was lost for weeks before anyone noticed. So when adding persistent UI here, answer two questions up front: how doespaint()rebuild it, and should it ride along insessionStoragewith the history? Measure geometry only once the panel is visible —scrollHeightis 0 while it is hidden, which silently writesheight: 0px.
Turnstile guards
/chatand/classify. It must never guard/mcp. That endpoint exists so machines can read Sigao's profile — it is in the official registry — and Turnstile exists to stop machines. It also costs nothing to serve: the tools read the knowledge pack and never call a model. The static outlets (llms.txt,knowledge.json,.well-known/mcp.json) are served by Pages and never reach the Worker at all.
Locally, Turnstile uses Cloudflare's always-pass test keys — sitekey in
site.tsbehindimport.meta.env.DEV, secret inworker/.dev.vars. The real key rejects headless browsers, which is exactly its job, so every suite that drives a real Worker would fail against it. The real secret exists only in production, set withwrangler secret put. A corollary worth remembering: the production happy path cannot be verified from a script — reaching it needs a human in a real browser. Automation can still prove the gate is up (a request with no credential must return 403).
One knowledge layer, three outlets: /llms-full.txt for passive crawlers, a chat assistant
(POST /chat, SSE) for humans, and an MCP server (/mcp, Streamable HTTP, no auth — tools:
get_profile / list_experience / get_case_study) for visiting agents, both served from
api.sigaoli.com (Cloudflare Worker, code in worker/). The knowledge pack
(/knowledge.json) is assembled at build time from the
same sources as the pages — persona markdown, cv.json, case studies, photo stats — so any
content edit propagates to all three outlets on the next deploy, no manual step. A privacy
guard fails the build if sensitive patterns (phone numbers, IDs, coordinates) ever leak into
the pack.
Alongside each reply the chat runs a lightweight intent classifier (POST /classify, a small
model) to suggest the single most relevant page, and can remember a returning visitor's name —
both kept entirely in the visitor's own browser (opt-in, clearable via "Forget me"), never on a
server. Visitors in the EU/EEA/UK have their chat and classification routed to an EU-hosted
provider, never the China-direct API. What the site stores and sends is described in plain
language at /privacy.
docs/bilingual-sync-design.md.src/data/cv.json or cv.zh.json — the hook keeps the other in step entry by
entry, so changing one role doesn't touch the rest. The timeline, /resume.json and
/llms-full.txt all render from it. Replace public/files/pdf/CV__Sigao_Li.pdf alongside.
(skills is deliberately left out of the sync: the two languages use different shapes there
and the renderer handles both.)src/lib/i18n.ts._inbox/ and commit. The pre-commit
hook files them by GPS, archives the originals to _originals/ (never committed), derives
serving masters with a maximum edge of 4096px, writes bilingual captions with a vision model, and registers them in
src/data/photos.json. Photos without GPS go in _inbox/<country-id>/ instead. Counts,
the map and the AI knowledge pack all follow from photos.json automatically.
See docs/photo-ingest-design.md.src/data/knowledge/*.md; the knowledge pack rebuilds on
every deploy and the assistant follows within ~10 minutes (Worker-side cache TTL).scripts/zoe-board2.mjs → zoe-qc2.mjs → zoe-prod2.mjs) keys, QCs, mirrors and
encodes them into public/zoe/. New actions = one clip + one row in the ZOE table in
ChatWidget.astro; specs and prompt cards in docs/zoe-production-handbook.md.Two chains run from a pre-commit hook: photo ingest, and bilingual sync. After cloning, point git at the tracked hooks directory once:
Without this neither runs — photos dropped into _inbox/ stay there, and the two
languages stop tracking each other. Both exit immediately when there is nothing to
do, so an ordinary commit is unaffected.
Both need .env (copy .env.example): the model calls for captions, translation
and the staleness check all go through that gateway.
Regenerating the lock file. package-lock.json has to be built on Linux. npm
records only the optional dependencies it can resolve on the machine it runs on,
so a lock made on Windows omits what sharp needs on a runner and npm ci refuses
to install. After changing dependencies here, run the Relock on Linux workflow
from the Actions tab; it rebuilds the lock, proves npm ci works, and commits the
result. Ordinary pushes never need it — and if you forget, the verify job says so.
Push to master → deploy.yml builds and deploys to Pages. Pushes to v2 build
without deploying (verification).
Two more workflows watch rather than gate, each emailing on failure and neither able to hold up a release:
The audit used to gate the build. It reads the day's advisory database rather than this repository, so an untouched commit could go from green to red overnight — which is exactly what stopped a photo batch from shipping on 13 September. Knowing is worth an email; being blocked is not.
The Worker deploys separately: cd worker && npx wrangler deploy (secrets via
wrangler secret put; custom domain api.sigaoli.com bound in the Cloudflare dashboard).
When a batch changes both, deploy the Worker first — the chat UI calls its endpoints, so a
site push ahead of the Worker leaves a brief window where those calls 404.
A deploy takes up to a minute to reach every edge location. Checking immediately reads the previous version, which has twice looked like a broken deploy when nothing was wrong — wait, then check.
Daily chat usage is at https://api.sigaoli.com/usage (last seven days, plus whether today has
hit the cap). The cap itself is DAILY_CAP in worker/src/core/quota.ts; when it trips it emails
once via Cloudflare Email Routing.
⚠️ Never click "Sync fork". This repository began as an academicpages fork; syncing would reset
masterto the upstream template. If that ever happens again:git push --force origin <good-commit>:master.
来源:README.md,提交 6268656
Get profile
Who Sigao Li is: identity, career narrative, contact links, and self-introduction.
langList experience
Full CV: current role, professional experience, research, education, volunteering, awards, skills, certifications.
langGet case study
Full text of one project case study by slug (challenge / approach / impact). Call with an unknown slug to get the list of valid slugs.
langslug必填已满足适用检查项的 90%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
请在仓库或注册中心条目中声明许可证。
src/├── pages/ # en routes + zh/ mirrors; llms.txt / resume.json / knowledge.json endpoints├── components/ # Nav, Hero, WorldMap, Lightbox, CommandK, ChatWidget …│ └── pages/ # shared page bodies rendered by both locales├── content/ # cases & research (en) + cases-zh & research-zh (generated, reviewed)├── data/ # cv.json / cv.zh.json / photos.json (GPS + bilingual alts)│ └── knowledge/ # persona sources for the AI assistant (about / faq / guidelines / boundaries)├── lib/ # i18n dict, GSAP lifecycle helper, site config│ └── knowledge/ # knowledge-pack pipeline (same-source layers + build-time privacy guard)└── assets/ # photo originals (optimized at build; originals never shipped)worker/ # Cloudflare Worker: /chat (SSE) + /classify (intent) + /mcp (MCP server)└── src/core/ # runtime-agnostic logic; Cloudflare specifics live only in src/adapter/public/zoe/ # Zoe's clip library (600p VP9 alpha, lazy-loaded; idle loads first)docs/ # zoe-production-handbook.md — clip production specs & prompt cardsgit config core.hooksPath .githooks