Files
familiar/doc/clients/claude-web.md
T
Latte df9e06a3e7
CI / lint (pull_request) Successful in 55s
docker / lint (pull_request) Successful in 56s
CI / test (pull_request) Successful in 1m6s
docker / test (pull_request) Successful in 1m4s
CI / publish (pull_request) Has been skipped
docker / docker (pull_request) Failing after 1m11s
docs: deployment guide + per-client setup + connect matrix
- doc/deployment.md: run familiar as a remote MCP server — secure defaults,
  bearer vs OAuth modes, the full env-var reference, one-time login / token-store
  provisioning, the published images, docker compose, and TLS reverse-proxy
  blocks for nginx (proxy_buffering off + long read timeout), Caddy, and Traefik.
- doc/clients/: one page per client with exact working steps — Claude Code,
  VS Code (.vscode/mcp.json with a masked token input, and the workspace
  .mcp.json header gotcha), Mistral Le Chat, Claude Desktop + Cowork (mcp-remote
  bridge, per-OS config paths), and Claude web (oauth mode + external IdP, with
  "use Desktop + bearer" as the simpler alternative). Plus a clients/ index.
- README: a "Connect a client" matrix (client -> auth -> guide) and a compact
  "Deploy with Docker" section linking to doc/deployment.md; oauth mode noted.
- doc/README.md index: rows for Deployment and Client setup.
- doc/getting-started.md: pointer from the HTTPS quickstart to the full docs.
- CLAUDE.md: FAMILIAR_AUTH_MODE / FAMILIAR_OAUTH_* / FAMILIAR_ALLOW_INSECURE_BIND
  and /healthz in the transport note; the split ci.yml / docker.yml workflows.

Deployment docs live under the existing doc/ tree (the repo uses doc/, not a
separate docs/) to keep a single documentation directory.
2026-07-04 19:26:33 +02:00

2.5 KiB

Connect Claude web (claude.ai)

Auth: OAuth 2.1 only. Prereq: familiar in oauth mode behind HTTPS, plus an external identity provider.

The claude.ai custom-connector flow speaks OAuth 2.1 with Dynamic Client Registration (DCR) and does not accept a static bearer token. familiar itself is only a resource server — it validates JWTs and advertises where to authenticate, but it is not an authorization server and does no DCR. So Claude web needs an external IdP that supports DCR (e.g. Authentik or Keycloak) sitting in front.

Simpler alternative: if you don't want to run an IdP, use the Claude Desktop app with a bearer token instead — see Connect Claude Desktop. Bearer is easier for every client except the claude.ai web connector.

1. Set up the IdP (external)

On your IdP, create an application/provider for familiar that:

  • issues JWT access tokens signed with a key published at a JWKS endpoint,
  • sets the token audience to familiar's public URL (the resource),
  • supports Dynamic Client Registration so claude.ai can register itself.

Note the issuer URL and (optionally) the JWKS URL.

2. Configure familiar in oauth mode

FAMILIAR_AUTH_MODE=oauth
FAMILIAR_OAUTH_ISSUER=https://idp.yourdomain.tld/application/o/familiar/
FAMILIAR_OAUTH_RESOURCE=https://familiar.yourdomain.tld
# FAMILIAR_OAUTH_AUDIENCE defaults to the resource URL; override if your IdP differs.
# FAMILIAR_OAUTH_JWKS_URI is discovered from the issuer's OIDC metadata if unset.

No FAMILIAR_HTTP_TOKEN is needed in oauth mode. familiar serves the discovery document at https://familiar.yourdomain.tld/.well-known/oauth-protected-resource/mcp, and unauthenticated MCP calls return 401 with a WWW-Authenticate: Bearer header pointing at your issuer.

3. Add the connector

In claude.ai: Settings → Connectors → Add custom connector, URL https://familiar.yourdomain.tld/mcp. Claude discovers your IdP from the metadata, registers via DCR, and runs the OAuth login. Approve familiar's scopes and you're connected.

Troubleshooting

  • "couldn't connect" immediately — familiar isn't in oauth mode, or FAMILIAR_OAUTH_RESOURCE/ISSUER are unset; the metadata endpoint must return 200.
  • Login loops / invalid token — audience mismatch: your IdP's token aud must equal FAMILIAR_OAUTH_RESOURCE (or your FAMILIAR_OAUTH_AUDIENCE).
  • DCR fails — the IdP doesn't have Dynamic Client Registration enabled; claude.ai requires it.