---
title: Sign-in and connected apps
description: How an AI app signs in to the Qaf MCP server with your Qaf account, how to disconnect it, and the OAuth details for client developers.
---

An app connects to the Qaf MCP server with your Qaf account, not with an API key. When you add the server, the app opens a Qaf page in your browser where you sign in and choose whether to allow it.

## What you allow

The consent page names the app and the account you're signed in with. If you allow it, the app can:

- search and read the Qaf library on your behalf;
- see your name and email address;
- stay connected, so you don't sign in every time.

The app can't read your conversations on qaf.ai, change your account or see your plan. Only allow apps you added yourself.

## How long an app stays connected

The app gets an access token that lasts one hour and renews it while you use it. After 30 days without use, the app asks you to sign in again.

## Disconnect an app

Disconnect an app from your connected apps in your Qaf account settings. It loses access right away, even with a token it already holds. To use it again, connect it from the app.

## When an account can't connect

The server checks your account on every request. It refuses:

- **a guest session:** sign in to qaf.ai with an account first;
- **an account waiting to be deleted:** requesting deletion also disconnects every app;
- **a suspended account:** while the suspension lasts.

A refused request gets `403` with the message `This Qaf account does not have access to the MCP server.` Signing in again with the same account doesn't change the answer.

## For client developers

The server follows the MCP authorization spec. A client that supports it needs no Qaf-specific code.

| Detail | Value |
| --- | --- |
| Server URL and token audience | `https://api.qaf.ai/mcp` |
| Protected resource metadata | `https://api.qaf.ai/.well-known/oauth-protected-resource/mcp`, named in the `WWW-Authenticate` header of a 401 |
| Authorization server metadata | `https://api.qaf.ai/.well-known/oauth-authorization-server` (also at `/.well-known/openid-configuration`). The issuer is `https://api.qaf.ai`. |
| Client registration | Dynamic client registration at `https://api.qaf.ai/auth/oauth2/register`, as a public client without a secret |
| Grant | Authorization code with PKCE (`S256`), and refresh tokens |
| Scopes | `openid`, `profile`, `email`, `offline_access`. The server adds `offline_access` and the `resource` parameter when a client leaves them out. |
| Tokens | A one-hour RS256 JWT access token for the resource above, and a 30-day refresh token. DPoP-bound tokens are supported. |
| Transport | Stateless Streamable HTTP, `POST` only. `GET` and `DELETE` get `405`. |
| Protocol revisions | `2026-07-28` and the 2025 revisions. A 2025 client gets an SSE response; a `2026-07-28` client gets one JSON body. |
| Rate limit | 60 requests a minute per account, counting every JSON-RPC message, such as `initialize` and `tools/list`. Over the limit: `429` with `Retry-After` in seconds. |
| Request size | 256 KiB per request. Larger bodies get `413`. |
| Batches | Not supported. A JSON-RPC batch gets `400`. |
| Browser requests | A request with an `Origin` header from a site Qaf doesn't serve gets `403`. Clients that run on a server send no `Origin` and aren't affected. |

Token errors come back as `401` with `WWW-Authenticate: Bearer error="invalid_token"` and a description, such as `The access token expired`. A client that gets one should refresh its token or send the user through sign-in again.
