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>
This commit is contained in:
co-authored by
Jakob Wennberg
Claude Fable 5.1
parent
6a85efb00a
commit
678acfe7ef
@@ -21,11 +21,11 @@ Det finns tre vägar in, beroende på vilken klient du använder. Alla tre når
|
||||
|
||||
## Väg A: claude.ai eller Claude Desktop (ett klick)
|
||||
|
||||
**[→ Anslut Accounted till Claude](https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=Accounted&connectorUrl=https%3A%2F%2Fapp.accounted.se%2Fapi%2Fextensions%2Fext%2Fmcp-server%2Fmcp%3Ftool_namespace%3Daccounted%26client%3Dclaude-connector)**
|
||||
**[→ Anslut Accounted till Claude](https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=Accounted&connectorUrl=https%3A%2F%2Fapp.accounted.se%2Fapi%2Fextensions%2Fext%2Fmcp-server%2Fmcp%3Ftool_namespace%3Daccounted%26client%3Dclaude-connector%26auth%3Drequired)**
|
||||
|
||||
Länken öppnar claude.ai med namn och adress ifyllda. Du granskar värdena och godkänner; länken fyller bara i formuläret och ger ingenting i sig. Ingen API-nyckel att hålla reda på.
|
||||
|
||||
**Du behöver inget Accounted-konto ännu.** Anslutningen fungerar direkt: servern svarar på handskakningen och dokumentationsverktygen utan inloggning, och första anropet som rör ett bolag öppnar Accounteds inloggning, där du som ny skapar kontot (BankID eller e-post + 2FA).
|
||||
**Du behöver inget Accounted-konto ännu.** Inloggningen öppnas direkt när du lägger till anslutningen, och där skapar du som ny kontot på plats (BankID eller e-post + 2FA).
|
||||
|
||||
**Alla behörigheter förvalda, varje skrivning stannar ändå.** Godkännandesidan ger hela behörighetslistan med ett klick. Fäll ut **Behörigheter** och välj **Endast läs** för en läsande anslutning (lista fakturor, läsa rapporter, räkna moms): så kan en granskare ansluta läsande medan du själv har en anslutning med skrivrättigheter för det dagliga arbetet. Oavsett behörigheter lägger skrivverktygen (skapa faktura, kontera, bokföra verifikat, köra bokslut) bara upp en pending operation som du bekräftar innan något bokförs, och åtkomsten går att återkalla under Inställningar → API & MCP.
|
||||
|
||||
@@ -33,22 +33,21 @@ Länken öppnar claude.ai med namn och adress ifyllda. Du granskar värdena och
|
||||
|
||||
Resten av inställningarna görs på Claudes sida, i den här ordningen:
|
||||
|
||||
1. **Connector-dialogen.** claude.ai öppnar **Add custom connector** med namn och adress ifyllda. Kontrollera adressen och klicka **Add**. Frågar dialogen om autentisering, välj **"Required when the server asks"**, inte det automatiskt föreslagna "None": servern kräver ingen inloggning när du ansluter, så "None" ser rätt ut men stoppar inloggningen i steg 3. Claude Desktop visar samma dialog under Inställningar → Connectors.
|
||||
2. **Verktygen dyker upp direkt.** Anslutningen visas som ansluten och Claude listar Accounteds verktyg innan du har loggat in. Det är avsiktligt: handskakningen och dokumentationsverktygen behöver inget konto.
|
||||
3. **Första riktiga frågan öppnar inloggningen.** Fråga något om bokföringen, till exempel *"Vilket bolag är jag ansluten till?"*. Servern svarar att inloggning krävs, och claude.ai öppnar Accounteds inloggning (BankID eller e-post + 2FA) följd av godkännandesidan. Den visar bolaget som just nu är aktivt i appen (byt bolag i appen först om du har flera) med alla behörigheter förvalda; fäll ut **Behörigheter** och välj **Endast läs** för en läsande anslutning. Godkänn och **ställ frågan igen**: frågan som väntade när inloggningen öppnades görs inte om av sig själv. Statusen "ansluten" med en obesvarad första fråga betyder "logga in och fråga igen", inte att anslutningen är trasig.
|
||||
4. **Klart.** Härifrån går varje fråga mot det bolaget, och skrivningar stannar under **/pending** tills du bekräftar.
|
||||
1. **Connector-dialogen.** claude.ai öppnar **Add custom connector** med namn och adress ifyllda. Kontrollera adressen och gå vidare: dialogen känner av att servern kräver inloggning (**Always required**) och att Claude kan registrera sig själv automatiskt. Behåll de valen och klicka **Add**. Claude Desktop visar samma dialog under Inställningar → Connectors.
|
||||
2. **Inloggningen öppnas.** claude.ai ber dig ansluta och öppnar Accounteds inloggning (BankID eller e-post + 2FA) följd av godkännandesidan. Den visar bolaget som just nu är aktivt i appen (byt bolag i appen först om du har flera) med alla behörigheter förvalda; fäll ut **Behörigheter** och välj **Endast läs** för en läsande anslutning. Godkänn, så visas anslutningen som ansluten med Accounteds verktyg listade.
|
||||
3. **Ställ din första fråga.** Till exempel *"Vilket bolag är jag ansluten till?"*. Härifrån går varje fråga mot det bolaget, och skrivningar stannar under **/pending** tills du bekräftar.
|
||||
|
||||
Inloggad, men Claude säger fortfarande att servern inte går att nå? Fråga igen i samma chatt först. Hjälper inte det: öppna Inställningar → Connectors, ta bort anslutningen och lägg till den igen med autentisering satt till "Required when the server asks".
|
||||
Inloggad, men Claude säger fortfarande att servern inte går att nå? Fråga igen i samma chatt först. Hjälper inte det: öppna Inställningar → Connectors, ta bort anslutningen och lägg till den igen via länken ovan, med autentisering kvar på **Always required**.
|
||||
|
||||
#### Lägga till manuellt i stället
|
||||
|
||||
I **claude.ai** (Inställningar → Connectors) eller **Claude Desktop** (Inställningar → Connectors → Add custom connector), välj **Add custom connector** och klistra in:
|
||||
|
||||
\`\`\`
|
||||
https://app.accounted.se/api/extensions/ext/mcp-server/mcp?tool_namespace=accounted&client=claude-connector
|
||||
https://app.accounted.se/api/extensions/ext/mcp-server/mcp?tool_namespace=accounted&client=claude-connector&auth=required
|
||||
\`\`\`
|
||||
|
||||
Behåll \`tool_namespace=accounted\`: den väljer verktygsnamnen som guiden utgår från. \`client=claude-connector\` är bara statistik. Frågar dialogen om autentisering, välj **"Required when the server asks"**, inte det automatiskt föreslagna "None".
|
||||
Behåll alla tre parametrarna. \`tool_namespace=accounted\` väljer verktygsnamnen som guiden utgår från. \`auth=required\` gör att dialogen känner av inloggningen (**Always required**): utan den accepterar servern en anonym handskakning, dialogen föreslår **None**, och en anslutning som läggs till med det förvalet öppnar aldrig inloggningen. Lägger du ändå till adressen utan parametern, välj **Required when the server asks** själv. \`client=claude-connector\` är bara statistik.
|
||||
|
||||
## Väg B: Claude Code (plugin)
|
||||
|
||||
|
||||
@@ -14,11 +14,11 @@ There are three ways to connect, depending on your client. All three reach the s
|
||||
|
||||
## Path A: claude.ai or Claude Desktop (one click)
|
||||
|
||||
**[→ Connect Accounted to Claude](https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=Accounted&connectorUrl=https%3A%2F%2Fapp.accounted.se%2Fapi%2Fextensions%2Fext%2Fmcp-server%2Fmcp%3Ftool_namespace%3Daccounted%26client%3Dclaude-connector)**
|
||||
**[→ Connect Accounted to Claude](https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=Accounted&connectorUrl=https%3A%2F%2Fapp.accounted.se%2Fapi%2Fextensions%2Fext%2Fmcp-server%2Fmcp%3Ftool_namespace%3Daccounted%26client%3Dclaude-connector%26auth%3Drequired)**
|
||||
|
||||
The link opens claude.ai with the connector name and URL already filled in. You review the values and confirm; the link only prefills the dialog, it grants nothing on its own. No API key to manage.
|
||||
|
||||
**You do not need an Accounted account yet.** The connector works as soon as it is added: the server answers the handshake and the documentation tools without credentials, and the first company-scoped call opens the Accounted sign-in, where a new user creates the account (BankID or e-mail + 2FA).
|
||||
**You do not need an Accounted account yet.** Adding the connector opens the Accounted sign-in straight away, and a new user creates the account right there (BankID or e-mail + 2FA).
|
||||
|
||||
**All permissions pre-selected, every write still staged.** The consent page grants the full scope set with one click. Expand **Behörigheter** and choose **Endast läs** to connect read-only (list invoices, read reports, compute VAT): a reviewer can do that while you keep a write-enabled connection for daily work. Whatever the scopes, write tools (create invoice, categorise, book vouchers, run year-end) only stage a pending operation that you confirm before anything is booked, and the grant can be revoked under Settings → API & MCP.
|
||||
|
||||
@@ -26,22 +26,21 @@ The link opens claude.ai with the connector name and URL already filled in. You
|
||||
|
||||
The rest of the setup happens on Claude's side, in this order:
|
||||
|
||||
1. **The connector dialog.** claude.ai opens **Add custom connector** with the name and URL filled in. Check the URL and click **Add**. If the dialog asks about authentication, choose **"Required when the server asks"**, not the auto-detected "None": the server does not demand a login at connect time, so "None" looks right but blocks the sign-in in step 3. Claude Desktop shows the same dialog under Settings → Connectors.
|
||||
2. **The tools appear straight away.** The connector shows as connected and Claude lists the Accounted tools before you have signed in. That is by design: the handshake and the documentation tools need no account.
|
||||
3. **The first real question opens the sign-in.** Ask something about your books, for example *"Which company am I connected to?"*. The server answers that a login is required, and claude.ai opens the Accounted sign-in (BankID or e-mail + 2FA), followed by the consent page. It shows the company that is currently active in the app (switch company in the app first if you have several) with every permission pre-selected; expand **Behörigheter** and choose **Endast läs** for a read-only connection. Approve, then **ask the question again**: the question that was waiting when the sign-in opened is not retried on its own. A "connected" status with an unanswered first question means "sign in, then ask again", not a broken connection.
|
||||
4. **Done.** From here every question runs against that company; writes stage at **/pending** until you confirm.
|
||||
1. **The connector dialog.** claude.ai opens **Add custom connector** with the name and URL filled in. Check the URL and continue: the dialog detects that the server requires a sign-in (**Always required**) and that Claude can register itself automatically. Keep those and click **Add**. Claude Desktop shows the same dialog under Settings → Connectors.
|
||||
2. **The sign-in opens.** claude.ai asks you to connect and opens the Accounted sign-in (BankID or e-mail + 2FA), followed by the consent page. It shows the company that is currently active in the app (switch company in the app first if you have several) with every permission pre-selected; expand **Behörigheter** and choose **Endast läs** for a read-only connection. Approve, and the connector shows as connected with the Accounted tools listed.
|
||||
3. **Ask your first question.** For example *"Which company am I connected to?"*. From here every question runs against that company; writes stage at **/pending** until you confirm.
|
||||
|
||||
Signed in, but Claude still says it cannot reach the server? Ask again in the same chat first. If that does not help, open Settings → Connectors, remove the connector, and add it again with authentication set to "Required when the server asks".
|
||||
Signed in, but Claude still says it cannot reach the server? Ask again in the same chat first. If that does not help, open Settings → Connectors, remove the connector, and add it again from the link above, with authentication left on **Always required**.
|
||||
|
||||
#### Adding it by hand instead
|
||||
|
||||
In **claude.ai** (Settings → Connectors) or **Claude Desktop** (Settings → Connectors → Add custom connector), choose **Add custom connector** and paste:
|
||||
|
||||
\`\`\`
|
||||
https://app.accounted.se/api/extensions/ext/mcp-server/mcp?tool_namespace=accounted&client=claude-connector
|
||||
https://app.accounted.se/api/extensions/ext/mcp-server/mcp?tool_namespace=accounted&client=claude-connector&auth=required
|
||||
\`\`\`
|
||||
|
||||
Keep \`tool_namespace=accounted\`: it selects the tool names this guide uses. \`client=claude-connector\` is telemetry-only. If the dialog asks about authentication, choose **"Required when the server asks"**, not the auto-detected "None".
|
||||
Keep all three parameters. \`tool_namespace=accounted\` selects the tool names this guide uses. \`auth=required\` makes the dialog detect the sign-in (**Always required**): without it the server accepts an anonymous handshake, the dialog suggests **None**, and a connector added with that default never opens the sign-in. If you do add the bare URL, choose **Required when the server asks** by hand. \`client=claude-connector\` is telemetry-only.
|
||||
|
||||
## Path B: Claude Code (plugin)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user