Composio Gap Resolution Policy
ADR-058 — Composio Gap Resolution Policy
Status: Accepted
Date: 2026-05-19
Author: Mishaal Murawala
Supersedes: none
Superseded by: —
INVARIANTS-UNCHANGED — this ADR does not add or modify any of the 15 V5 gateway invariants. It adds policy for Composio gap resolution above the invariant layer.
Context
Post-cutover (ADR-057, 2026-05-19), Composio is the canonical OAuth SaaS layer. Two recurring failure modes appear in agent sessions:
- Scope gaps — a Composio-managed OAuth connection exists but returns 403/401 because the OAuth app was granted insufficient scopes. Sessions repeatedly prompt the user to “add the missing scope” with no durable fix.
- Missing toolkits — a SaaS API Ascend needs isn’t in Composio’s catalog at all. Sessions either fall back to V5’s
call_apishim (violating the intent of the cutover) or halt and ask the user what to do.
Both failure modes require human intervention today. This ADR canonicalizes the two autonomous resolution paths so future sessions self-execute without prompting.
Docs-First Gate
Before implementing either path, fetch the relevant Composio documentation and verify the steps below still match current reality.
The API paths, request schemas, callback URIs, and auth flows in this ADR reflect Composio’s platform as of 2026-05-19. Composio ships platform changes without notice.
Minimum fetches before implementing Path 1:
https://composio.dev/docs/auth-configuration/custom-auth-configshttps://composio.dev/docs/programmatic-auth-configsMinimum fetches before implementing Path 2:
https://composio.dev/introduction/foundations/components/integrations/custom-integrationIf docs show a different API path, request schema, or auth flow than what is written below:
- Minor change (field renamed, version bump): update the affected step inline, add a
> Updated YYYY-MM-DD: <what changed>note directly in this ADR, and continue.- Substantial change (new auth model, new ingestion pipeline, Composio platform restructure): stop. Update this ADR fully before implementing. The steps are a template, not gospel.
- URL 404s: search
https://composio.devfor the current equivalent before assuming the feature no longer exists.Never implement Composio API calls from training data.
Decision
Two paths. Only two. Nothing else.
Path 1 — Scope gaps: BYO custom auth config
Fetch
composio.dev/docs/auth-configuration/custom-auth-configsandcomposio.dev/docs/programmatic-auth-configsbefore executing these steps. Verify the callback URI, endpoint path, and request body schema are current.
When a Composio-managed connection returns 403/scope errors:
- Register a dedicated OAuth app in the provider’s developer console with the required scopes. Redirect URI:
https://backend.composio.dev/api/v3.1/toolkits/auth/callback(verify against current docs — this URI is set by Composio, not by us, and changes with API versions). - Store
client_id+client_secretin Infisical atcomposio/oauth-apps/{provider}(project1c1907fa-ee74-4d52-ba1a-839fc71e855d, envprod). Never commit raw credentials. - Create a custom auth config in Composio. Verified 2026-05-19: The documented path is SDK-based —
composio.authConfigs.create({ toolkit, authConfig: { type: "use_custom_auth", credentials: { clientId, clientSecret, scopes: [...] } } }). The raw REST endpointPOST /api/v3/toolkits/{toolkit}/auth_configis NOT documented in current Composio v3 docs (may work, but cannot be relied upon). Use the SDK path.Updated 2026-05-19: Raw REST endpoint undocumented. Canonical path is
composio.authConfigs.create()(TypeScript SDK) orcomposio.auth_configs.create()(Python SDK). Dashboard “Add auth config” flow also confirmed working. Use SDK or dashboard; avoid undocumented REST. - Re-run the OAuth connect flow for affected user_ids.
- Smoke test one tool; confirm 200.
- Record in
docs/composio/auth-config-registry.md.
Path 2 — Missing toolkits: Session-only SDK custom toolkit + CF Worker escalation
Updated 2026-05-19 (substantial): The
integrations.yamlpersistent ingestion pipeline and dashboard “Start import” flow documented in this ADR’s original draft DO NOT EXIST in current Composio v3. Verification: fetchedhttps://docs.composio.dev/docs/toolkits/custom-tools-and-toolkits.mdon 2026-05-19 — custom toolkits are session-scoped only via the experimental SDK API. There is no persistent custom toolkit registration mechanism available via API or dashboard.The steps below reflect current reality. If Composio ships a persistent ingestion mechanism, fetch current docs and update this ADR before proceeding.
When a SaaS API isn’t in Composio’s catalog:
- Verify absence. Search
backend.composio.dev/api/v3/tools?search=<query>(try multiple keyword variants). Checkcomposio.dev/toolkitscatalog. If found, stop and use it. - Assess urgency and persistence need.
- If ≤14-day wait is acceptable: file a request on the Composio GitHub. Use session-only SDK custom toolkit for dev/testing in the interim (see step 3). Record in
docs/composio/toolkit-registry.mdwith statusPENDING-NATIVE. - If >14 days or persistent integration needed in production: proceed to step 4 (CF Worker).
- If ≤14-day wait is acceptable: file a request on the Composio GitHub. Use session-only SDK custom toolkit for dev/testing in the interim (see step 3). Record in
- Session-only fallback (dev/testing only — not for production use). Use the experimental SDK:
composio.experimental.Toolkit({ name, tools: [...], auth: {...} }). This creates a toolkit local to the current SDK session — not persisted in Composio, not available to other agents or n8n. Document which sessions use it. Do NOT ship code that depends on a session-only toolkit for production reliability. - Persistent path: dedicated CF Worker. When the toolkit must be reliably available across all sessions and agents, build a thin CF Worker that implements the provider’s API surface and exposes it as a Streamable HTTP MCP server. This Worker is owned by this repo, registered in
docs/composio/toolkit-registry.mdwith statusCF-WORKER, and deployed via the standard deploy pipeline. Open a tracking ADR for the new Worker. - Record in
docs/composio/toolkit-registry.mdwith current status and path taken.
Explicitly rejected alternatives
| Alternative | Rejection reason |
|---|---|
V5 unfreeze — reopen call_api shim for OAuth flows | ”We’re not going to bring V5 back and complicate the process.” V5 is a frozen fallback for AWS/LLM only. Adding SaaS OAuth to V5 would create a parallel auth surface that diverges from Composio over time. |
| Hardcode tokens in KV | Violates ADR-057 invariant #5: tokens:* KV is AWS+Anthropic only post-cutover. |
| New auth broker | No external auth brokers beyond Composio (invariant #5). Introducing a second broker adds operational surface for zero gain. |
| Wait for Composio to add native support | Acceptable as a time-bounded hedge (e.g., QBO — see LEDGER tech debt row) but not a default stance. If the wait exceeds 14 days and the tool is needed, proceed with Path 2. |
Code-side custom tools as production solution (composio.dev/docs/toolkits/custom-tools-and-toolkits) | Experimental, session-scoped only. Not appropriate for durable integrations. Acceptable as a dev/testing interim (Path 2 step 3) but must be replaced by a CF Worker (step 4) for production use. |
Implementation
Skills that encode these two paths as self-triggering runbooks:
.claude/skills/composio/scope-gap-resolver/SKILL.md(Path 1).claude/skills/composio/missing-toolkit-resolver/SKILL.md(Path 2)
These are delivered in the Window 1 PR per docs/plans/composio-autonomy.md.
Drift check #22 (scripts/checks/22-no-retired-names.ts) is extended in the same Window 1 PR to verify both skills and both registry docs exist — missing any = pre-commit fail.
Consequences
- Sessions encountering scope gaps or missing toolkits resolve autonomously via the relevant skill.
- No ad-hoc
call_apiworkarounds for OAuth-covered APIs. - Registry docs (
auth-config-registry.md,toolkit-registry.md) serve as the audit trail. - Future ADRs for novel auth flows (non-OAuth2, custom PKCE variants) reference this ADR as the baseline.
- Staleness responsibility: the session implementing a path owns verifying the steps against current Composio docs. If docs have drifted, update this ADR inline (minor) or via a new PR (substantial) — do not silently implement against stale steps.