c0ecf2fa3bebd46bdfd0169efd73b89653d1dfed
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
678acfe7ef |
fix(mcp): eager-auth flag so claude.ai's connector dialog detects OAuth, not "None" (#2159)
claude.ai's two-step "Add custom connector" dialog probes the server URL without credentials and pre-fills the Authentication choice from the answer. Our lazy-auth endpoint (issue #1814) answers 200 on an anonymous initialize, which the dialog reads as an authless server: it suggests "None", and a connector added with that default never opens the sign-in when the challenge arrives later. Per Anthropic's connector docs a 401 is the only answer it reads as OAuth ("Claude does not honor a WWW-Authenticate header on a 200 response"). - `auth=required` on the endpoint URL (extensions/general/mcp-server/ auth-mode.ts) turns lazy auth off for that URL: every tokenless request, initialize included, answers the 401 + WWW-Authenticate challenge. Callers with a token are unaffected; the bare URL keeps lazy auth for Claude Code, the plugin, Cursor and ChatGPT, and existing connector records are untouched. - The links we control carry the flag: Settings -> API & MCP (install link and copy block), the onboarding checklist, both docs pages and claude-plugin/CONNECTORS.md (plugin 1.2.3). The docs' Path A now describes the eager flow (sign-in opens on Add) instead of telling users to override the dialog's "None". - Tests: eager-auth.test.ts (401 on initialize/tools/list/public tools, namespaced metadata pointer, token no-op, exact-flag only); checklist link shape updated. Companion: gnubok-website PR (Kom igång connector link + regenerated connect-claude / anslut-claude pages). Claude-Session: https://claude.ai/code/session_013yw62FMXGSzo6icFDiBwP3 Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
4f33184a9a |
fix(mcp): explain the Claude-side steps after "Anslut till Claude" and tick the checklist on a real connection (#2133) (#2147)
* fix(mcp): explain the Claude-side steps after "Anslut till Claude" and tick the checklist on a real connection (#2133) Lazy auth is by design: Claude lists the tools before any sign-in and the first company-scoped call answers 401, which opens the Accounted sign-in. Nothing told the user, so a "connected" status with an unanswered first question read as a broken connection (Axel, Discord). - Settings -> API & MCP: one sentence of expectation under the button, and the step-by-step guide link moved from under two disclosures to directly under the button. - Docs (connect-claude / anslut-claude): new "What happens after you click" section for Path A covering the connector dialog, the tools appearing before sign-in, the first-call login + consent screen, "ask again", and the "Required when the server asks" auth setting that only the manual path mentioned. - Hem checklist step "Anslut till Claude": deep link now carries client=claude-connector like the settings button (claudeConnectorLink), the footnote carries the same expectation line plus the guide link, and the done-signal is an unrevoked api_keys row minted by the MCP OAuth token route (OAUTH_MCP_KEY_NAME) instead of the in-app AI-profile flag, which never meant "connected to Claude". - Tests: claudeStepDone with/without a key row, deep-link snapshot. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W7iJQwKiRTDWSMnRm4WM4L * fix(mcp): correct consent-page claims, stop the completion PATCH loop, count OAuth keys past RLS (#2133) Three skeptic refutations on PR #2147, fixed in one pass: - Docs (EN + SV): the consent page shows the company active in the app and pre-selects every scope for Claude's connector (founder decision 2026-08-26); it has no company picker and nothing to tick. Steps 3-4 of the new section, the "Read-only by default" paragraph above it, the sandbox note and the 10-minute test now describe Endast läs under Behörigheter instead. - Checklist completion: users with initial_setup_path NULL (skipped the books question, then imported) hit the route's "Välj först hur du vill komma igång" 400 and, with saving as an effect dependency, retried it forever with a toast. completionPatchBody() records path=migration when none was chosen, and a rejected PATCH is not retried within the session. - hasMcpKey: api_keys' SELECT policy is company-scoped, so the user client could not see companyless (NULL company_id) or archived-company keys and the step stayed open for the user who had just connected. The head count now runs through the service client with an explicit user_id filter. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W7iJQwKiRTDWSMnRm4WM4L * fix(mcp): surface a failed OAuth-key count and reserve the marker name (#2133) CodeRabbit round on PR #2147: - app/(dashboard)/page.tsx: a failed api_keys count answered count null, which claudeStepDone read as "never connected". Throw to the error boundary like the settings fetch does instead of guessing. - app/api/settings/api-keys: reject a hand-minted key named MCP-klient (OAuth) (400 VALIDATION_ERROR): that name is the marker the Hem checklist reads as "connected to Claude", so a manual key with it would tick the step without any connection. Test added. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W7iJQwKiRTDWSMnRm4WM4L --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
b5da51ea0a |
feat(settings): API & MCP tab: correct connector URL namespace, plugin path, Swedish guide (#2105)
* feat(settings): API & MCP tab: correct connector URL namespace, plugin path, Swedish guide The in-product MCP URLs omitted `tool_namespace=accounted`, and resolveMcpToolNamespace() falls back to the legacy `gnubok_` prefix when the param is absent. Every connection made from Settings therefore got `gnubok_*` tool names while the docs, the accounted-api skill, and claude-plugin/.mcp.json all reference `accounted_*`. - Add `tool_namespace=accounted` to the Claude.ai, Claude Code, and Claude Desktop snippets. - Move the Claude Desktop bridge from `npx gnubok-mcp` / `GNUBOK_API_KEY` to `npx -y accounted-mcp` / `ACCOUNTED_API_KEY`, and emit `ACCOUNTED_URL` so self-hosted and white-label instances get a config pointing at their own host. The `gnubok_sk_` key prefix is unchanged: it is wire format. - Surface the Claude Code plugin, the only path that configures the connection and the seven workflow commands in one step. - Rename the settings tab "API" to "API & MCP" and rewrite its intro: the MCP connection is what most users come here for, not API keys. - Link the step-by-step guide from the panel, locale-aware. Docs: add a Swedish /docs/api/anslut-claude alongside the English page (the docs site has no locale routing, so each language is its own URL), give both the Claude Code plugin path, and teach the export and freshness scripts about the new page so cross-repo drift is caught. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HfZgiZmNN6qGEfgvXqxAeg * fix(settings,docs): Cursor is not Claude Code; use the accounted_ tool name Review follow-up on #2105. `claude mcp add` is a Claude Code command. Cursor does not read it, so the "Claude Code / Cursor" row and the docs sentence pointing Cursor users at that command were both wrong (the row predates this PR; the docs sentence did not). Cursor now gets its own row and its own `~/.cursor/mcp.json` snippet with the `url` field, in the panel and in both docs pages. Also `vat_close_check` -> `accounted_vat_close_check` in the reviewer test on both pages, matching the identifier used in the prompts section above it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HfZgiZmNN6qGEfgvXqxAeg * feat(settings,docs): one-click Connect to Claude, and cut the panel to one action Anthropic documents an install link for custom connectors: https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=NAME&connectorUrl=ENCODED (claude.com/docs/connectors/building/directory-vs-custom). It opens claude.ai with the connector name and URL prefilled; the user still reviews and confirms, and it grants nothing on its own. We were telling people to copy a URL and go paste it somewhere else instead. Settings panel, rendered and reviewed: - "Connect to Claude" button is now the only thing above the fold. Everything that needs a config file or a terminal (claude.ai manual paste, Claude Code, the plugin, Cursor) moved into one "Other clients" disclosure, and the API-key methods keep theirs. Four code blocks -> one button, 1057px -> 719px. - The connect group renders above the API-keys group. Connecting is why users open this tab; the tab's own intro says so. - Each entry inside the disclosures shows its instruction as visible text. They were `?` HelpPopovers, so the panel read as opaque code blobs with no instructions on screen. - Prose interpolates the brand's real casing, not the lowercased config key. Docs, both languages: Path A leads with the install link and drops from five manual steps to a link plus three short paragraphs, with the manual paste kept under a subheading. No raw HTML: the docs renderer has no rehype-raw, so <details> would have been silently dropped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HfZgiZmNN6qGEfgvXqxAeg * fix(settings,docs): correct claude mcp add syntax and the SSR install link Review follow-up. Both findings verified before acting on them. `claude mcp add --help` gives `claude mcp add [options] <name> <commandOrUrl>`: the URL is positional and there is no `--url` flag, so the API-key snippet would have failed on a missing argument. Both commands now put `--transport http` before the name and pass the URL positionally, in the panel and in both docs pages. The panel is server-rendered before it hydrates and window.location has no server equivalent, so the install link was built from a relative mcpBase in the first paint. A click in that window would hand claude.ai a connectorUrl it cannot resolve. The origin now resolves after mount and the anchor carries no href until it is known, which also makes it unclickable rather than wrong. Verified: the SSR HTML contains no claude.ai href and no relative connectorUrl, post-hydration the href is absolute, and there are no hydration warnings. DECISIONS.md: code-span the `gnubok_*`/`accounted_*` wildcards so they stop rendering as emphasis, and drop the "no one-click deeplink" claim from the earlier entry rather than leave a false statement standing two lines above its own correction. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HfZgiZmNN6qGEfgvXqxAeg --------- Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |