# MCP and agent connections

OAuth-authenticated agents use the existing Worker and the shared tool catalog.

## Connection flow [#connection-flow]

The MCP resource is `/api/mcp`. Better Auth provides OAuth 2.1, PKCE S256 and dynamic client registration. Protected-resource and authorization-server metadata live at the well-known endpoints; JWKS is `/api/auth/jwks`. Read the [connection guide](/docs/connect-your-agent) for client commands and supported scopes.

An unauthenticated request receives a Bearer challenge. `data:read` is required; `data:write` permits requesting writes, each still subject to exact User approval. Read-only grants do not see write tools. Revoking a connection rejects later access even before its JWT expires.

## Scope and approval [#scope-and-approval]

MCP is pinned to the User's personal Organization because an OAuth token does not carry the app's Active Organization. Tools check current membership. Writes return an approval request and an Integrations link. Requests expire after 15 minutes, with at most 20 unexpired pending records per User.

Legacy draft tools create inert proposals. Approving proposal creation does not apply its domain changes; the separate Apply step remains. Replaying an executed approval returns the stored result.

## Resources and widgets [#resources-and-widgets]

The server adapts the same 15-tool catalog as the [assistant](/docs/features/assistant), subject to OAuth scope filtering. It exposes authorized Todo resources and planning prompts. Todo tool results can advertise both MCP Apps and OpenAI widget resources; hosts without iframe support still receive JSON. Public demo posts/profiles are separate static content, not private domain records.

`template://organization/documents/{fileId}` returns the first bounded JSON page of converted text. Continue through `document_read` with `nextCursor`. The `plan-from-document` prompt reads relevant pages and calls `draft_task_plan`; creating that proposal needs approval and its separate Apply step creates Todos. Document resources use the same membership and read-scope checks as tools. Files uploaded by external clients still need [browser text preparation](/docs/features/documents) before document tools can read them.

## Extend [#extend]

Add shared operations in the catalog, retain scope filtering and the in-process JWKS lookup, and use the server builder per connection. A Worker HTTP self-fetch for JWKS is not equivalent. Verify protocol errors, revoked tokens, insufficient scope and approval binding. Do not advertise an experimental MCP server-card endpoint as a stable discovery requirement.


## Key files [#key-files]

- [`packages/api/src/mcp/server.ts`](https://github.com/CarlosZiegler/doro/blob/main/packages/api/src/mcp/server.ts)
- [`packages/api/src/mcp/guard.ts`](https://github.com/CarlosZiegler/doro/blob/main/packages/api/src/mcp/guard.ts)
- [`packages/api/src/mcp/context.ts`](https://github.com/CarlosZiegler/doro/blob/main/packages/api/src/mcp/context.ts)
- [`packages/auth/src/mcp-oauth.ts`](https://github.com/CarlosZiegler/doro/blob/main/packages/auth/src/mcp-oauth.ts)
- [`apps/web/src/routes/api/mcp.ts`](https://github.com/CarlosZiegler/doro/blob/main/apps/web/src/routes/api/mcp.ts)

