@clawnify/integrations
v0.2.2
Published
Connection descriptor registry for Clawnify apps. Encodes — once, per integration — how a credential is accessed and what its typed client looks like, so app code never carries integration-specific plumbing. Broker-agnostic: the provider that actually hol
Readme
@clawnify/integrations
The connection descriptor registry for Clawnify apps. One descriptor per integration encodes — once — how its credential is reached and what its typed client looks like, so app code never carries integration-specific plumbing.
This package holds the knowledge; @clawnify/connections
holds the accessors (connect, secret, describe) that turn that knowledge
into runtime clients. Apps depend on @clawnify/connections and rarely import
this package directly.
What a descriptor is
interface ConnectionDescriptor<Client> {
service: string; // "googleads" — the id used in clawnify.json `requires`
label: string; // "Google Ads"
kind: "oauth" | "managed" | "key" | "secret";
envName?: string; // for key/secret: the injected env var name
accessor: string; // one-line snippet shown to agents via describe()
client?(ctx): Client; // builds the typed client (oauth/managed only)
}A descriptor describes a capability, never a vendor. Whether a connection
resolves through a managed provider, a self-configured connection, or a future
backend is decided entirely inside the Clawnify credentials worker and is
invisible here — descriptors only ever see ctx.token() and ctx.run(action).
Kinds
| kind | how it's reached | client | example |
|------|------------------|--------|---------|
| oauth | bearer token, app calls the vendor API directly | yes | metaads |
| managed | a managed action runs the call (app needs no extra creds) | yes | googleads |
| key | a provider API key injected as an env var | no — use secret() | openrouter |
| secret | an arbitrary user-defined secret env var | no — use secret() | — |
You only add a descriptor when you want a typed client
A new integration does not need an entry here to work. @clawnify/connections
falls back to a generic token() + run(action) client for any unregistered
service, so a toolkit added in the dashboard is usable with zero package change
and zero release. You add a descriptor only to upgrade one integration from
generic to first-class (connect("x").query(...) instead of raw run(...)).
That means this package is released on its own cadence — when an integration earns a bespoke client — not every time the catalog grows.
How to add one
Add a file under src/descriptors/, register it in src/registry.ts, and (if
it exposes a client) add its client type to ServiceClients. Keep every
broker-specific identifier (managed action slugs, base URLs, response quirks)
inside the descriptor — that is the whole point.
Provisioning a connection still happens only in the Clawnify dashboard. A descriptor declares how to use a connection, never how to create one.
