Get anything the user connected
After SSO, you know what the user has connected (connections) and which assistants' memories they've imported (imports). This page shows the deterministic ways to read that data and act on it, so you ask the user only for what's missing, and use the rest.
Ask only for what's missing
The verify payload already tells you the state:
json
"connections": { "gmail": true, "calendar": false },
"imports": { "chatgpt": true, "claude": false }So if connections.gmail is already true, don't ask the user to connect Gmail again; Configure has it. Only prompt for what's false. To send the user a link for a missing one, call configure_connect (MCP) with the app; it returns a ready link and whether it's connected.
Get memories from a specific source (deterministic)
Every source the user has is an openable box. Reading one is the same shape every call:
jsonc
// MCP: configure_profile_read with a box id
{ "box": "imports/chatgpt" } // memories imported from ChatGPT
{ "box": "imports/claude" } // memories imported from Claude
{ "box": "agents/parry" } // what a specific agent has saved
{ "box": "work" } // a judged category of vouched factsWhere the box ids come from: category ids like work are listed in the verify payload's boxes. Import box ids are derived from the payload's imports map, imports/<provider> for each provider that is true. agents/<name> handles come from the sources list on a full profile read (GET /v1/profile or configure_profile_read); the verify payload does not include them.
For a point lookup instead of a whole box, use configure_profile_search with query set to the search text and source set to a box id, for example configure_profile_search { query: "writing style", source: "imports/chatgpt" }. Use imports/<provider> (or import:<provider>) for import-only results and agents/<name> for one agent's memories. A bare provider name (chatgpt, claude, gemini, grok, other) is not import-only: it matches both the agent shelf and the import shelf, and each result keeps its own source label.
The same reads work over REST with the Bearer you already hold, no MCP needed: GET /v1/profile?box=imports/chatgpt opens a box (add &page=2 for big boxes), and GET /v1/profile/search?query=writing+style&source=imports/chatgpt is the point lookup. The SDK mirrors both as profile.read({ box, page }) and profile.search({ query, source, box }).
If you call a connector tool for an app that is false, the call fails closed with a not-connected error. Call configure_connect with that app to mint the connect link, then surface it to the user. Only scope or permission failures (for example a missing send scope) return a minted link directly in the result.
Act on what's connected
Connection state becomes capability through the MCP. If the user connected Gmail or Calendar, your agent can:
configure_gmail_search: read their mailconfigure_calendar_get/configure_calendar_create_event: read and create eventsconfigure_drive_search,configure_notion_search: read files and notesconfigure_email_send: send on their behalf
Add the MCP to your agent (optional) so it always has the profile and can use these when it makes sense. On the Anthropic Messages API (beta header mcp-client-2025-11-20):
js
mcp_servers: [{ type: 'url', name: 'configure', url: 'https://mcp.configure.dev', authorization_token: userAccessToken }],
tools: [{ type: 'mcp_toolset', mcp_server_name: 'configure' }]Other MCP clients take an mcpServers config block instead; see MCP for per-runtime setup.
userAccessToken is the OAuth access token you already hold from sign-in, the same Bearer you send to /verify. Verify does not mint a new access token; the id_token it returns is a signed identity assertion for local verification, not an API credential. Keep using the Bearer you already hold.
SSO hands you the state; the MCP turns that state into action. That is the whole loop: one button gets you a signed identity plus everything the user chose to bring, and the agent uses it.