Skip to content

fix(cli): warn in doctor when the MCP endpoint lacks the /mcp suffix - #698

Merged
mthines merged 8 commits into
mainfrom
feat/doctor-mcp-suffix-check
Oct 17, 2026
Merged

mthines merged 8 commits into
mainfrom
feat/doctor-mcp-suffix-check

Conversation

@mthines

@mthines mthines commented Oct 17, 2026 •

Copy link
Copy Markdown
Owner

Why

An endpoint like https://<ref>.supabase.co/functions/v1 (missing the /mcp suffix) passes every lorekit doctor check today — the connectivity/authentication probes go over REST via mcpToRestBase, which is suffix-agnostic — and only 404s once an actual MCP client tries to use it.

What changed

  • Added a pure classifyMcpEndpoint (shared MCP_PATH_SUFFIX with mcpToRestBase) that judges whether an endpoint's path is shaped correctly, with a stricter rule on *.supabase.co hosts.
  • Threaded a source id through resolveProjectConnection/resolveConnection/loadControl so doctor can name exactly which config (flag, .mcp.json, ~/.claude.json, .lorekit.json, or an env var) produced a bad endpoint.
  • doctor's endpoint check now WARNs (never fails) on a wrong-shaped endpoint, names the source, and prints a ready-to-run fix. The install fixes carry --force (or --mcp-json for the committable web entry) so they get past install's already-installed early return. On a *.supabase.co host, a wrong path gets <origin>/functions/v1/mcp as the suggested URL. A healthy endpoint's output is unchanged.
  • Updated docs/cli.md, the CLI README, the self-host skill (+ version bump), self-host.mdx, remote.mdx's "Verify the connection" step, and the llms.txt template (regenerated) to describe the new warning. *.supabase.co needs /functions/v1/mcp; a custom domain or reverse proxy only needs the path to end in /mcp.
  • The three older resolveProjectConnection tests no longer read the real ~/.claude.json.

How to verify

  • cd packages/cli && node --test test/doctor.test.mjs test/config.test.mjs. The FIX_CASES test installs with a bad endpoint, runs each printed fix, and asserts the entry changed.

Add a pure classifyMcpEndpoint + MCP_PATH_SUFFIX shared with
mcpToRestBase, thread a source id through resolveProjectConnection/
resolveConnection/loadControl, and use both in doctor's endpointCheck
to WARN (never FAIL) with the offending source and a fix command —
closing the gap where a suffix-missing endpoint passed every doctor
check via the suffix-agnostic REST probes and then 404s for MCP
clients.
Update docs/cli.md, packages/cli/README.md, the self-host SKILL.md
(Step 8 + version bump to 1.0.1, mirrored to the plugin copy), and
self-host.mdx Step 3 to describe the new WARN when a resolved MCP
endpoint does not end in /mcp — replacing the old "check the suffix
yourself" guidance now that doctor does it automatically.
@github-actions

github-actions Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

The dashboard preview for this PR — redeployed on each push that changes the web app.

Project Deployment Actions Updated
lorekit Ready Ready Preview Oct 17, 2026 12:31pm UTC

Preview always points at this PR's latest commit; Deployment is the immutable build of 3eabed0. · Comment /web-preview to force a redeploy. · Workflow logs

@mthines

mthines commented Oct 17, 2026 •

Copy link
Copy Markdown
Owner Author

⚠️ No findings — 1 gate needs attention

The prior blocking finding is fixed: every printed lorekit install fix now carries --force or --mcp-json, and a new test runs each one against an installed scope. Nothing new blocks.

Warnings: Docs list omits llms.txt/template.md and remote.mdx, added in 3eabed0

Checked: 14 of 14 changed files read · 4 of 21 dependent files traced · 1 possible issue → 0 confirmed → 0 posted

