Imported from alienstro/reddit-post (
skills/composio-walk/SKILL.md). Install upstream withnpx skills add alienstro/reddit-post --skill composio-walk. Copyright stays with the author.
composio-walk
Add a Composio-only marketplace card: a provider Composio can connect but that we have no browser signup for. Its Add button skips the "Add provision" modal and runs the Composio authorize flow directly, ending in a success or error snackbar. This is the Composio analogue of signup-walk — but there is no browser walk and no replay recipe. The "walk" is verifying the toolkit inside Composio and classifying what it can do.
A Composio-only card is just a Capability with no backendType and no signupRecipe, plus a reviewed Composio toolkit. "Composio-only" is derived from those empty fields (see isComposioOnly in apps/web/src/equip/catalog.ts) — do NOT add a backendType/signupRecipe to make it "Add", and do NOT invent a flag. If browser-signup automation is added later (via signup-walk on the same id), the card upgrades itself to the full dual-provider modal with no migration.
Design: docs/superpowers/specs/2026-07-21-composio-walk-design.md.
Prerequisites
- The shared feature must be live. Composio-only cards render Add (widened
isConnectable), the Add button routes straight to the Composio connect flow, and success/error snackbars fire. Without it, the card you wire will render "Soon" or open the wrong flow. If it isn't built yet, that is a code task, not this skill. - A Composio API key with toolkit READ access. The key in
apps/api/.env(COMPOSIO_API_KEY) has Read All + Write All scopes (regenerated 2026-07-21), socomposio.toolkits.get()and the tools listing below both work directly against the API — this is the primary verification path. NOTE: these API-key scopes govern what our backend may do against Composio's platform API (read toolkit/tool defs, create connected accounts, execute tools). They have nothing to do with what a connected agent can do on the provider (e.g. GitHub) — that is set entirely by the OAuth/API-key grant the owner approves at connect time. If atoolkits.get()ever fails withCouldn't fetch Toolkit with slug: <slug>(see the walk below), the key lost read scope; fall back to the public toolkit pages. - For a live end-to-end connect test:
COMPOSIO_ENABLED=true,COMPOSIO_API_KEY, andCOMPOSIO_CALLBACK_ORIGINset inapps/api/.env. Testing agent tool execution (as opposed to connect-only) also requiresCOMPOSIO_MCP_ENABLED=true.
When to use / not use
- Use when the user names a provider Composio supports that has no marketplace card (e.g. Linear, GitHub, Jira, HubSpot, Trello, Gmail, Google Calendar).
- Don't card it when the provider already has a marketplace card (it is already Composio-capable via
applyComposio, possibly a dual provider) — grep the catalog first. Or when the toolkit exposes no usable tools (zero_tools) — report and stop, exactly asetsy/mastodon/patreonare handled today.
The walk — verify the toolkit in Composio
Run from apps/api (so @composio/core resolves and --env-file loads the key). Replace <TOOLKIT_SLUG> with the Composio toolkit slug (which is often NOT the provider id — see Gotchas):
cd apps/api && node --input-type=module --env-file=.env -e '
import { Composio } from "@composio/core";
const c = new Composio({ apiKey: process.env.COMPOSIO_API_KEY });
const tk = await c.toolkits.get("<TOOLKIT_SLUG>");
console.log(JSON.stringify({
slug: tk.slug,
name: tk.name,
toolsCount: tk.meta?.toolsCount,
authSchemes: tk.composioManagedAuthSchemes,
categories: (tk.meta?.categories ?? []).map((x) => x.slug ?? x),
}, null, 2));
'
slugpresent +toolsCount > 0→ the toolkit exists and has tools.authSchemes→ the auth scheme(s), e.g.["OAUTH2"],["API_KEY"],["BEARER_TOKEN"],["NO_AUTH"]. This decides the connect UX (redirect vs immediate) the shared feature runs.- If the call fails with
Couldn't fetch Toolkit with slug: <slug>, do NOT assume the slug is wrong — this SDK version surfaces a read-permission failure with that exact "bad slug"-looking message. Disambiguate by re-running against a known-good slug likelinear: iflinearfails identically, it's the key (missing toolkit read scope), not your slug; iflinearsucceeds but yours doesn't, the slug really is wrong. When the key can't read, fall back to the public toolkit pages (https://composio.dev/toolkits/<slug>andhttps://docs.composio.dev/toolkits/<slug>— both list auth scheme, tool count, and example tools; no login needed, unlike the dashboard).
Judgment call — read the actual tool list. toolsCount > 0 alone is not enough: decide whether the tools let an agent act as the connected account (→ usable) or are constrained/read-only/partner-scoped (→ limited, with a one-line reason). Match the tone of the existing limitation strings in composio-catalog.ts. Pull real tool names from the API (note: c.tools.list / c.toolkits.list do not exist in the installed @composio/core — use getRawComposioTools with a toolkits array):
cd apps/api && node --input-type=module --env-file=.env -e '
import { Composio } from "@composio/core";
const c = new Composio({ apiKey: process.env.COMPOSIO_API_KEY });
const res = await c.tools.getRawComposioTools({ toolkits: ["<TOOLKIT_SLUG>"], limit: 30 });
console.log((res?.items ?? res ?? []).map((t) => t.slug ?? t.name).join("\n"));
'
Or read the tool list off the public composio.dev/toolkits/<slug> page when the API is unavailable.
Support classification
| support | when | catalog effect |
|---|---|---|
usable |
real tools that act as the connected user | full Composio-only card |
limited |
works but constrained (Pages-only, public read-only, dev-tier required, …) | card + a limitation string shown to the owner |
zero_tools |
no usable tools | stop — do not card it |
Auth scheme maps to ComposioAuthScheme: 'OAUTH2' | 'API_KEY' | 'BASIC' | 'NO_AUTH' | 'S2S_OAUTH2'. NO_AUTH toolkits still get a card and a Composio chip; their Add connects immediately (no redirect).
Wiring the card
Do all steps for one provider, then verify. Files: apps/api/src/integrations/composio-catalog.ts (API allowlist), apps/web/src/equip/catalog.ts (marketplace), apps/web/public/logos/.
-
Confirm it isn't already carded. Grep both catalogs for the provider id and the toolkit slug:
grep -niE "'<id>'|<toolkit_slug>" apps/web/src/equip/catalog.ts apps/api/src/integrations/composio-catalog.tsAny hit in
CURATED_CAPABILITIES/CAPABILITIESmeans it already exists — stop. -
API catalog — make the toolkit connectable server-side. Add a row to the
capabilitiesarray incomposio-catalog.ts. This buildsCOMPOSIO_TOOLKITS, whichComposioIntegrationsServiceconsults onconnect/status; without it the server rejects the connection even though the card renders:['<id>', '<toolkit_slug>', 'usable', 'OAUTH2'], // limited example: ['<id>', '<toolkit_slug>', 'limited', 'API_KEY', '<one-line limitation>'], -
Web catalog — add the Composio-only card. In
catalog.ts:- Add a
CapabilitytoCURATED_CAPABILITIESwith nobackendTypeand nosignupRecipe:{ id: '<id>', name: '<Name>', desc: 'Connect a <Name> account for your agent', logo: '/logos/<id>.svg', tile: 'bg-[#<brand-hex>]', cats: ['<category>'] }, - Add the Composio metadata (keyed by card
id) toCOMPOSIO_CAPABILITIES, mirroring the API row. This entry is also what registers the slug inREVIEWED_COMPOSIO_TOOLKIT_SLUGS(the validator derives "reviewed" from this map, not the API catalog):<id>: composio('usable', '<toolkit_slug>', ['OAUTH2']), // limited: composio('limited', '<toolkit_slug>', ['API_KEY'], '<same limitation>'), - If the id is in
COMPOSIO_UNAVAILABLE_IDS, remove it — otherwiseapplyComposiooverwrites it withunavailableand the card won't be Composio-only.
- Add a
-
Logo — must be COLORED. Add
apps/web/public/logos/<id>.svg. Check it doesn't already exist. The marketplace / equip / agent cards render the logo<img>directly on the dark card background (#0a0f1a) — thetilefield is NOT used behind it — so a black or fill-less mark is invisible (this is what a raw simple-icons download gives you). Use a colored, light-on-dark-visible logo:- Prefer the brand's official colored SVG.
- Otherwise pull the simple-icons mark and give its
<path>an explicit brand-colorfill(simple-icons ships one monochrome path with no fill → defaults to black):curl -sL -o apps/web/public/logos/<id>.svg \ https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/<id>.svg # then add fill="#<brand-hex>" to the <path> so it's visible on the dark card
Sanity check: the fill is a mid/light brand color, never
#000/absent. (Working examples: devto#ffffff, hashnode#2962ff, notion white; Linear uses#5E6AD2.) -
Verify.
- Update
catalog.test.tsin two places. (a) Bump the provider count — it asserts a hardcoded total (Expected Composio metadata for all N providers); each new card grows it by one, so incrementNin both the!==condition and the message string, or the test fails. (b) Add the id to theexpectedComposioSupportlist for its support level (usable/limited/…). Not strictly required to pass today (the loop only checks listed ids, not completeness), but keep it in sync so the per-support assertion stays meaningful. - Catalog validator (must print no errors) — run the web catalog test that calls
validateComposioCatalog(CAPABILITIES). The web runner isnode --testviatsx, not vitest/jest:cd apps/web && TSX_TSCONFIG_PATH=tsconfig.app.json \ node --import tsx --import ./test/register-asset-hooks.mjs --test src/equip/catalog.test.ts - Typecheck both apps:
cd apps/api && npx tsc --noEmitandcd apps/web && npx tsc -b --noEmit. Grep the output for your provider's id/slug to confirm you introduced nothing new (pre-existing unrelated errors are fine). - Optional live check: on a dev agent, open the marketplace, confirm the card shows the Composio chip + Add, press Add, complete authorize, and confirm the success snackbar (and the error snackbar on cancel).
- Update
Gotchas — check every card
- Toolkit slug ≠ provider id. The API row and
COMPOSIO_CAPABILITIESvalue carry the real Composio slug, which frequently differs from the cardid:msteams→microsoft_teams,x→twitter,eodhd→eodhd_apis,kofi→ko_fi,stackexchange→stack_exchange,twelvedata→twelve_data. Read the slug from the verification output, never guess. - Two catalogs, two purposes. The web
COMPOSIO_CAPABILITIESentry (step 3) drives rendering + the validator's "reviewed" set; the APIcomposio-catalog.tsrow (step 2) drives the server's connect/status. Miss the web entry andapplyComposioleaves the card without metadata; miss the API row and the card renders but the connection is rejected server-side. Do both. - Duplicate toolkit fails the validator. Two cards mapping the same toolkit slug →
duplicate toolkit. One card per toolkit. - Left in
COMPOSIO_UNAVAILABLE_IDS.applyComposiowill stamp the cardunavailableand it silently loses Composio-only behavior. Remove the id. - Added a
backendType/signupRecipeby habit. That turns the card into a browser-signup (or dual) provider and it will open the modal instead of going straight to authorize. Composio-only cards have neither. zero_toolstoolkit. Composio lists the toolkit but exposes nothing an agent can use — do not card it; report the blocker.- Invisible logo. A raw simple-icons SVG is black with no fill and vanishes on the dark card. The logo must carry a visible brand-color
fill(see step 4). Couldn't fetch Toolkit with slug≠ bad slug. The installed SDK reports a read-permission failure with that exact message, which reads like the slug is wrong. The key should have toolkit read scope (Read All), so this is rare — but if you hit it, re-run against a known-good slug likelinearto confirm it's the key, then fall back to the publiccomposio.dev/docs.composio.devtoolkit pages. Do not "fix" it by hunting for a different slug.