| Status | Proposed |
| Date | 2026-10-07 |
| Issue | https://github.com/baserow/baserow/issues/6260 |
| Author | Al Amin (@alamin-br) |
| Contributors | Davide Silvestri (@silvestrid) |
AI apps (MCP clients) connect to Baserow with a secret key in the URL. The key leaks, can’t be limited to some tools, and ChatGPT and Claude’s connector directory don’t accept it. Baserow will run its own OAuth server as the MCP spec defines, so users sign in from the app and choose which workspaces and tools it can use.
Today a user creates an MCP endpoint for one workspace in their settings and pastes its URL into the app. The URL holds a secret key that gives the app its owner’s full permissions in that workspace, with no way to limit it to some tools. The endpoint uses SSE, a transport the MCP spec has deprecated.
This has to change because:
The goal is sign-in that works with the major AI apps, on SaaS and self-hosted instances, without an external identity provider or per-app setup.
In scope: how apps identify themselves, sign users in and get limited access, and what happens to existing endpoint keys. Out of scope: OAuth for the REST API or other integrations, which tools exist, and Baserow connecting to other MCP servers.
| Term | Meaning |
|---|---|
| App | An AI app that uses Baserow’s tools over MCP, such as Claude, ChatGPT or Cursor. |
| Endpoint key | The secret in today’s MCP endpoint URL. Not a database token. |
| CIMD | Client ID Metadata Document: the app’s ID is a URL to a document describing it, which Baserow fetches. |
| DCR | Dynamic Client Registration: the app registers itself with Baserow on first use and gets an ID back. |
| Connection | One app approved by one user, with the workspaces and tools they picked. Disconnecting ends it. |
| Streamable HTTP | The MCP transport that replaces SSE. |
Baserow runs its own OAuth server in core, built on django-oauth-toolkit, so neither SaaS nor self-hosted instances need an external identity provider.
The MCP spec prefers CIMD and has deprecated DCR, but Cursor, Gemini CLI and other major apps still only support DCR, so Baserow accepts both.
Every app connects to one shared URL that carries no credentials. It uses Streamable HTTP, which replaces the deprecated SSE transport.
Sign-in uses the normal Baserow login, so SSO and 2FA apply. A consent page shows which app is asking, warns when its identity can’t be verified, and lets the user pick which workspaces and tools it gets.
A connection acts only as its user, within the chosen workspaces and tools. Every call checks again that the user is still active and still a member of the workspace. Tools the user didn’t pick are blocked, not just hidden.
A connection lasts until the user disconnects the app, which takes effect immediately, or until it goes unused for 30 days. Connecting and disconnecting are recorded in the audit log.
Scripts and apps that can’t use OAuth keep their endpoint keys, sent in a request header instead of the URL, with the tools they have today. URLs with a key in them keep working until almost nobody uses them.
| Option | Why not |
|---|---|
| Keep the key in the URL | It leaks, can’t be limited, and ChatGPT and the app directories don’t accept it. |
| API keys in the header only | ChatGPT can’t send them, and users get no consent step. Kept for scripts. |
| External identity provider (Auth0, WorkOS) | Every self-hosted instance would need its own account with the provider, and core would depend on a third party. |
| Separate OAuth service (Keycloak, Ory Hydra) | Every install would run and secure another service in its stack. |
| Authlib instead of django-oauth-toolkit | No MCP authorization support, while django-oauth-toolkit added it in 3.4.0. |
| CIMD only | Cursor, Gemini CLI and other major apps can’t sign in. |
| DCR only | Deprecated by the spec, and needs an open registration endpoint. |
| Client IDs set up by an admin | Users would copy a client ID into each app, and some apps have nowhere to put it. |