Skip to content

docs(readme): note the sign-in step the claude mcp add one-liner needs - #11019

Merged
os-elon merged 1 commit into
mainfrom
claude/issue-10319-readme-mcp-add-auth
Aug 22, 2026
Merged

docs(readme): note the sign-in step the claude mcp add one-liner needs#11019
os-elon merged 1 commit into
mainfrom
claude/issue-10319-readme-mcp-add-auth

Conversation

@os-elon

Copy link
Copy Markdown
Collaborator

Fixes#10319

What was wrong

The root README's "Your app is AI-operable, for free" section hands the reader a copy-paste one-liner:

claude mcp add --transport http my-app http://localhost:3000/api/v1/mcp

Run it, then try to actually use the connection, and it 401s — no hint anywhere in the README that a sign-in step follows. Re-derived by content at head (the file has moved several times today via #10881/#10929/#10968, then #10321 and #10320): the snippet still lives at README.md:171-173 on this branch, unchanged in shape from the card.

The two-part fix — both halves verified

1. Read the linked docs page first (per triage's framing).content/docs/ai/connect-mcp.mdx — the page the README delegates to — already carries the auth step in full: a "Claude Code (one command)" section explaining that interactive clients use OAuth and the first tool call opens a browser login, a headless API-key flow for CI/containers, and a troubleshooting table that names the exact 401 this card is about. The docs page is not missing anything — no docs-page finding to file. The gap is entirely in the README, which presents the command with no pointer to any of that.

2. The README fix — one clarifying sentence after the snippet, no change to the command itself (inlining full auth setup here would just move the defect the README already correctly delegates elsewhere):

 claude mcp add --transport http my-app http://localhost:3000/api/v1/mcp

-Objects are exposed automatically; actions opt in with ai: { exposed: true }.
-See Connect an MCP Client.
+The first tool call opens a browser to sign you in — each deployment is its own
+OAuth server, so there's no token to copy-paste. Headless setups (CI,
+containers) use an API key instead. Objects are exposed automatically; actions
+opt in with ai: { exposed: true }. See
+Connect an MCP Client for both flows.


## Verification — live, at head, not reasoned about
Built the dependency closure and booted a real `examples/app-crm` instance (`pnpm start`, compiled — the `pnpm dev`/tsx path currently fails to resolve `packages/formula/src/index.ts`'s `./registry` import unrelated to this change, so `start` was used instead) on `localhost:3000`, then, in-process:
- **Ran the printed command for real**: `claude mcp add --transport http my-app http://localhost:3000/api/v1/mcp` → `Added HTTP MCP server my-app ... to local config`, confirmed via `claude mcp get my-app`. Removed afterward (`claude mcp remove my-app -s local`) — this was local-scope, never touched the repo's committed `.mcp.json`.
- **Reproduced the original defect**: unauthenticated `POST /api/v1/mcp` `initialize` → `401 {"code":"UNAUTHENTICATED","message":"Unauthorized: a valid OAuth access token or API key is required"}`, with a `WWW-Authenticate: Bearer realm="ObjectStack MCP", resource_metadata=".../.well-known/oauth-protected-resource"` header — exactly the header the docs page's troubleshooting table cites, and exactly the 401 the original finding measured.
- **Verified the headless path the new sentence points to**: signed up the first owner (`POST /api/v1/auth/sign-up/email`), minted an API key with the session cookie (`POST /api/v1/keys` → `{"success":true,"data":{"key":"osk_..."}}`, byte-for-byte the flow the docs page documents), then called `initialize` again with `x-api-key: osk_...` → `200 {"result":{"protocolVersion":"2025-06-18",...}}`.
- **Honestly not verified**: the interactive OAuth *browser* login itself — that requires a real browser and a human clicking through a login page, which this sandboxed environment cannot drive. The corroboration above (the `WWW-Authenticate` challenge is served exactly as the docs describe, and the headless alternative the same docs page offers works end-to-end) is what stands in for it.
- Cleaned up: killed the server process tree, removed the local MCP registration, reverted an incidental executable-bit change `pnpm install` made to `packages/create-objectstack/bin/create-objectstack.js` (cluster-B territory, untouched by intent — confirmed `git status` is clean except this PR's two files before committing).
Reverse verification does not apply — this is a prose-only change with no code path to ablate; noted per the brief rather than silently skipped.
## Gates — derived at final commit `47869aeefd`
`node scripts/pm/dispatch-gates.mjs` (no paths — derived from the diff at HEAD vs merge-base `45204a5e3`) names 6 local gates for this surface, all run and green:
- `pnpm check:doc-anchors` → `✅ check-doc-anchors: 279 internal #fragment link(s) across 407 source file(s) all resolve to a real heading`
- `pnpm check:changeset-gate-self-tests` → `✓ objectui-changeset-digest --self-test: all checks passed` / `✓ objectui-range --self-test: all checks passed`
- `pnpm check:objectui-changeset` → same self-tests as above (shared script)
- `node scripts/check-adr-0087-registration.mjs` → `✓ check-adr-0087-registration: this PR adds no declared-breaking changeset (0 non-breaking changeset(s) seen).`
- `node scripts/check-changeset-no-major.mjs` → `✓ This diff introduces no major bump.`
- `node scripts/check-empty-changeset.mjs` → `✓ No empty-frontmatter changeset introduced by this diff (0 declaring changeset(s) added).`
The derivation also flagged one ambiguous "silent" verdict worth naming explicitly: `node scripts/check-changeset-fixed.mjs` declares only `.changeset/config.json` as its population, which sits in the same directory as the new changeset file — read the gate's source to resolve it (it only cross-checks `pnpm-workspace.yaml` packages against the `fixed` group in `config.json`; it never scans individual `.changeset/*.md` files), then ran it anyway: `✓ .changeset/config.json "fixed" group is in sync with 69 public workspace packages.`
**`Check Documentation Links`** (in scope per the brief for root `README.md`) could not be run live: `lychee` isn't installed locally, and fetching the pinned binary (`v0.24.2`) from the GitHub releases CDN through this session's proxy is blocked (`api.github.com` returns "GitHub access to this repository is not enabled for this session"; the raw release-asset URL 404s through the same proxy) — the same egress restriction the brief called out as having blocked live verification elsewhere today. Corroborated instead by direct diff inspection: the touched section's link targets are byte-identical before and after (`http://localhost:3000/api/v1/mcp` inside the code fence, and `https://objectstack.ai/docs/ai/connect-mcp` as the one Markdown link) — this diff introduces no new or changed link target, so the gate's outcome on this file is unaffected by the change regardless of the tree's pre-existing state.
## Scope
Root `README.md` only, plus a changeset (`@objectstack/spec` patch, matching the convention #10320 used for the same file). No touch to `content/docs/releases/**`, no touch to cluster B (`packages/create-objectstack`, the blank template, #10322/#10324/#10325 territory) — the one incidental change a build made there (an executable-bit flip on `create-objectstack.js`) was reverted before committing, not shipped.
## Out-of-scope findings
None filed. The linked docs page was in scope to *read*, not fix, and it needed no fix.
---
_Generated by [Claude Code](https://claude.ai/code/session_019bmVFqoQPq63zhKrxdYG1r)_

…eds (#10319)
The "Your app is AI-operable, for free" section's copy-paste command —
`claude mcp add --transport http my-app http://localhost:3000/api/v1/mcp` —
registers the MCP server correctly, but the next natural step (an agent
actually calling a tool) 401s until the caller signs in. Measured live, at
head, against a freshly booted `examples/app-crm`: unauthenticated
`initialize` returns `401 {"code":"UNAUTHENTICATED","message":"Unauthorized:
a valid OAuth access token or API key is required"}`, matching the finding
this closes. The README gave no hint that a sign-in step follows the
command.
The linked docs page, content/docs/ai/connect-mcp.mdx ("Connect an MCP
Client"), already carries the step in full — interactive OAuth browser
login for the exact same command, plus a headless API-key flow for
CI/containers — so the fix is a one-sentence pointer here, not a rewrite of
a page that already correctly carries the weight this README delegates to.
Fixes#10319
Claude-Session: https://claude.ai/code/session_019bmVFqoQPq63zhKrxdYG1r
Co-authored-by: Claude <noreply@anthropic.com>
@github-actionsgithub-actionsBot added size/s documentation Improvements or additions to documentation tooling labels Aug 22, 2026
@os-elon
os-elon marked this pull request as ready for review August 22, 2026 08:34
@os-elon
os-elon added this pull request to the merge queueAug 22, 2026
Merged via the queue into main with commit de19489Aug 22, 2026
24 checks passed
@os-elon
os-elon deleted the claude/issue-10319-readme-mcp-add-auth branch August 22, 2026 08:44
@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 32562656477 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

失败的 job(日志抽取,best effort):

  • Console Pin Gate — 失败步骤: Build the Console SPA at the pinned objectui SHA

    ✗ Build failed in 5.95s
    

↳ 失败原因 是判读的关键:超时Test timed out in … / Hook timed out in …)多半是负载/时序,不是本 PR 的回归;
断言AssertionError: …)才指向真实的行为改变。两者的 FAIL 行长得一模一样,只有这一行能区分。

跨 PR 相同签名(24h,按失败测试文件聚合):

  • ⚠️本次没有可用的聚合签名(日志里没有能解析出测试文件名的 FAIL 行)—— 这不是「没有同签名的其他 PR」,是这一轮没测到。跨 PR 聚合本次不可用,请手工比对其他 PR 的同类评论。
  • ⚠️ 24h 评论账本没读完(超过 5 页仍未读到窗口尽头),所以上面的「不同 PR 数」是下界,不是全量。

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 90 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 看上面的「跨 PR 相同签名」;已有汇总 issue ⇒ flaky/环境问题实锤,去那张 issue 上谈,修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/stooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] The README's claude mcp add one-liner 401s as printed — the endpoint is fine, the documented command omits auth

2 participants

@os-elon@claude