Skip to content

fix(mcp,#240): delete the unfixable version read; guard the domain - #264

Merged
kevinthelago merged 1 commit into
mainfrom
240-mcp-version-read
Jul 29, 2026
Merged

fix(mcp,#240): delete the unfixable version read; guard the domain#264
kevinthelago merged 1 commit into
mainfrom
240-mcp-version-read

Conversation

@kevinthelago

Copy link
Copy Markdown
Owner

The mobile half of #240 — needs no desktop change. Part of #234.

Stacked on #263 (239-automations-dead-reads), because both edit the same harness file and would otherwise conflict. Base is set to that branch, so the diff here is the mcp commit alone. Merge #263 first; GitHub will retarget this to main automatically.

version is deleted, not filed as a projection gap

mcpView read readString(r.version, ''). But no version exists in McpServer or anywhere on the wire — and none can, because there is no version string to project. That makes it categorically different from a missing projection: unfixable desktop-side.

Consequences: McpServerVM.version was permanently null, so installTag's version branch was unreachable and every installed server rendered the bare installed literal.

Removed the field, the read, and the dead branch. The test asserting the VM "carries a version through when present" is replaced by one asserting it does not, even when a payload invents one.

builtin is KEPT — a deliberate asymmetry with #239

verdict
Hook.builtin (#239) Deleted — cannot ever exist; Hook is exclusively user-authored config
McpCard.builtin (here) Kept — can and should exist; the payload already carries the built-in ids in installedIds in a form nothing can use, so the fix is withBuiltins(input.servers) in the same builder

Until that lands, builtins is empty and the "Built-in tools" section does not render. That is honest rather than dead: the section is one desktop field away from live, and this decoder needs no change when it arrives.

A decision, not a follow-up

MCP install/update status (McpStat) is out of scope for the mirror. It is Tauri-invoke-derived, name-keyed, ephemeral, and only defined for downloadable first-party servers. It does not belong in a store projection. Recording that here so it is not re-raised as a gap.

Harness

mcp moves from PENDING_DOMAINS into DECODERS — Layer A strict re-encode, plus Layer B asserting both install states resolve (neither falls back to unknown), the stdio server has no url while the http one does, and that builtins is still empty.

That last assertion is deliberately written to fail the day the desktop starts shipping built-ins, so the mobile section gets switched on rather than silently staying empty.

Pending domains: 3 → 2 — only components (#241) and blueprints (#236) remain, and both are desktop-side or stale.

Still open desktop-side

McpCard needs builtin?: boolean, and buildMcpPayload needs withBuiltins(input.servers)preserving the case-insensitive name-shadowing rule, or mobile renders a duplicate when a user server is named Research. Two always-enabled, always-installed servers are invisible to the phone today, so the tool inventory it shows is incomplete. #240 stays open for that.

Gate

  • npx tsc --noEmit clean.
  • 532 tests pass, including Layer A: mcp payload round-trips through the mobile model.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RAPZC6xEyCrH9qSKUKLQdy

@kevinthelago
kevinthelago changed the base branch from 239-automations-dead-reads to main July 29, 2026 06:37
The mobile half of #240 — no desktop change needed.

**`version` is deleted, not filed as a projection gap.** `mcpView` read
`readString(r.version, '')`, but no `version` exists in `McpServer` or anywhere on the wire —
and unlike a missing projection, none *can* exist, because there is no version string to
project. So `McpServerVM.version` was permanently null and `installTag`'s version branch was
unreachable: every installed server showed the bare "installed" literal. Removed the field,
the read, and the dead branch. The test that asserted the VM "carries a version through when
present" is replaced by one asserting it does NOT, even when a payload invents one.

**`builtin` is KEPT, and that is a deliberate asymmetry with #239.** The automations
`Hook.builtin` was deleted because it can never exist — `Hook` is exclusively user-authored
config. `McpCard.builtin` is the opposite: it can and should exist, and the payload already
carries the built-in ids in `installedIds` in a form nothing can use. The fix is
`withBuiltins(input.servers)` in the same builder. Until then `builtins` is empty and the
"Built-in tools" section does not render — honest rather than dead, since it is one desktop
field away from live.

**MCP install/update STATUS (`McpStat`) is out of scope for the mirror — a decision, not a
follow-up.** It is Tauri-invoke-derived, name-keyed, ephemeral, and only defined for
downloadable first-party servers. It does not belong in a store projection.

**Harness:** `mcp` moves from `PENDING_DOMAINS` into `DECODERS` — Layer A re-encode plus
Layer B asserting both install states resolve (neither falls back to `unknown`), the stdio
server has no url and the http one does, and that `builtins` is still empty. That last
assertion is written to FAIL the day the desktop starts shipping built-ins, so the mobile
section gets switched on rather than silently staying empty.

Pending domains: 3 → 2 (`components` #241, `blueprints` #236).

## Still open desktop-side (tracked on #240)

`McpCard` needs `builtin?: boolean` and `buildMcpPayload` needs `withBuiltins(input.servers)`,
preserving the case-insensitive name-shadowing rule so a user server named Research does not
render twice. Two always-enabled, always-installed servers are currently invisible to the
phone, so the tool inventory it shows is incomplete.

Stacked on the #239 branch (PR #263) because both edit the same harness file; this diff
reduces to the mcp commit alone once #263 merges.

Gates: `npx tsc --noEmit` clean; 532 tests pass.

Refs #240

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RAPZC6xEyCrH9qSKUKLQdy
@kevinthelago
kevinthelago force-pushed the 240-mcp-version-read branch from f8c810e to 490beaf Compare July 29, 2026 06:39
@github-actions

Copy link
Copy Markdown

📦 Preview build ready

Artifact: preview-pr-264-6b44d23c8ff048f176b506712eb71c89ea1a3ed4

⬇️ Download from Actions run

Built from commit 6b44d23

@kevinthelago
kevinthelago merged commit 1c3da09 into main Jul 29, 2026
5 checks passed
@kevinthelago
kevinthelago deleted the 240-mcp-version-read branch July 29, 2026 06:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant