End to end
How this works, end to end
Every route a question or an app can take, what is checked by code and what is left to a model, and where a person is still needed.
The problem
- To let users connect their Google, LinkedIn or Shopify account, you register an app with that provider.
- For some providers that takes ten minutes. For others it means a review that can run for weeks.
- Setup guides explain the clicking, but not how hard it is, how long approval takes, or which steps only you can do.
- This site puts those answers first and says how sure it is about each: Tested, Sourced, Reported, Inferred or Unknown.
The pieces
Everything runs in one Next.js app on Vercel. The browser never talks to an AI model, a search engine or Composio directly.
Drawing the diagram…
Diagram source
flowchart TD
U["Browser<br/>Library, Ask, Live agent, Plan, Compare"]:::code
U --> PG
U --> AS
U --> GE
subgraph APP["Next.js 16 on Vercel"]
direction LR
PG["Pages<br/>pre-rendered"]:::code
EX["/api/guides, /badge, llms.txt<br/>exports"]:::code
AS["/api/ask<br/>answers questions"]:::code
GE["/api/generate<br/>Live agent, streams progress"]:::code
end
PG --> LB
EX --> LB
AS --> LB
LB[("Library<br/>10 researched JSON guides + passage index")]:::data
AS --> OR
GE --> OR
OR["Orchestration and guardrails, in code<br/>schema, quote check, tags, rate limits, address blocking"]:::good
OR --> R["AI router<br/>Claude, Groq, Gemini, OpenRouter"]:::ai
OR --> W["Web research<br/>Tavily search + page fetch"]:::code
OR --> C["Composio<br/>API or public toolkit docs"]:::code
classDef code fill:#ffffff,stroke:#0f0f0f,color:#0f0f0f;
classDef ai fill:#eef0ff,stroke:#0007cd,color:#0f0f0f;
classDef human fill:#fff4d6,stroke:#9a6400,color:#0f0f0f;
classDef stop fill:#fde8e1,stroke:#cf4519,color:#0f0f0f;
classDef good fill:#e6f4ee,stroke:#0a7a58,color:#0f0f0f;
classDef data fill:#f0f0f0,stroke:#5c5c5c,color:#0f0f0f;- Pages are pre-rendered from the library data, so the 10 researched guides load instantly and never depend on an AI.
- /api/ask answers a question from the library, or researches the web when the app is not in it.
- /api/generate is the Live agent: it researches one app and streams its progress while it writes a guide.
- Guardrails sit in code, not in the prompt: schema, quote matching, tag downgrades, rate limits and private-address blocking.
- Keys (Claude, Groq, Gemini, Tavily and the rest) live only in Vercel environment variables, never in the repository or the browser.
Four scenarios
Two questions decide the route: is the app in the library, and does Composio manage its OAuth app?
Drawing the diagram…
Diagram source
flowchart TD
Q["You name an app<br/>(in the home search box, Ask or the Live agent)"]:::code --> L{"Is it one of the 10<br/>researched library apps?"}
L -- yes --> LG["Researched guide<br/>written from official docs,<br/>quotes checked against pages"]:::good
L -- no --> LV["Live research<br/>pages read a moment ago,<br/>quotes checked by code"]:::ai
LG --> M1{"Does Composio<br/>manage the OAuth app?"}
LV --> M2{"Does Composio<br/>manage the OAuth app?"}
M1 -- yes --> S1["Scenario 1<br/>Library + managed"]:::good
M1 -- no --> S2["Scenario 2<br/>Library + you register your own"]:::good
M2 -- yes --> S3["Scenario 3<br/>Not in library + managed"]:::ai
M2 -- no or unknown --> S4["Scenario 4<br/>Not in library + you register<br/>or not confirmed"]:::ai
classDef code fill:#ffffff,stroke:#0f0f0f,color:#0f0f0f;
classDef ai fill:#eef0ff,stroke:#0007cd,color:#0f0f0f;
classDef human fill:#fff4d6,stroke:#9a6400,color:#0f0f0f;
classDef stop fill:#fde8e1,stroke:#cf4519,color:#0f0f0f;
classDef good fill:#e6f4ee,stroke:#0a7a58,color:#0f0f0f;
classDef data fill:#f0f0f0,stroke:#5c5c5c,color:#0f0f0f;| Scenario | How sure we are | What happens | Examples |
|---|---|---|---|
| 1. In the library, Composio manages the OAuth app | Researched by a person, quotes checked against pages | Instant keyword answer, then an AI answer written only from the guide's passages. Cards show Composio managed auth as Available. | GitHub, Notion, Slack, HubSpot, Shopify |
| 2. In the library, you register your own app | Researched by a person, quotes checked against pages | Same pipeline. The full setup, review and wait are the whole job, and the guide says which steps only you can do. | Salesforce, LinkedIn, Meta (advanced access) |
| 3. Not in the library, Composio manages the OAuth app | Pages read a moment ago, not human-checked | Ask researches the web and answers from those pages. The Live agent writes a guide; the managed flag comes from Composio and is set by code. | Zoom, Discord, Dropbox |
| 4. Not in the library, you register your own, or Composio is silent | Pages read a moment ago, not human-checked | Same research. If Composio's status cannot be found the guide says Not confirmed and plans for the worse case. Anything no page states is Unknown. | Smaller or newer apps |
- Library answers are researched by a person and every quote is checked against its page.
- Everything else is researched live, labelled as not human-checked, and shows the pages it read.
- Whether an app is in the library is separate from whether Composio manages its OAuth app. The next diagram covers the second question.
Composio managed or not
The managed status is looked up by code, never guessed by a model.
Drawing the diagram…
Diagram source
flowchart TD
A["App name"]:::code --> B{"COMPOSIO_API_KEY<br/>set on the server?"}
B -- yes --> C["Ask the Composio API for<br/>the toolkit's managed auth schemes"]:::code
B -- no --> D["Read the public page<br/>docs.composio.dev/toolkits/app"]:::code
C --> E{"What did it say?"}
D --> E
E -- "managed OAuth available" --> Y["Status yes<br/>tagged Sourced"]:::good
E -- "not available" --> N["Status no<br/>tagged Sourced"]:::good
E -- "no page, or not stated" --> U["Status unknown<br/>tagged Unknown, nothing assumed"]:::human
Y --> Y2["Guide says: you can connect users<br/>without registering your own provider app first.<br/>Register your own only for your branding,<br/>scopes or rate limits."]:::code
N --> N2["Guide says: you must register your own app.<br/>Steps: create the app, redirect URI, scopes,<br/>review, then give the credentials to a Composio auth config."]:::code
U --> U2["Guide shows Not confirmed<br/>and plans for the worse case:<br/>register your own app"]:::code
Y2 --> Z["Your own app, if you make one,<br/>still faces the provider's review.<br/>The wait shown is for that review."]:::human
N2 --> Z
U2 --> Z
classDef code fill:#ffffff,stroke:#0f0f0f,color:#0f0f0f;
classDef ai fill:#eef0ff,stroke:#0007cd,color:#0f0f0f;
classDef human fill:#fff4d6,stroke:#9a6400,color:#0f0f0f;
classDef stop fill:#fde8e1,stroke:#cf4519,color:#0f0f0f;
classDef good fill:#e6f4ee,stroke:#0a7a58,color:#0f0f0f;
classDef data fill:#f0f0f0,stroke:#5c5c5c,color:#0f0f0f;- Managed (yes): Composio's own OAuth app can connect your users, so you can skip registering with the provider first.
- Not managed (no): you register your own OAuth app. This is the case the guides are built for, with effort, wait and what only you can do.
- Unknown: no Composio page was found or it does not say. The card shows Not confirmed and the guide plans for the worse case.
- Even when Composio manages it, your own app, for your branding, scopes or rate limits, still faces the provider's review.
- The status and its tag come from code (Composio API if a key is set, otherwise the public toolkit page) and the model cannot overwrite them.
Flow 1: how a library guide is made
Drawing the diagram…
Diagram source
flowchart TD
R["Research<br/>official provider docs +<br/>Composio's guide, by a person"]:::human --> J["One typed JSON guide<br/>data/guides"]:::data
J --> Z{"Schema and evidence check<br/>npm run validate"}
Z -- "missing field, unknown source,<br/>Sourced without a quote" --> J
Z -- passes --> Q{"Do the quotes still match<br/>the live pages?<br/>npm run verify-quotes"}
Q --> PG["Pre-rendered pages<br/>guide, library, compare, plan"]:::good
Q --> IX["Passage index (BM25)<br/>+ optional embeddings (off by default)"]:::good
Q --> EX["Exports: Markdown, agent brief,<br/>JSON API, README badge, llms.txt"]:::good
PG --> T["A person registers the app by hand<br/>and logs it in docs/TESTING.md"]:::human
T --> TG["Only then may a claim be tagged Tested"]:::good
classDef code fill:#ffffff,stroke:#0f0f0f,color:#0f0f0f;
classDef ai fill:#eef0ff,stroke:#0007cd,color:#0f0f0f;
classDef human fill:#fff4d6,stroke:#9a6400,color:#0f0f0f;
classDef stop fill:#fde8e1,stroke:#cf4519,color:#0f0f0f;
classDef good fill:#e6f4ee,stroke:#0a7a58,color:#0f0f0f;
classDef data fill:#f0f0f0,stroke:#5c5c5c,color:#0f0f0f;- A person researches the provider's official docs and Composio's own guide, then records the result as one typed JSON guide.
- The schema check rejects a guide with missing fields, a cited source that does not exist, or a Sourced claim without a quote.
- verify-quotes re-fetches the pages and confirms each quote is still there. Until it has run against open network, quotes show as not re-matched.
- One guide feeds everything: its pages, the compare and plan tools, the search index, Markdown and agent-brief export, the JSON API, README badge and llms.txt.
- Tested means a person registered the app by hand and logged it in docs/TESTING.md. Until then no claim carries that tag.
Flow 2: Ask, app in the library
Drawing the diagram…
Diagram source
flowchart TD
Q["Question about a library app"]:::code --> RL{"Under 20 questions<br/>this hour?"}
RL -- no --> E1["Try again later"]:::stop
RL -- yes --> CA{"Same question answered<br/>in the last 24 hours?"}
CA -- yes --> H["Return the saved answer"]:::good
CA -- no --> T{"About connecting,<br/>registering or authorising an app?"}
T -- no --> OT["Polite out-of-scope message<br/>no model is called"]:::stop
T -- yes --> K["Phase 1: keyword search<br/>BM25 + synonym groups<br/>(approval = review = verification)"]:::code
K --> Q1["Show passages at once,<br/>assembled by code, no AI"]:::good
Q1 --> HY["Phase 2: optional re-rank<br/>Gemini embeddings (not active today),<br/>keyword order stands"]:::ai
HY --> PR["Prompt = the written skill + top passages<br/>passages are data, not instructions"]:::code
PR --> M["AI router picks a model"]:::ai
M --> V{"Is every citation a passage<br/>that was really retrieved?"}
V -- yes --> A["Answer with clickable citations<br/>saved for 24 hours"]:::good
V -- "no, or all models failed" --> F["Show the guides' own wording,<br/>composed by code, labelled"]:::human
classDef code fill:#ffffff,stroke:#0f0f0f,color:#0f0f0f;
classDef ai fill:#eef0ff,stroke:#0007cd,color:#0f0f0f;
classDef human fill:#fff4d6,stroke:#9a6400,color:#0f0f0f;
classDef stop fill:#fde8e1,stroke:#cf4519,color:#0f0f0f;
classDef good fill:#e6f4ee,stroke:#0a7a58,color:#0f0f0f;
classDef data fill:#f0f0f0,stroke:#5c5c5c,color:#0f0f0f;- Phase 1 is instant and uses no AI. Keyword search finds passages and code assembles an answer, so there is always something useful on screen.
- Phase 2 would re-order passages by meaning with Gemini embeddings; that is optional and not active today, so keyword order is used. Then a model writes an answer using only those passages and the written skill (method, format, link rules).
- Passages are passed as data, not instructions, so a sentence inside a guide cannot redirect the model.
- Citation check: every [id] in the answer must be a passage that was retrieved. If one is not, the AI text is hidden.
- If every model fails, the answer is the guides' own wording, assembled by code, with the reason shown.
- Questions that are not about connecting an app are turned away politely, with no model call.
Flow 3: Ask, app not in the library
Drawing the diagram…
Diagram source
flowchart TD
Q["Question names an app<br/>that is not in the library"]:::code --> N["Find the app name<br/>known-apps list, domain or capitalised word"]:::code
N --> S["3 web searches in parallel<br/>setup, review and scopes, authentication"]:::code
N --> CT["Composio toolkit page"]:::code
N --> PF{"Registered through a parent?<br/>Instagram to Meta, YouTube to Google"}
S --> O["Official hosts first<br/>docs, developers, support"]:::code
O --> FP["Fetch pages, follow auth and review links.<br/>If a site blocks us, use the text<br/>the search engine already read"]:::code
FP --> FL["Keep only pages about the app.<br/>Drop tool lists and script shells"]:::code
PF -- yes --> PG["Add our parent guide's passages"]:::good
FL --> PA["Cut into passages and rank (BM25)"]:::code
CT --> PA
PG --> PA
FL -- "nothing readable" --> GK["Labelled general-knowledge answer<br/>no sources, may be out of date"]:::human
PA --> PR["Prompt = skill + passages"]:::code
PR --> M["AI router"]:::ai
M --> V{"Citations valid?"}
V -- yes --> A["Answer: researched live,<br/>not human-checked, pages listed"]:::ai
V -- no --> F["Passages composed by code"]:::human
classDef code fill:#ffffff,stroke:#0f0f0f,color:#0f0f0f;
classDef ai fill:#eef0ff,stroke:#0007cd,color:#0f0f0f;
classDef human fill:#fff4d6,stroke:#9a6400,color:#0f0f0f;
classDef stop fill:#fde8e1,stroke:#cf4519,color:#0f0f0f;
classDef good fill:#e6f4ee,stroke:#0a7a58,color:#0f0f0f;
classDef data fill:#f0f0f0,stroke:#5c5c5c,color:#0f0f0f;- The app name comes from a known-apps list, a domain, or a capitalised word in the question.
- Three searches run at once (setup, review and scopes, authentication). Official hosts such as docs, developers and support are read first.
- Pages that do not mention the app, tool-name lists and script-built shells are dropped, so they cannot be cited as evidence.
- A product registered through a parent (Instagram, WhatsApp and Threads through Meta; YouTube and Gmail through Google) also brings in our parent guide's passages.
- If a site blocks our fetch behind a bot check, the text the search engine already read is used and the source says so.
- The answer is labelled researched live, not human-checked. If nothing readable was found, a general-knowledge answer is shown with no sources and a clear label.
Flow 4: the Live agent writes a guide
This route takes about one and a half to three minutes. The page shows a loader and a list of every step, with Expand all and Collapse all buttons.
Drawing the diagram…
Diagram source
flowchart TD
I["App name, website, or a typed question"]:::code --> X["Find the app inside the text<br/>sentences with no app are refused"]:::code
X --> CK{"A guide for this app<br/>made in the last week?"}
CK -- yes --> RE["Replay it instantly<br/>costs nothing"]:::good
CK -- no --> RL{"Under 5 new guides<br/>this hour?"}
RL -- no --> E1["Try again later"]:::stop
RL -- yes --> P1["Fixed probes, no AI, Composio first<br/>1 docs.composio.dev/toolkits/app<br/>2 managed-OAuth flag<br/>3 composio.dev/auth guide<br/>4 OAuth discovery if a website was given"]:::code
P1 --> P2{"Registered through a parent?"}
P2 -- yes --> PG["Our parent guide becomes evidence"]:::good
P2 -- no --> LP
PG --> LP["Research loop: up to 6 actions in about 45s<br/>the model picks search or fetch;<br/>code refuses repeats, reworded searches<br/>and addresses no search returned"]:::ai
LP --> VP["Three fixed searches:<br/>review and verification, access tiers and audits,<br/>quotas and limits.<br/>Read the best gate pages, up to 2 each"]:::code
VP --> OD{"Did we read a provider page<br/>about registering the app?"}
OD -- no --> OD2["One more search, read the<br/>provider's own docs page"]:::code
OD -- yes --> OK
OD2 --> OK{"Any usable page read?"}
OK -- no --> ER["Stop. No guide is invented."]:::stop
OK -- yes --> WR["Write the guide as JSON<br/>heavy AI router, up to 110s<br/>whole run capped near 190s"]:::ai
WR --> RP["Repair near-misses<br/>label case, null minutes, bad enums"]:::code
RP --> EN["Enforce checks<br/>see the next diagram"]:::good
EN --> OK2{"Passed?"}
OK2 -- yes --> SH["Show guide<br/>save 24 hours, signed share link"]:::good
OK2 -- no --> RT{"First try?"}
RT -- yes --> WR
RT -- no --> ER2["Show why nothing was shown,<br/>never an unchecked guide"]:::stop
classDef code fill:#ffffff,stroke:#0f0f0f,color:#0f0f0f;
classDef ai fill:#eef0ff,stroke:#0007cd,color:#0f0f0f;
classDef human fill:#fff4d6,stroke:#9a6400,color:#0f0f0f;
classDef stop fill:#fde8e1,stroke:#cf4519,color:#0f0f0f;
classDef good fill:#e6f4ee,stroke:#0a7a58,color:#0f0f0f;
classDef data fill:#f0f0f0,stroke:#5c5c5c,color:#0f0f0f;- A typed question is reduced to the app it names; a sentence with no app is refused with a hint to use the Ask box.
- Fixed probes run first and use no AI, Composio first: the page docs.composio.dev/toolkits/app, its managed-OAuth flag, Composio's setup guide, and OAuth discovery if a website was given.
- In the research loop the model chooses a search, a page or done; code runs each action with time, size and address limits. It refuses a repeated or reworded search, a page no search or link returned, and a third search in a row. It stops after 6 actions or about 45 seconds.
- The agent always looks for the gate pages with three fixed searches (review and verification, access tiers and audits, quotas and limits) and reads the best provider pages from each, because models often skip the one page that answers how long approval takes. If it never read a provider page about registering the app, it makes one more search for it.
- If no usable page was read, it stops. It never invents a guide.
- The write step uses the heavy router (Claude first most of the time), a JSON template taken from a researched guide, and a size limit so the reply is not cut off.
- A near-miss such as a wrong label case or a missing number is repaired. Missing setup minutes become a tier-based estimate tagged Inferred.
- The prompt tells the writer to rate a tier by what stops your own app from working for other people. A marketplace listing is a separate, optional step and does not raise the tier.
- A finished guide is saved for 24 hours, and a signed share link is made.
Flow 5: what the checks do
These run in code after the model has written. They are the reason a quote on a guide is trustworthy.
Drawing the diagram…
Diagram source
flowchart TD
D["Draft guide from the model"]:::ai --> E1{"Evidence page was<br/>actually fetched, and the<br/>quote is in its text?"}
E1 -- no --> X1["Drop that evidence"]:::stop
E1 -- yes --> K["Keep it, mark quote verified<br/>forum, community and Q and A pages<br/>are never counted as official"]:::good
X1 --> C
K --> C["For every claim"]:::code
C --> T1{"Tagged Tested?"}
T1 -- yes --> DG1["Downgrade to Inferred<br/>Tested is for humans only"]:::human
T1 -- no --> T2{"Sourced, but no quote left,<br/>or only community pages?"}
DG1 --> T2
T2 -- yes --> DG2["Inferred, or Reported<br/>if only community pages say it"]:::human
T2 -- no --> T3{"Does the cited page really<br/>say it? Shared wording,<br/>years, numbers of 10 or more"}
DG2 --> T3
T3 -- "no" --> DG3["Inferred, or Reported if a<br/>number is only on a community page"]:::human
T3 -- yes --> T4{"An absence such as<br/>'no review is mentioned'?"}
DG3 --> T4
T4 -- yes --> DG4["Unknown or Inferred, never Sourced"]:::human
T4 -- no --> T5{"Tier 3 or 4 without a<br/>Sourced review step?"}
DG4 --> T5
T5 -- yes --> DG5["Tier lowered to 2 and said so"]:::human
T5 -- no --> T6{"A step done in the provider's<br/>console marked agent or either?"}
DG5 --> T6
T6 -- yes --> DG6["Changed to You"]:::human
T6 -- no --> CM
DG6 --> CM["Sources nobody cites are dropped<br/>Composio managed status<br/>is set by code, never the model"]:::code
CM --> SC{"Passes the schema?<br/>Zod: types, enums, numbers"}
SC -- no --> FAIL["Rejected: nothing shown"]:::stop
SC -- yes --> OUT["Guide + a list of every automatic change"]:::good
classDef code fill:#ffffff,stroke:#0f0f0f,color:#0f0f0f;
classDef ai fill:#eef0ff,stroke:#0007cd,color:#0f0f0f;
classDef human fill:#fff4d6,stroke:#9a6400,color:#0f0f0f;
classDef stop fill:#fde8e1,stroke:#cf4519,color:#0f0f0f;
classDef good fill:#e6f4ee,stroke:#0a7a58,color:#0f0f0f;
classDef data fill:#f0f0f0,stroke:#5c5c5c,color:#0f0f0f;- A source the agent never fetched is dropped. So is a quote that is not in the page text, character for character. Pages on forums, community boards and Q and A sites never count as official, even on the provider's own domain.
- A claim that loses its quote drops from Sourced to Inferred. One backed only by community pages becomes Reported. The model cannot mark anything Tested.
- A Sourced claim must match its cited page: shared wording, and any year it names must appear there. Every figure of 10 or more must be on a cited page, or the claim becomes Inferred; one only a community page contains makes it Reported.
- An absence ("no review is mentioned") is never Sourced. A Tier 3 or 4 without a Sourced review step is lowered to Tier 2, with a note. Steps done in the provider's console are always You. Then a second, independent review reads each claim next to its quotes and removes or lowers anything they do not support (wrong scope, two reviews blended, off-topic); it can never raise a tag. Sources nobody cites are dropped, and an unsupported gotcha that is not about setup, auth, review or limits is removed.
- The Composio status is set by code. The model's own value is overwritten.
- The schema check fixes the shape: if it fails twice, nothing is shown, and the screen says why.
- Every automatic change is listed under Automatic checks applied on the guide, so nothing happens silently.
Which AI answers, and what happens when one fails
Drawing the diagram…
Diagram source
flowchart TD
R["Request to an AI model"]:::code --> H{"Writing a whole guide?"}
H -- no --> A1["Tier 1: Claude or Groq<br/>at random<br/>(only those with a key)"]:::ai
A1 -- "error, timeout or wrong format" --> A2["Tier 2: Gemini or OpenRouter, 50-50"]:::ai
A2 -- fails --> A3["Tier 3: Claude once more"]:::ai
H -- yes --> G1["Claude first, with 80% of the time.<br/>Groq is skipped for long prompts"]:::ai
G1 -- fails --> G2["Gemini or Groq"]:::ai
G2 -- fails --> G3["Claude last"]:::ai
A1 --> OKK["First good reply wins"]:::good
A2 --> OKK
A3 --> OKK
G1 --> OKK
G2 --> OKK
G3 --> OKK
A3 -- fails --> ERR["Error names every provider<br/>and why it failed"]:::stop
G3 -- fails --> ERR
classDef code fill:#ffffff,stroke:#0f0f0f,color:#0f0f0f;
classDef ai fill:#eef0ff,stroke:#0007cd,color:#0f0f0f;
classDef human fill:#fff4d6,stroke:#9a6400,color:#0f0f0f;
classDef stop fill:#fde8e1,stroke:#cf4519,color:#0f0f0f;
classDef good fill:#e6f4ee,stroke:#0a7a58,color:#0f0f0f;
classDef data fill:#f0f0f0,stroke:#5c5c5c,color:#0f0f0f;- Short answers pick Claude or Groq at random (only those with a key), then Gemini or OpenRouter, then Claude once more.
- Whole guides go to Claude first, then Gemini or Groq, then Claude last. Groq is skipped for long prompts because of its size limit.
- A reply in the wrong format (for example prose where JSON was needed) counts as a failure and moves to the next provider.
- If everyone fails, the error lists every provider and its reason, so a quota problem on one is not hidden behind another.
- /api/health tests each provider and shows which ones respond right now.
Technology used
- Next.js 16 (App Router), React 19, TypeScript
- Pages are pre-rendered; the API routes run as serverless functions on Vercel. The Live agent streams its progress to the browser as server-sent events.
- Zod schema
- Every guide, written by a person or an AI, must fit one typed shape. A guide that does not fit is rejected, not repaired into something else.
- BM25 + synonym groups
- Keyword retrieval over passages cut from the guides. Synonym groups (approval, review, verification, listing) let a question and a guide use different words.
- Gemini embeddings (optional, off by default)
- Could re-order keyword hits by meaning. Needs a working Gemini key and prebuilt vectors (npm run build:embeddings), neither of which is in place today, so Ask uses keyword order. Capped at 4 seconds if enabled.
- AI router
- Claude, Groq, Gemini and OpenRouter, used only when their key is set. Claude, Groq and OpenRouter have answered live; Gemini is wired in but over quota until billing is enabled. Tiers and random choice spread load and survive any one provider failing.
- Tavily search, then fetch
- Search finds the provider's pages. Fetch reads them (private addresses blocked, size and time capped). When a site shows a bot check, the text the search engine read is used and labelled as such. Results that are news, jobs, app-store pages or about another product are filtered out, repeats of one page are merged, and when picking review and quota pages it skips customer-account checks, product reviews, release notes and audit-log marketing pages.
- Composio API and public toolkit docs
- Tell us whether Composio manages the OAuth app and which auth methods the toolkit supports.
- Signed share links
- A guide is packed into the URL and signed with HMAC-SHA256 using a server secret. Nothing is stored; only this server can mint a valid link.
- Caches and limits
- Generate guide and the home box reuse a saved guide for up to 24 hours, as do Ask answers; the Write a fresh one button regenerates it and replaces the saved copy, in your browser and on the server (in Vercel Blob when connected, so every visitor shares them). Ask allows 20 questions an hour and the Live agent 5 new guides an hour per visitor; repeats cost nothing.
- Tests
- 83 automated tests cover the schema, quote checks, the claim-versus-page checks, retrieval, the AI router, link signing and the text cleaning. Run with npm test.
What is checked by code and what is not
- By code, every time: quotes against page text, tags, Composio status, schema, link signing, rate limits, private-address blocking, citations against retrieved passages.
- By a model: choosing the next page to read, writing the answer or guide, and reading the question.
- By a person, still pending: registering apps by hand, so no claim is Tested yet, and a review of live-generated guides before they join the library.
- Known limits: a guide takes about one and a half to three minutes; retrieval re-ranking by meaning has not been prebuilt; Gemini needs billing enabled before it adds capacity; the server cache is per instance, while the browser copy is reliable.
From 10 guides to 100
- Seed the list from Composio's managed-auth directory, starting with the apps developers ask for most.
- Run the batch (scripts/batch-generate.ts): each app goes through the Live agent with the same checks and is saved for review.
- Review a sample: open the quotes, run npm run verify-quotes and compare the tier with the provider's own docs.
- Promote reviewed guides into the library. Unreviewed ones stay labelled as written by the agent.
- Re-check on a schedule, because provider docs change. Each guide shows its last-verified date.
Plain-language glossary
- OAuth app
- The registration your product holds with a provider so users can grant access without sharing passwords.
- Provider review
- The provider checking your app before strangers can use it. This is the slow part.
- RAG
- Look up relevant passages first, then let a model answer from them, so answers stay tied to written sources.
- Agent
- A model that decides which tool to use next, such as search or fetch a page, in a loop within limits we set.
- Hallucination
- A model stating something that sounds right but is not supported. The quote and citation checks look for exactly this.
- Evidence tag
- Tested, Sourced, Reported, Inferred or Unknown, shown beside each claim.