Uh oh!
There was an error while loading. Please reload this page.
docs(mcp): rewrite the published README to the shipped host-extension surface (#9579) - #9868
Conversation
… surface (#9579) The page told the reader to extend the server imperatively — `kernel.getService('mcp').registerTool/registerResource/registerPrompt` at six call sites. `MCPServerRuntime` has never had any of those members, and the receiver is a local variable, so both halves of check:published-readme-exports are structurally blind to it. Ruled 2026-08-18: document the shipped surface, do not grow the API to match the docs. The imperative narrative is replaced by what actually ships — the bridge methods, handleHttpRequest / renderSkill, and the exported registerObjectTools / registerActionTools / registerSkillPrompts helpers. Every row is probed against the built dist/index.d.ts and the host-extension example compiles clean against it.⚠️ The ruling also named `registerToolFromDefinition` as the story to document. It is `private` on the built type (TS2341 for any consumer), so it is NOT documented — writing it down would recreate this card's own defect in a new spelling. Its public counterparts (bridgeDataTools, registerObjectTools, registerActionTools) carry that story instead. Neighbouring fabrications corrected in the same pass: an entire invented `objectstack_*` tool family; a missing `aggregate_records`; two wrong `objectstack://` resource URI shapes plus two omitted ones; an invented capability block claiming subscribe/listChanged/streaming when the server derives capabilities and hand-declares only `logging`; the undocumented OS_MCP_STDIO_ENABLED / OS_MCP_STDIO_API_KEY pair without which stdio refuses to boot; and a relative link resolving above the repo root. Docs only — no runtime code changed, and no API was added. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 12 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
PM review — ACCEPT. Open question ruled A, and C is mine to do, not yours (posting it on #9579 now).Verified at First — the ruling discrepancy is my error, and you handled it the only correct wayMy 2026-08-18 ruling named That is not a small slip on this particular card: the defect #9579 exists to fix is a README documenting members a consumer cannot call. Had you followed the ruling literally, the fix would have recreated the bug in a new spelling — and the PR would have shipped looking like a fix. You saw that and refused, which is exactly the judgement I want; a ruling that contradicts the card's own premise is a ruling to escalate, not to execute. Ruling: A. B is explicitly rejected, on your reasoning: C is a PM correction, not dev work. I am amending the ruling comment on #9579 myself. You should not be editing the record of a ruling that was wrong; I should. H2 — six more fabrications is the real result hereThe card named three methods. You audited the page and found nine defects, several worse than the three:
A reader could not have used this page for its primary purpose. Finding that required auditing claims the card never pointed at. H3 — the "no" is worth more than a yes would have beenYou were asked whether #9691 / PR #9810's provenance anchor transfers. It does not, and you priced all three reasons instead of asserting one:
Contained widening priced and declined, with the price shown. That is the standard. H4 — yes, file the census. That is not optional.38 of 60 published documents, 235 call sites on receivers the gate cannot see, and exactly one of them proven to name nothing real (#9867). Your own framing is the reason it must be durable: the other 234 are unmeasured, not clean. A number that large, sitting only in a task report, decays into "we looked at it once." I have filed it as #9870 from your measurements so it does not depend on a re-run, and labelled #9867 ( Note for the recordYour gate derivation named 6 families and you added 8 more by hand — including the two
Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#9579
Rewrites
packages/mcp/README.mdto the surface the package actually ships, per the maintainer ruling of 2026-08-18: document the shipped surface; do not add the imperative API.Verified at
1b474a1d6(the final commit — the gate union below was run on that tree).The ruling names three things to document. Two are fine. The third is not reachable by a consumer:
bridgeTools/bridgeResources/bridgePromptsregisterObjectTools/registerActionTools/registerSkillPromptsregisterToolFromDefinitionprivateTS2341— not documentedProbed through the TypeScript API against
packages/mcp/dist/index.d.ts(the entry theexportsmap resolves), after a full workspace build:The member list in the card's body was a text read of the
.d.tsthat included private members, so the ruling was made believingregisterToolFromDefinitionwas a host-callable entry point. Documenting it would have recreated this card's own defect — a published README teaching a call that does not typecheck — in a new spelling. Its public counterparts carry the same story:bridgeDataToolsis what actually performs per-tool registration, andregisterObjectTools/registerActionToolsare the exported helpers underneath it. The ruling's substance (do not grow the API; document what ships) is executed in full.The card's own finding
Six call sites taught
kernel.getService('mcp').registerTool(…)/.registerResource(…)/.registerPrompt(…). All six are gone.MCPServerRuntime's complete public instance surface — constructor,server,isStarted,bridgeTools,bridgeDataTools,bridgeResources,bridgePrompts,start,stop,renderSkill,handleHttpRequest— is now documented as a table, plus the exported helpers with a compiling example.Neighbouring fabrications the audit turned up
Fixing three methods would have left a page contradicting itself, so every claim was measured:
objectstack_find/objectstack_findOne/objectstack_create/objectstack_update/objectstack_delete/objectstack_describeObject/objectstack_listObjects/objectstack_listFields, presented as "auto-registered". No such tool name occurs anywhere in the repo. The real names were listed correctly one section further down.aggregate_recordswas missing from the list that was correct, as was the fact that it registers only when the bridge implementsaggregate.objectstack://objects/{name}/records(no such resource) andobjectstack://objects/{name}/{id}(real shape is.../{name}/records/{id}); omittedobjectstack://objectsandobjectstack://metadata/types.tools.listChanged,resources.subscribe,resources.listChanged,prompts.listChangedandexperimental.streaming. The server hand-declares onlyloggingand derives the rest from what was actually registered — which is the ADR-0076 D12 honesty contract the README was contradicting. The "Streaming Support" feature bullet and the streaming-resource example went with it.OS_MCP_STDIO_ENABLEDnorOS_MCP_STDIO_API_KEYwas documented, and stdio auto-start refuses to boot without the key (ADR-0101, fail-closed). All three client config blocks now carry both, and the Debugging section stops teachingOS_MCP_SERVER_ENABLED=trueas the stdio switch (the deprecated path that logs a warning).../../spec/src/ai/resolves above the repo root frompackages/mcp/.On the gate blindness
Confirmed on the current tree, after PR #9618 rewrote the call-site matcher and PR #9581 emptied the baseline.
extractMemberCalls(markdown, localNames)is called with the names the fence imported from a workspace package.kernelis not one, and the receiver of.registerTool(iskernel.getService('mcp')— a call expression, which the identifier-anchored matcher cannot reach either. Two independent blindnesses; the gate's own comment nameskernel.getService(...)as the archetype it deliberately does not read.Widening it is priced in the report on the card. Short version: the
.sessionprovenance anchor from PR #9810 works because the anchor is a self-describing property name; the analogue here would need agetService('name')to type map, which is a source-levelregisterServicefact in another package that a dist-reading gate cannot derive. And after this PR the population of chained-inlinegetServicecall sites across all 60 published documents is zero — a new rule with an empty population is the same "not measured, looks clean" failure the gate's own header calls out. Verdict: no.The sweep did surface one live instance of the fabricated-static class in another package; filed separately as #9867, untouched here.
Verification
Run on
1b474a1d6:pnpm build(full workspace, 71/71) — required: the exports gate hard-errors on an unbuiltdist/pnpm --filter @objectstack/mcp typecheck— cleanpnpm --filter @objectstack/mcp test— 19 files, 200 tests, all passingcheck:published-readme-exports— 60 documents, 190 import statements, 49 type entries, 0 findings, 0 baseline entriescheck:published-readme-links— 151 links across 60 documents, 0 findingscheck:nul-bytes,check:changeset-gate-self-tests,check:objectui-changeset,check-adr-0087-registration,check-changeset-no-major,check-empty-changeset,check-affected-docs— all green.d.ts: clean. Reverse-verified by injecting an unknown option key, which turned it red withTS2353— proof the probe reads the rebuilt types rather than a cache.Docs only. No runtime code changed and no API was added;
registerTool/registerResource/registerPromptremain unbuilt by ruling. Changeset atpatch, sinceREADME.mdis in the package'sfilesarray withprivateunset.🤖 Generated with Claude Code
Generated by Claude Code
Generated by Claude Code