Connections and SDK Integrations
KDCube separates provider mechanics from product policy. Reusable SDK integrations handle OAuth/OIDC, normalized provider calls, claim checks, retries, file hosting, and consent responses. Your app decides which tools and services it offers, which conversations receive external events, and which product surfaces expose those capabilities.
The central user-facing model is a connected account: an external account that a platform user delegates to KDCube so apps and tools can act through that provider on the user's behalf. Agents never receive raw provider tokens. Trusted SDK resolvers load the current user's credential server-side and enforce the claims required by the attempted operation.
MCP 2026-07-28
KDCube's managed MCP endpoint implements the tested MCP 2026-07-28 stateless tool wire and retains the legacy 2025-11-25 initialize/discovery path for earlier clients. The protocol does not supply application authorization: KDCube re-checks server-side grant records on every concrete call. Gate one asks whether this caller holds the required KDCube resource and operation grant. Gate two resolves the selected provider account and its per-account caller binding. No provider token reaches an agent or generated code.
A hosted agent has deterministic delegated-client identity kdcube-agent:<application>:<agent_id>. Its grants are deduplicated by grantor, agent client, and resource set in Connection Hub's Delegated by KDCube registry, are reused each turn through the connections named service, and are revocable independently of sibling agents. External OAuth clients and manual automation bearers use separate issuance paths over the same descriptor-backed resource catalog.
What's included
- Provide or consume MCP: expose async app-native tools, connect hosted agents over stdio, HTTP or Streamable HTTP, and SSE, or use both directions independently.
- Modern and legacy tool clients: tested
server/discover,tools/list, andtools/callbehavior with cache/result hints and automatic fallback to legacy initialization. - Three authorization owners: deliberately public, app-owned, or Connection Hub managed endpoints, with descriptor pre-registration, Client ID Metadata Documents, and configurable DCR compatibility.
- Exact live authority: per-agent tool views, grants scoped to resources, operations, claims, and selected accounts, plus atomic OAuth state, refresh, revocation, and reauthorization on every call.
- Credentials and browser mutations protected: provider credentials remain server-side; managed denials are actionable; selected cookie-authenticated operation POSTs can opt into single-use CSRF proof.
- Production app capabilities around the wire: bounded structured results, paging, files and download URLs, optional named-service realms, app-configured economics and rate policy, Git lifecycle, and stateless scale-out.
The end-to-end walkthrough is Delegated MCP End to End; the full configuration chain is the recipe.
Connected Accounts and Mail
A connected account has three layers: the provider defines OAuth/OIDC endpoints, profile mapping, and external scopes; an administrator configures a connector app with client secrets and an allowed KDCube-claim ceiling; the user creates a connected account with provider identity, approved claims, credential health, and a credential reference.
Claims, not raw tokens
The mail namespace door uses named_services:use plus operation claims such as mail:read or mail:send. The selected Google account is checked separately for provider claims such as gmail:read or gmail:send. A provider claim is not a platform role and is not copied into an MCP bearer.
Provider-neutral mail
The named-service namespace is mail, not Gmail. Gmail is the first provider behind a contract that can also serve iCloud, Yahoo, IMAP, or another mailbox. Provider credentials remain server-side.
Files by transport
In chat, mail actions use trusted workspace attachment_paths; result files arrive as chat.files object-ref cards and resolve on click under the user session. Without a workspace, callers stage bytes and pass staged_ref. A turn-less MCP client retains its URL result contract. File bytes and signed URLs never travel through the model's prose.
Gmail tools support search, read, attachment download, send, and forward. At attempt time, a missing or insufficient account returns the managed needs_connected_account_consent envelope with an absolute Connection Hub link and a precise reason. The user can grant the requested claims or turn off the tools asking for them.
Reference: Mail named-service recipe.
Slack and Telegram
Slack is both a connected-account provider and a slack named-service namespace. Telegram is a channel transport whose verified external subject is linked to a KDCube platform identity before a turn is submitted.
Slack tools and namespace
Search, list channels, read history, download/upload files, post messages, and inspect assistant-search support. A user may connect multiple workspaces; every account has its own team metadata, claims, and credential reference.
Slack authorization is operation-specific
The named-services door requires named_services:use plus the real operation claim, such as slack:search, slack:history, slack:files:write, or slack:post. The provider account must hold that same capability, and a hosted agent must also be bound to use it on the selected account. There is no synthetic slack:read/slack:write umbrella at this boundary.
Telegram identity linking
A public webhook starts with an anonymous KDCube session. The app resolves the verified Telegram subject through a stored Connection Hub delegation edge, constructs delegated platform authority, then submits external_events[] through ChatIngressSubmitter.
Slack assistant search is workspace-dependent; callers should inspect assistant_search_info before relying on it. If an MCP client has a Slack namespace grant but the user has no matching account, the provider returns the standard connect/consent response rather than silently retrying.
References: Slack integration and Telegram webhook journey.
Google Sheets and Google Docs
The Google connection also backs first-class sheets and docs named-service realms. Sheets supports discovery, read/materialization, value updates, row append, range clearing, spreadsheet/tab management, formatting, and deletion under sheets:read/sheets:write. Docs supports search, read/export, creation, copy/import, typed edits, image embedding, and comment workflows under separate docs:read, docs:write, and docs:comment claims.
Stable refs such as sheets:google:<account_id>:spreadsheet:<id> and docs:google:<account_id>:document:<id> preserve provider ownership while the shared resolver and workspace materialize authorized snapshots. Each concrete operation still passes the same delegated-resource, provider-capability, and per-account binding checks.
Reference: Google connected services.
Custom OAuth/OIDC and Other Providers
Normal OAuth 2.0 and OpenID Connect services can use the generic oauth2.generic or oidc.generic adapters. Configure provider endpoints and profile mapping, register a connector app with secret references and allowed KDCube claims, then let users connect concrete accounts. Providers with unusual mechanics still need a provider-specific adapter.
Storage boundary
Connected-account metadata lives in ConnectionStore app-filesystem state, but raw provider tokens live in user-scoped secrets. Delegated OAuth and manual automation grant/session records use Redis GrantStore state. Deployment client, verifier, bot, and signing secrets live in the configured secrets provider. “Connection token” is not one storage family.
Runtime resolution
Tool code calls resolve_connected_account_claim(...) instead of reading account files or secrets. If a provider rejects a token, run_with_connected_account_retry(...) can refresh once and retry under the same user identity.
Other provider adapters
Provider-specific integrations such as Gmail, Slack, iCloud, LinkedIn, and Telegram remain available when their protocol or product semantics need dedicated handling.
Manual Delegated by KDCube access tokens are shown once; later listings expose metadata and last_four, not the raw bearer. Claude Code or another external MCP client's delegated OAuth token is not stored in ConnectionStore. accounts.json contains connected-account metadata only, and neither bundles.yaml nor bundles.secrets.yaml owns a user's connected-provider token.
Reference: Connect a custom OAuth/OIDC service.
Runtime Pattern
concrete tool or named-service operation is attempted
-> gate 1: caller's KDCube resource + exact operation grant
missing -> delegated_consent_required
-> gate 2a: selected provider account holds the provider claim
missing -> connect_required | claim_upgrade_required | reconnect_required
-> gate 2b: this caller is bound to that claim on that account
missing -> agent_grant_required
-> trusted adapter resolves the server-side credential and calls provider
-> stale provider token? refresh once and retry through SDK policy
Consent is demand-driven: the attempted operation is the ask. Catalog visibility does not authorize the call and missing connected-account consent does not remove the tool at turn start. In a chat turn, caller-side middleware emits the scoped consent event because the provider app may have no chat lane. A successful grant authors connections.consent.granted into that conversation so the live turn can fold the transition. Conversation-less MCP calls return the structured denial but create no conversation event.
Provider capability is resolved before per-agent account binding, so the UI sends the user to Delegated to KDCube for OAuth/connect or claim upgrade, then offers “Continue → grant to <agent>” for the KDCube binding under Delegated by KDCube. Sequential demand approvals merge into the existing resource grant; an explicit Connection Hub edit may narrow or replace it.