Tool. Defaults set on the factory can be
overridden per tool.
api_key_tool_factory
Tools for an API that authenticates with static headers: x-api-key, a bearer
token you already hold, several headers at once.
str | Callable[[], str]
required
Base URL for the API, e.g.
"https://api.example.com/". A callable is
resolved on every request.Dict[str, str] | Callable[[], Dict[str, str]]
default:"None"
Headers injected on every request. May be omitted here and supplied per tool
via
api_key_headers_override; a tool with neither raises DeclarationError. An
empty value in a literal mapping is rejected at build time — on the factory
and on the tool."camel" | "snake" | "pascal" | "kebab"
default:"\"camel\""
Case convention for body keys.
"camel" | "snake" | "pascal" | "kebab"
default:"\"snake\""
Case convention for query keys.
"camel" | "snake" | "pascal" | "kebab"
default:"\"snake\""
Case convention for path keys.
int
default:"20"
Request timeout in seconds.
Optional[str]
default:"None"
Link to the API’s own rate-limit documentation. Carried onto every tool.
Optional[Envelope]
default:"None"
How this API reports failure inside a 200 response. Declared once here,
enforced on every tool the factory builds.
Optional[Iterable[ScopeRefusal]]
default:"None"
How this API says a credential’s grant does not cover the call, so each such
answer raises
InsufficientScope naming
the scopes to add. The standard WWW-Authenticate challenge needs no
declaration. See ScopeRefusal.Optional[Pagination]
default:"None"
Where this API keeps its cursor. Declare it per tool instead when only some
endpoints are lists — a retrieve labelled with a cursor parameter it does not
accept is worse than no declaration.
"json" | "form"
default:"\"json\""
"form" for form-encoded APIs such as Stripe and Twilio."repeat" | "bracket"
default:"\"repeat\""
"bracket" for APIs expecting expand[0]=x in the query string.Optional[Dict[str, Any]]
default:"None"
Query parameters sent verbatim on every request.
Optional[Dict[str, str]]
default:"None"
Headers sent verbatim on every request — an Azure
api-version, a
Notion-Version.Optional[CallSink]
default:"None"
Receives a
ToolCall after every
invocation of every tool this factory builds. Declared here because
observability belongs to the deployment, not to one endpoint.Optional[Iterable[int]]
default:"None"
Statuses that mean “your credential” rather than “not allowed”. Defaults to
{401}.bool
default:"False"
Whether a 3xx is followed. Off by default: on a JSON API a redirect is
usually a wrong URL, and following it quietly hides that. Turn it on per tool
with
follow_redirects_override where the answer is a redirect — GitHub
serves Actions logs as a 302 to a signed URL. The headers named in
api_key_headers are dropped when a redirect leaves the origin.ToolBuilder
A callable that builds
Tool instances with these defaults. Its parameters
are listed under the builder.oauth_tool_factory
Tools for an API that authenticates with a bearer token. The token is fetched
from credential_provider on every call, so a provider that refreshes is picked
up without rebuilding the tools. Charter never runs the OAuth flow itself: a
missing, expired or rejected token raises CredentialError for the host
application.
api_key_tool_factory — body_case,
query_case, path_case, timeout, quota_doc_url, envelope, scope_refusals, pagination,
body_format, query_format, static_query, static_headers, on_call,
credential_statuses, follow_redirects — behave identically. The five that
differ:
str
required
Provider identifier passed to
get_credentials, e.g. "google". Also the
peer.service label on every record.CredentialProvider
required
Supplies the bearer token. See Credentials.
Optional[ScopesDeclaration]
default:"None"
What these tools need from a grant: scope strings, or
AnyOf(...) where the provider accepts several,
narrowest first. A mapping of Kind to lists declares
them for each kind of credential the provider issues. Carried as metadata for
scopes_for, consent screens and approval UIs;
Charter does not request them. A tool’s scopes_override list replaces the
default kind’s and keeps the others; a mapping replaces the kinds it names.int
default:"10"
How dead a token must be before the runtime refuses to send it. A guard
against sending something already expired, not a refresh policy.
Optional[str]
default:"None"
The header the token goes in, for an API that does not read it from
Authorization. None sends Authorization: Bearer <token>; a name sends
the token bare in that header — "X-Shopify-Access-Token" for Shopify. Only
where the token lands changes: it still comes from credential_provider on
every call, so a provider that renews keeps renewing, which a key in
api_key_headers cannot. Dropped on a redirect that leaves the origin, and
masked in the debug log, as Authorization is.The builder
Both factories return a callable with the same parameters, except thatapi_key_headers_override exists only on the API-key builder and
scopes_override only on the OAuth one.
Two details of how overrides resolve:
body_case_override,query_case_override,path_case_override,timeout_override,envelope_override,pagination_override,on_call_override,follow_redirects_override,api_key_headers_overrideandscopes_overridereplace the factory value when they are notNone. PassingNonekeeps the factory’s.body_format_overrideis applied withor, so"json"and"form"both work but a falsy value falls back to the factory’s.
static_body is per tool rather than per factory because the constant belongs
to the operation: every Linear tool POSTs to the same graphql URL, and the
query document is what distinguishes one from another.
Errors
Related
api_key_tool_factory— the narrative version, with more auth shapes- Authorization servers — what to pass as
credential_provider - Packs — factories already declared against eleven APIs