index 9813d0d..126f75d 100644
@@ -169,6 +169,49 @@ For stdio, run `WIKIHUB_API_KEY=wh_… node dist/index.js` and it'll stream MCP
---
+## Authentication model (explicit)
+
+**The WikiHub MCP server uses plain API-key auth. It does NOT use OAuth or
+client IDs.** This is a deliberate design choice — here's what that means:
+
+### What the server accepts
+
+| Auth path | Where you put the `wh_…` key | Works in |
+| --------------------------------- | ------------------------------------------------ | --------------------- |
+| `Authorization: Bearer <key>` | Client's custom-header field | Claude Code (HTTP), ChatGPT DR, curl |
+| `x-api-key: <key>` | Client's custom-header field | Any client that lets you set arbitrary headers |
+| `?key=<key>` query param in URL | Appended to the connector URL | Claude Desktop custom-connector UI (fallback for builds that only show OAuth fields) |
+| `WIKIHUB_API_KEY` env | Shell / systemd / launch config | stdio transport (local) |
+
+Precedence (first match wins): Bearer → `x-api-key` → `?key=` → env.
+
+### What the server does NOT do
+
+- **No OAuth 2.0 flow.** There is no authorization_endpoint, no token exchange, no refresh token dance.
+- **No client ID / client secret.** You don't register your app ahead of time.
+- **No OpenID Connect / OIDC.** The user is identified solely by which `wh_…` key they present.
+- **No OAuth discovery endpoints.** `/.well-known/oauth-authorization-server`, `/.well-known/oauth-protected-resource`, and `/.well-known/openid-configuration` all return `404`. If a client tries OAuth-first discovery, it will fail over to the custom-header / query-param path.
+
+### Why no OAuth
+
+- **One-shot agent onboarding is a core WikiHub principle** (see `AGENTS.md §1`). `POST /api/v1/accounts` returns an immediately-usable `api_key` with no email step, no browser, no consent screen. OAuth would reintroduce all three.
+- **Keys are per-user, labeled, and revocable.** You can mint one key per agent (`POST /api/v1/keys {"label":"claude-connector"}`) and revoke in isolation — fine-grained enough for the current trust model without OAuth scoping.
+- **Every major MCP client already speaks Bearer.** Claude Code's `--header`, ChatGPT Deep Research's custom-header field, and stdio env vars all carry a raw key just fine.
+- **The one client UI that can't paste headers — older Claude Desktop builds — is handled by the `?key=` query-param fallback.** That's a pragmatic tradeoff (URL-visibility risk in exchange for zero-friction install) and keys are revocable if leaked.
+
+### When OAuth would be worth adding
+
+OAuth becomes the right tool when:
+
+1. You want **third-party apps** (not just the user's own agent) to request scoped access without the user pasting a key.
+2. You want to publish the connector in Anthropic's or OpenAI's curated connector directory — some directories require OAuth for discoverability.
+3. You want **per-session scopes** (e.g. "read-only", "one specific wiki", short-lived tokens).
+4. You want a **browser consent screen** for UX reasons — users who don't know what a Bearer token is.
+
+None of that is required for the current "bring your own agent" flow. If we hit one of these use cases later, the upgrade path is additive: keep the `wh_…` Bearer path for backward compat, bolt on an OAuth server that issues short-lived access tokens.
+
+---
+
## Env vars
| Var | Default | Notes |