Repository navigation
MCP 自报版本停在 2.27.1,公开计数的兜底停在六月:两个没有维护者的自报数字 #1820
Copy link
Copy link
Closed
Labels
Description
两处「没人维护的自报数字」,都是外部读到的我们
1. 每个 MCP 客户端握手时读到的版本号停在 2.27.1
$ curl -sS https://misakanet.org/mcp -H 'Content-Type: application/json' -H 'Accept: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18"}}'
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-06-18","capabilities":{"tools":{}},
"serverInfo":{"name":"misakanet","version":"2.27.1"}}}仓库 / server.json / PyPI / npm 全是 2.30.2,中间隔了 6 个 release。
根因是注释描述了一个不存在的机制,于是没人觉得这个数字需要维护:
workers/register-proxy-sw.js:447:version: env.MCP_VERSION || "2.27.1"—— 硬编码兜底;workers/register-proxy-sw.js:193的注释却写:「Version injected at build time from env.MCP_VERSION or falls back to package.json」;- 而
MCP_VERSION没有任何注入点:workers/wrangler.toml全文无[vars](只有 triggers / kv / d1),
.github/workflows/deploy-worker.yml:33是裸npx wrangler deploy --config wrangler.toml(无--var),
全仓grep -rn MCP_VERSION只命中workers/*.test.mjs里的测试假值; scripts/align_versions.py管的是 server.json / glama.json / well-known 卡片 / plugin.json,不管这个字符串。
2. /api/counter 的末级兜底读的是一份停在六月的文件
/api/counter 在 D1 与 KV 都失败时走到 workers/register-proxy-sw.js:4187
(return fetchFromGitHub(token, "data/counter.json")),而 :3002 的默认 ref = "data":
data 分支的 counter.json : {"current": 10047, "updated": "2026-06-01T02:25:00Z"}
线上 /api/counter : {"current": 10303, "updated": "2026-09-17"}
也就是说:恰好在我们最脆弱的时候(存储不可用),公开计数会静默回退到一个低 256、停在 3.5 个月前的数字。
比报错更糟——读的人无法察觉。
(顺带:/api/health 现在 status: ok 的同时 kv_writes: {attempts: 5, failures: 5, last_ok_at: ""},
见另一条 issue。)
建议的修法(任选其一,但要有「读回来比对」的门禁)
- 让版本号只有一个来源:deploy 时注入
[vars] MCP_VERSION(或直接从package.json读进来),
并加一条检查:线上initialize的版本 == 仓里 package.json 的版本(不一致即红)。 - 兜底要么删掉,要么改成"宁可 5xx 也不要旧数字"(
data分支的文件已经过期 3.5 个月,它不可能是真值)。 align_versions.py扩到"发出去的东西":registry 的isLatest、npm/PyPI 上的版本、线上/mcp自报版本——
现在isLatest还停在 2.29.0(仓内server.json已 2.30.2)。
这一类问题的模式记录在 docs/maintainer/architecture-cognition-defects-2026-09-18.md 模式 2 与模式 3。
This repo is using Opire - what does it mean? 👇
💵 Everyone can add rewards for this issue commenting
/reward 100 (replace 100 with the amount).🕵️♂️ If someone starts working on this issue to earn the rewards, they can comment
/try to let everyone know!🙌 And when they open the PR, they can comment
/claim #1820 either in the PR description or in a PR's comment.🪙 Also, everyone can tip any user commenting
/tip 20 @Ikalus1988 (replace 20 with the amount, and @Ikalus1988 with the user to tip).📖 If you want to learn more, check out our documentation.
Reactions are currently unavailable
Activity
docs(maintainer): capability inventory, defect register, and a strate…
feat(bounty): runnable, self-checking task fixtures for the #1819 mea…
fix(service): make the endpoint's self-report true, and release the i…
fix(service): make the endpoint self-report true, and release the ins…
Auto-merge #1863: feat(ci): the MCP registry listing publishes itself…
Ikalus1988 commentedon Sep 19, 2026
The registry half of this issue is fixed, and it is now maintained by CI rather than by memory.
Before / after (registry API, read out of the registry itself)
Why it was stuck, and why "retry later" was never going to work
Publishing was a manual step on a maintainer's machine:
mcp-publisher login github(device code) →publish server.json. Nothing in CI watched it.I tried to do it by hand from this environment today and it cannot be done there at all:
token poll died with
dial tcp 20.205.243.166:443: i/o timeout;https://github.com/login/device→ HTTP 000 after 15s, whilehttps://registry.modelcontextprotocol.io/...→ HTTP 200 in 1.6s, andapi.github.com→ 200.So the sandbox can reach the registry but not the thing that authorizes it.
release-checklist.mdsaid "retry manually when network is available" — from inside a sandboxed agent environment, that is
never. (The repo already recorded this on 2026-09-12 as "沙箱到 github.com 的 device-flow 出口不通".)
What landed (#1863, merged
99119bd75).github/workflows/publish-mcp-registry.yml, using the registry's documented method for GitHubActions —
mcp-publisher login github-oidc, i.e. the repository is the identity: no storedsecret, no device code.
release-please.ymldispatches it when, and only when, it created a tag(dispatch-only on purpose: release-please tags with
GITHUB_TOKEN, and a GITHUB_TOKEN push cannottrigger a
push: tagsworkflow — a tag trigger would have looked right and never fired).Three checks the manual path never had:
mcp-publisher validatefirst;isLatestis the version just published.Run 35440807153:
Docs updated:
release-checklist.mdstep 10, and the directory matrix inmaintenance.md§10.Still open in this issue
Part 1 — the MCP server's self-reported version stuck at 2.27.1 — is untouched here. That is the
other unmaintained number:
workers/register-proxy-sw.jshasversion: env.MCP_VERSION || "2.27.1"with a hardcoded fallback, and the comment above it describes a build-time injection that does not
exist. The registry half is now automatic; making
serverInfo.versiontell the truth needs theworker's var to be wired to something that moves at release time (or the fallback removed so a
missing value is visible rather than plausible). Leaving the issue open for that.
Ikalus1988 commentedon Sep 19, 2026
Both self-reported numbers now have a maintainer, and they are both current as of the 2.31.0 release
that went out while this was being fixed.
Where they stood, and where they are
serverInfo.version(every client's handshake)workers/register-proxy-sw.js, which is annotated for itisLatest(the authoritative listing)publish-mcp-registry.ymlpublishes it on every release and reads it backWhat the automated path caught on its first real run
The registry publish failed on 2.31.0 — which is the value of wiring it up:
The registry validates that the version in
packages[]exists on the package registry, and therelease flow dispatches the PyPI publish and the registry publish at the same moment — a race between
two sibling steps, not a flake. The workflow now waits (polling PyPI, up to 10 minutes) before
authenticating, and the re-run succeeded:
isLatest = 2.31.0(run35441564386). Without theautomation this would have been one more "retry it by hand later" that never happened.
The one thing still not true
env.MCP_VERSION— the variable the comment andalign_versions.pyrefer to — is still neverinjected:
wrangler.jsoncand the deploy workflow define no such var, so the number clients see isthe annotated constant. That is correct today and maintained from now on, but the env branch is a
second path that does not exist. Either wire it at deploy time or delete the branch, so the code stops
implying a mechanism that isn't there. I am leaving this issue open for exactly that, since it is the
remaining half of its title ("a self-reported number with no maintainer" — now it has one, but the
story in the code is still wrong).
feat(ci): the MCP registry listing publishes itself, and is read back (…
fix(release): the release PR can pass again — every pinned version ge…
fix(ci): the auto-merge stops writing its own changelog entry twice
feat(ci): the docs auto-merge channel gets a way in — a maintainer's …
Ikalus1988 commentedon Sep 19, 2026
The last unverified claim of this issue is now verified against the live database — and it doubles as
the end-to-end proof of the installer's context hints (#1859).
The columns are real, and the privacy shape holds
max_q = 80withover80 = 0: every stored query is truncated at exactly the documented 80characters — no verbatim prompt;
long_hint = 0and 8-hex values (abea0c8d,8103f7bb,eeaba900):client_hintis the salteddedup key, not the client id as sent;
And the newest row is a full hint chain
agent+version+oson one row is the installer'sX-MisakaNet-*headers arriving from a realclient — the piece that was missing when this issue was written, verified on production data rather than
in a fixture. (The two older hint rows show
os = wsl2and no version, i.e. an earlier client that sentthe OS hint only, which is what the read policy expects: every hint is optional.)
Method:
wrangler d1 execute misakanet-db --remote --config workers/wrangler.tomlagainst the live D1binding. Two environment notes for anyone re-running it from this machine:
api.cloudflare.comresolvesto IPv6 first and this environment has no IPv6 route (force IPv4), and wrangler wants
WRANGLER_CACHE_DIRinside the workspace.fix(bootstrap): the second installer was a release behind — no contex…
chore(npm): record 2.34.0 — the publish run could not push it, becaus…
Ikalus1988 commentedon Sep 25, 2026
Re-verified today, and narrowed to one half
Half 1 — the self-reported MCP version — is fixed. Live handshake, 2026-09-25:
and the constant now has the owner this issue asked for:
x-release-please-versionis release-please's annotation, so the number moves with the release train instead of waiting for a human. That is the structural half of the report answered, not just the value nudged.Half 2 —
/api/counter's last-resort fallback — is still there, and still reads a branch that nothing keeps current:So the path this issue describes is unchanged: when D1 and KV both fail, the public counter silently falls back to a file on the
databranch. Note the file that is maintained (data/counter.jsononmain, updated bysync-node-counter.yml, currently{"current": 12480, "updated": "2026-09-24T09:29:05Z"}) is a different file on a different branch from the one the fallback reads — which is why the fix here is a decision about the fallback, not a sync job.Options as originally stated, in the order I would take them: make the fallback fail loudly (a 5xx is honest, a 3.5-month-old number is not), or point it at a file something actually writes, and either way add the read-back comparison the issue asks for. Left open for that decision rather than closed with the version half.
fix(worker): the counter's last resort read a branch that no longer h…
feat(doctor): read the deployed version back, so a self-reported numb…
Ikalus1988 commentedon Sep 25, 2026
两半都处理完了,逐条给证据。
第 1 半:MCP 自报版本(已被人修好,本轮验证了机制)
线上实测(今天,多次):
而且机制是有的,不是又手改了一次数:
workers/register-proxy-sw.js:527现在是version: env.MCP_VERSION || "2.34.0", // x-release-please-version—— 带 release-please 标记,发版时会被自动推进;
scripts/align_versions.py:127解析这一行(locations()里的 key 就叫"workers/register-proxy-sw.js (serverInfo)",注释直接写着 MCP 自报版本停在 2.27.1,公开计数的兜底停在六月:两个没有维护者的自报数字 #1820),:268会重写它;:261-265那段注释:env.MCP_VERSION只在
wrangler deploy --var这种 ad-hoc 覆盖时用,故意不写进 wrangler.toml,否则运行时就多一个"没被测过的所有者"(
env.MCP_VERSION || constant)。记录一下,因为这与 issue 里的第 1 条建议不同。第 2 半:
/api/counter的末级兜底(已修,PR #2190 →0646e2d3ce)实测比 issue 里写的更糟:那个路径现在是 404,不是"停在六月的数字"。
data/counter.jsondata(代码用的默认 ref)counter.json,冻结在 2026-06-01({"current": 10047})main{"current": 12480, "updated": "2026-09-24T09:29:05Z"},sync-node-counter.yml每天刷新所以 D1 与 KV 同时不可用时,末级兜底抛异常 → 502。而
data分支根目录那份六月文件正是你报的这个数字:把兜底指向它就能"修好 404",同时把原缺陷换个形状带回来——所以修法是显式写
main。同一处错误还在 PR Genius 的 stats 分支里:它的无 token 分支一直在读
main,同一个 handler 自相矛盾。修法:
fetchFromGitHub去掉默认 ref(两个依赖默认值的调用点就是两个坏掉的),两处都显式写"main"。门禁两个方向都验证过:
workers/register-storage-d1.test.mjs新增的行为测试(让 D1 抛错、去掉 KV 绑定、stub
globalThis.fetch,断言它构造的 URL 是ref=main)在旧代码上not ok;tests/test_worker_github_fallbacks.py(8 条)在旧代码上红 3 条。deploy-worker.yml的release环境批准,run36092864451此刻状态是
waiting。批准之前线上仍是旧行为。顺手把"读回来比对"的门禁补上了(PR #2191 →
0ce31e33)你建议里那条门禁此前不存在:所有检查都读文件,没有一条问服务。现在
doctor.py有第四个检查deployed-version,由新的--post-deploy标志触发(部署 job 已改用它,顺带享有那 5 次重试):期望值取自
scripts/align_versions.py(它本来就是这个数字的所有者);它故意不进普通doctor.py——开发者的检出常常领先于线上,默认比较会为一件不是缺陷的事变红。
仍然存在、留给你决定的一点
data分支根目录那份 冻结在 2026-06-01 的counter.json还在那里,对下一个读者仍是陷阱。删掉它意味着往
update-badges.yml拥有的分支上写,我倾向由你决定,而不是我去写一个自动化 job 正在提交的分支。两个 PR 都合了、门禁都在两个方向上验证过,所以这条按"已实现"关闭。如果部署批准后
--post-deploy报出差异,那正好是它存在的意义。fix(ci): the OCR review's four real findings — a dead token guard, an…
fix(worker): a missing lesson answered "retry shortly", and any repos…
chore(data): delete the frozen counter.json — the endpoint has no fil…
chore(data): the node counter has no copy in the repository, and the …
fix(leaderboard): read the bench board from `main`, not the `data` br…
feat(leaderboard): hold the contributor board in D1, not in 1,026 com…