Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions skills/iblai-agent-mcp/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down