Skip to main content
A pack is a set of tools already declared against one API. Configure the credential once and every tool in it is callable — the schemas, the wire contract, the failure convention and the pagination style are already written down. Doing it yourself is the slow part. One endpoint can pull in a dozen schemas that reference each other across as many pages, sometimes on a different site, and one field in the wrong place is a 400 you cannot reproduce. A pack is that reading already done, from the vendor’s own docs, and checked by the conformance suite. Why Charter is the longer answer to why the gap exists at all.

Coverage

Gmail

23 tools · OAuth bearer

Google Calendar

13 tools · OAuth bearer

Google Sheets

17 tools · OAuth bearer

Google Docs

3 tools · OAuth bearer

Google Drive

25 tools · OAuth bearer

Google Forms

6 tools · OAuth bearer

Slack

18 tools · OAuth bearer

GitHub

139 tools · OAuth bearer

Stripe

59 tools · API key

Linear

128 tools · API key

Shopify

22 tools · API key

Notion

35 tools · OAuth bearer

Granola

9 tools · API key

Firecrawl

43 tools · API key

Tavily

9 tools · API key
Every tool in every pack has its LLM schema built, its egress map checked against that schema, and its OpenAI function definition validated in the suite.

Compatibility with agents

Every pack exports TOOLS, which is what an adapter takes:
packs_to_langchain_tools.py
TOOLS is the default list, not the complete one. A pack may build tools it leaves out.

What the hard cases taught the runtime

Slack reports failure as HTTP 200 with {"ok": false, "error": "..."}, so a generic HTTP client hands the model an error payload as if the message had sent.That is not patched per tool. It is declared once, as an Envelope on the factory, and enforced by the runtime on every call — including calls by tools somebody adds next year. The same one line handles any GraphQL API, whose failures are always a 200 with an errors array. Read more.
Form-encoded in both directions with bracket notation (line_items[0][price]=…), and a cursor that is the last object’s id rather than a token the API hands back (data[-1].id). Both are declared once on the factory. Read more.
A bearer token from your credential provider, alongside an Accept, an X-GitHub-Api-Version and a User-Agent that GitHub requires and the model must never see. Those go in static_headers.GitHub also pages by number rather than by cursor — ask for page 1, 2, 3 and stop when a page comes back short — which is the second pagination style Pagination declares. Read more.
Every tool in a GraphQL pack POSTs to the same URL. What makes issues_list different from issue_create is the query document, which is a constant belonging to the tool rather than a parameter. Putting it in static_body keeps it off the schema entirely.That is the whole boundary: a GraphQL endpoint accepts arbitrary documents, so a tool that let the model write the query would not be an integration, it would be a shell.Both packs also carry a failure GraphQL’s own errors array does not. A mutation the server understood and then declined comes back HTTP 200, with no errors, and the refusal in the payload — Linear’s success: false, Shopify’s userErrors. Every signal a runtime normally trusts says the write happened. So Envelope field names are paths, with * standing for whichever operation the tool called:
Shopify additionally has no fixed host: a store lives at https://{shop}.myshopify.com/, so its base URL is resolved per request from configure() rather than being a schema field the model could point elsewhere. Linear · Shopify.

Writing your own pack

Twelve packs will never cover the API you actually work with. That is the normal case, and the answer is not to wait for a twelfth. A pack is declarations rather than integration code, which makes writing one small: the same oauth_tool_factory or api_key_tool_factory call that every pack page prints in full, then one schema per endpoint. And you mostly do not write it yourself. The pack-writing skill is a single markdown file that gives a coding agent the order to work in and the reading it must not skip, which is the step that decides whether a pack is right. The conformance suite then holds the result to the same rules as the eleven above.

Improving existing packs

A pack covers the endpoints most people reach for, not all of them. When yours is missing, TOOLS is an ordinary list:
packs_extend.py
If a tool already in the pack declares something wrong, write your own and leave that one out. The runtime treats them the same. Either way the fix is worth sending back, because the next person hits the same thing.

Contributing it back

A pack for an API you actually use is the most useful thing anyone can add here, and it does not need permission first. Open a pack request so that two people do not write the same pack, then follow the skill file. CONTRIBUTING.md covers the setup and the rules the suite enforces anyway.