From 84d540d01ca858c8cefe52af008154006042704d Mon Sep 17 00:00:00 2001 From: Miguel Amigot Date: Fri, 17 Jul 2026 20:26:36 -0400 Subject: [PATCH] docs(iblai-agent-mcp): add connector model, resolution order, in-chat OAuth Augment the MCP agent skill with conceptual/behavioral coverage from the ibl.ai /developer MCP docs that was missing or thinner in the skill: - Connector model: server / connection / connected-service relationship - auth_type vs auth_scope orthogonality (how vs whose credentials) - Runtime credential resolution order (user > mentor > tenant > featured > fail) - In-chat OAuth events for per-user oauth2 connectors (oauth_required / oauth_connection_resolved / warning / error, poll & timeout) - is_featured cross-org semantics and automatic OAuth token refresh Source: docs-content/developer/agents/mcp-authentication/{architecture, mcp-connections,oauth-connectors,in-chat-mcp-events}.md Co-Authored-By: Claude Opus 4.8 --- skills/iblai-agent-mcp/SKILL.md | 59 +++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/skills/iblai-agent-mcp/SKILL.md b/skills/iblai-agent-mcp/SKILL.md index a0b2c5d..314ad0e 100644 --- a/skills/iblai-agent-mcp/SKILL.md +++ b/skills/iblai-agent-mcp/SKILL.md @@ -83,6 +83,65 @@ curl -X POST \ }' ``` +## Connector model + +Three objects work together: + +- **MCP server** (`mcp-servers/`) — the connector record: `name`, `url`, + `transport` (`sse|websocket|streamable_http`), `auth_type` + (`none|token|oauth2`), and `auth_scope` (`user|mentor|tenant`). + `is_featured=true` lets admins in *other* orgs create their own connections to + the same server; disabled connectors are skipped at runtime. +- **MCP server connection** (`mcp-server-connections/`) — the auth binding that + supplies credentials for a server at a given `scope`. OAuth2 connections + reference a `connected_service`. +- **Connected service** (`connected-services/…`) — a user's stored OAuth grant + for a provider + service (e.g. `google` + `drive`), created by completing the + OAuth flow. One per user per service. + +`auth_type` and `auth_scope` answer two different questions: `auth_type` is +*how* the call is authenticated (`none`, a static `token`, or `oauth2`); +`auth_scope`/`scope` is *whose* credentials are used (`user`, `mentor`, or +`tenant`). Only `auth_type=oauth2` **and** `auth_scope=user` together trigger the +in-chat OAuth prompt below. + +## Runtime credential resolution + +When an agent calls an attached MCP server, the platform selects credentials in +priority order — first match wins: + +1. **user**-scoped connection for (server, current user) +2. **mentor**-scoped connection for (server, agent) +3. **tenant**-scoped connection for (server, org) +4. featured-server global fallback +5. otherwise fail (401 / no connection) — or, for a per-user oauth2 server with + no user connection, start the in-chat OAuth flow + +OAuth access tokens are refreshed automatically as they near expiry — no client +action required. + +## In-chat OAuth (per-user oauth2 connectors) + +A connector with `auth_type=oauth2` + `auth_scope=user` authenticates each user +individually. When an authenticated user chats with the agent and has no +connection yet, the chat pauses and the runtime emits JSON events on the +existing chat socket (WebSocket/SSE) — switch on the `type` field: + +- `oauth_required` — carries `server_name`, `server_id`, and `auth_url`; open + `auth_url` in a new tab/popup (providers block iframes) so the user can + authenticate. Backend then polls for the new connection. +- `oauth_connection_resolved` — the connection was created; dismiss the prompt, + the chat resumes automatically. +- `warning` (`code` 503) — MCP tools couldn't load for a non-OAuth reason + (server unreachable / misconfigured); chat continues without those tools. +- `error` (`status_code` 400) — OAuth timed out (default ~5 min), the auth URL + couldn't be built (missing `auth_{provider}` credential), or the connection + has no valid connected service; the user retries the message. + +The backend polls every ~10s and times out after ~300s. Completing OAuth *after* +a timeout still works — the next message succeeds because the connection now +exists. + ## Notes - The connector list is paged (`page_size=12`); use `search` and `transport` to