Skip to content

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:

  1. 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.
  2. Missing toolkits — a SaaS API Ascend needs isn’t in Composio’s catalog at all. Sessions either fall back to V5’s call_api shim (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-configs
  • https://composio.dev/docs/programmatic-auth-configs

Minimum fetches before implementing Path 2:

  • https://composio.dev/introduction/foundations/components/integrations/custom-integration

If 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.dev for 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-configs and composio.dev/docs/programmatic-auth-configs before executing these steps. Verify the callback URI, endpoint path, and request body schema are current.

When a Composio-managed connection returns 403/scope errors:

  1. 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).
  2. Store client_id + client_secret in Infisical at composio/oauth-apps/{provider} (project 1c1907fa-ee74-4d52-ba1a-839fc71e855d, env prod). Never commit raw credentials.
  3. 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 endpoint POST /api/v3/toolkits/{toolkit}/auth_config is 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) or composio.auth_configs.create() (Python SDK). Dashboard “Add auth config” flow also confirmed working. Use SDK or dashboard; avoid undocumented REST.

  4. Re-run the OAuth connect flow for affected user_ids.
  5. Smoke test one tool; confirm 200.
  6. 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.yaml persistent ingestion pipeline and dashboard “Start import” flow documented in this ADR’s original draft DO NOT EXIST in current Composio v3. Verification: fetched https://docs.composio.dev/docs/toolkits/custom-tools-and-toolkits.md on 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:

  1. Verify absence. Search backend.composio.dev/api/v3/tools?search=<query> (try multiple keyword variants). Check composio.dev/toolkits catalog. If found, stop and use it.
  2. 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.md with status PENDING-NATIVE.
    • If >14 days or persistent integration needed in production: proceed to step 4 (CF Worker).
  3. 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.
  4. 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.md with status CF-WORKER, and deployed via the standard deploy pipeline. Open a tracking ADR for the new Worker.
  5. Record in docs/composio/toolkit-registry.md with current status and path taken.

Explicitly rejected alternatives

AlternativeRejection 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 KVViolates ADR-057 invariant #5: tokens:* KV is AWS+Anthropic only post-cutover.
New auth brokerNo external auth brokers beyond Composio (invariant #5). Introducing a second broker adds operational surface for zero gain.
Wait for Composio to add native supportAcceptable 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_api workarounds 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.