What this change reaches — 7 changed exports · 21 dependent files · 4 checked · 17 not checked
flowchart LR
  subgraph pr["Changed in this PR"]
    s1["loadControl<br/>body changed"]:::changed
    s2["resolveProjectConnection<br/>body changed"]:::changed
    s3["copyDir<br/>body changed"]:::changed
    s4["mcpToRestBase<br/>body changed"]:::changed
    s5["classifyMcpEndpoint<br/>added"]:::changed
    s6["ENDPOINT_SOURCES<br/>added"]:::changed
    smore["+1 more changed export<br/>listed below"]:::changed
  end
  s1c1["packages/cli/src/store/index.mjs<br/>✓ checked"]:::ok
  s1c2["packages/cli/src/commands/ · 10 files<br/>✓ 3 checked · ? 7 not checked"]:::partial
  s1c3["packages/cli/test/config.test.mjs<br/>? not checked"]:::unknown
  s2c1["packages/cli/src/shared/ · 2 files<br/>✓ checked"]:::ok
  s2c2["packages/cli/src/commands/ · 2 files<br/>? not checked"]:::unknown
  s2c3["packages/cli/test/config.test.mjs<br/>? not checked"]:::unknown
  s3c1["packages/cli/src/commands/ · 2 files<br/>? not checked"]:::unknown
  s3c2["packages/cli/test/ · 2 files<br/>? not checked"]:::unknown
  s4c1["packages/cli/test/ · 2 files<br/>? not checked"]:::unknown
  s4c2["packages/cli/src/store/remote.mjs<br/>? not checked"]:::unknown
  s5c1["packages/cli/src/commands/doctor.mjs<br/>? not checked"]:::unknown
  s5c2["packages/cli/test/doctor.test.mjs<br/>? not checked"]:::unknown
  s6c1["packages/cli/test/doctor.test.mjs<br/>? not checked"]:::unknown
  s1 --> s1c1
  s1 --> s1c2
  s1 -.-> s1c3
  s2 --> s2c1
  s2 -.-> s2c2
  s2 -.-> s2c3
  s3 -.-> s3c1
  s3 -.-> s3c2
  s4 -.-> s4c1
  s4 -.-> s4c2
  s5 -.-> s5c1
  s5 -.-> s5c2
  s6 -.-> s6c1
  classDef changed fill:#eef2ff,stroke:#6366f1,color:#1e1b4b
  classDef ok fill:#e7f6ec,stroke:#16a34a,color:#14532d
  classDef partial fill:#fef9c3,stroke:#ca8a04,color:#713f12
  classDef unknown fill:#f3f4f6,stroke:#9ca3af,stroke-dasharray:4 3,color:#374151
  classDef bad fill:#fde8e8,stroke:#dc2626,color:#7f1d1d
  classDef warn fill:#fff4e5,stroke:#d97706,color:#78350f
  classDef imports fill:#f8fafc,stroke:#64748b,stroke-dasharray:4 3,color:#1e293b
Loading
  • loadControl (packages/cli/src/shared/control.mjs) — body change · 12 consumer files · 4 verified unaffected · 8 not traced
  • resolveProjectConnection (packages/cli/src/shared/config.mjs) — body change · 5 consumer files · 2 verified unaffected · 3 not traced
  • copyDir (packages/cli/src/shared/config.mjs) — body change · 4 consumer files · 4 not traced
  • mcpToRestBase (packages/cli/src/shared/mcp.mjs) — body change · 3 consumer files · 3 not traced
  • classifyMcpEndpoint (packages/cli/src/shared/mcp.mjs) — added change · 2 consumer files · 2 not traced
  • ENDPOINT_SOURCES (packages/cli/src/commands/doctor.mjs) — added change · 1 consumer file · 1 not traced
  • endpointCheck (packages/cli/src/commands/doctor.mjs) — added change · 1 consumer file · 1 not traced
Review details

Needs attention

Gate Status Details
Description vs. code ⚠️ Docs list omits llms.txt/template.md and remote.mdx, added in 3eabed0.
Prior review feedback ✅ Earlier review comments are resolved.
Documentation ✅ Docblocks, docs/cli.md, README, llms.txt and both docs pages explain the WARN and its fix.
Self-review signals ✅ No debug logs, leftover TODOs, or unreviewed stubs.
Code review ✅ The multi-lens review found no blocking issues.

Found

Quality — produced 1 → posted inline 0 · cleared 0 · carried forward 0 · deferred 0 · below-bar 0
Optimality — ran — 0 proposals: a pure offline shape check plus source threading fits the existing resolver; a live MCP probe was considered and rejected (it would fail on proxies doctor cannot judge)
Standards — ran — 3 governing docs, 0 findings (user-facing docs + llms.txt updated together; skill version bumped)

Run

full · 234 lines in delta · tier deep · depth checkout
⚠️ intent worker returned no readable candidates — ran intent in-context — 1 prepare-time anomaly (no --state file supplied — routing computed with lastFullSha=none, incrRunsSinceFull=0 (forces the D6 'no prior deep pass on record' trigger every run); pass --state after reading the LoreKit state record for an accurate routing decision)
Integrations — not activated — no manifest or lockfile in the diff
CI — still pending: Typecheck, Test & Lint (affected), Web — Vercel preview (changed) / Deploy Vercel preview, Web — Storybook interaction + visual tests (changed) · 6 passed
Memories — 1 indexed · 1 used (1 hotspot)

  • hotspot hotspot::packages/cli/src/commands/doctor.mjs

Nothing to report — measurability (skipped), severity, 0 files skipped.

pr-reviewer · commit 3eabed0 · full review · how these findings are produced · updated Oct 17, 2026 12:43pm UTC

Comment thread packages/cli/src/commands/doctor.mjs Outdated
Comment thread docs/cli.md
Comment thread packages/cli/src/shared/mcp.mjs Outdated
Comment thread packages/cli/test/doctor.test.mjs Outdated
…-installed gate

A plain `lorekit install --project|--global --endpoint <u>` early-returns
on an installed scope, so the printed fix rewrote nothing. Add --force to
every install fix and prove each one rewrites an already-installed entry.
…co host

A *.supabase.co endpoint like /rest/v1 got a placeholder fix even though
the host only serves MCP at one path; suggest the concrete URL instead.
@mthines
mthines marked this pull request as ready for review October 17, 2026 12:51
@mthines
mthines merged commit db84211 into main Oct 17, 2026
18 checks passed
@lorekitbot lorekitbot Bot mentioned this pull request Oct 17, 2026
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