# auth.md

> How agents and integrations authenticate against GymStack's MCP server.
> Endpoint: `POST https://gymstack.de/mcp` (stable alias, Streamable HTTP) —
> origin server: `https://intent-finch-948.eu-west-1.convex.site/mcp`.
> Human docs (German): https://gymstack.de/mcp/ · Markdown: https://gymstack.de/mcp/index.md

## OAuth (claude.ai / ChatGPT connectors)

- Add the endpoint above as a custom connector. Discovery per RFC 9728:
  https://intent-finch-948.eu-west-1.convex.site/.well-known/oauth-protected-resource
- Authorization server: Clerk (dynamic client registration supported). The gym
  operator signs in and confirms their studio; no key required.
- Scopes: `mcp:read`, `mcp:propose`.

## API key (Claude Code, Cursor, n8n, Anthropic Messages API)

- A gym admin creates a key in the GymStack console under
  "Einstellungen → Integrationen (MCP)" (max. 10 per gym, plaintext shown once,
  scopes read/propose, revocable at any time).
- Header: `Authorization: Bearer gsk_<64 hex>`
- Claude Code:

```bash
claude mcp add gymstack --transport http https://intent-finch-948.eu-west-1.convex.site/mcp \
  --header "Authorization: Bearer gsk_…"
```

- Anthropic Messages API: `mcp_servers: [{ type: "url", url: "…/mcp", name: "gymstack", authorization_token: "gsk_…" }]`

## Security model

- Writes are never executed directly: every write becomes a proposal in the gym's
  human approval queue and only takes effect after explicit approval in the studio
  console. Read tools return data directly.
- Rate limits: 60 requests/min per key (HTTP 429), 30 proposals/hour.
- All access is audited per gym, including the key id for API-key access.

## Not supported

- There is no public signup for API access — keys are issued inside the product
  by gym admins. Demo/trial for gym operators: https://gymstack.de/termin/
- Password/cookie automation or scraping of the app UI.
