Profile-bound CLI for agent-first access to growth providers. This repository
has one CLI and one workspace package: gkit.
The reviewed provider surface includes DataForSEO, PostHog, Google Ads, Google Search Console, Bing Webmaster, and HubSpot.
gkit runs on Bun. Confirm that Bun is available before installing:
bun --versiongkit is distributed only as a public npm tarball attached to GitHub Releases. It is not published to an npm registry, so the GitHub URL is required in every install command.
Install the latest stable release globally:
bun add --global "gkit@https://github.com/celados/gkit/releases/latest/download/gkit.tgz"
gkit --schema gscIf the install succeeds but gkit is not found, run bun pm bin --global and
make sure the printed directory is included in your PATH.
Install an exact version instead:
VERSION=0.1.3
bun add --global "gkit@https://github.com/celados/gkit/releases/download/v${VERSION}/gkit-${VERSION}.tgz"
gkit --schemaPrereleases are available only through their exact version URLs and never
replace the stable latest download.
Because the stable URL does not change between releases, remove the installed copy before upgrading so Bun cannot reuse an older cached resolution:
bun remove --global gkit
bun add --global "gkit@https://github.com/celados/gkit/releases/latest/download/gkit.tgz"
gkit --schema gscTo uninstall:
bun remove --global gkitDiscovery commands are offline and do not load a profile or resolve secrets:
gkit --schema
gkit --schema gsc
gkit docs --provider gsc
gkit describe --id gsc.properties.listUse gkit --help for the complete command shape. Use describe before calling
an operation: it returns the reviewed input schema, effects, examples, and
artifact behavior for that capability.
Provider execution must bind exactly one App profile. Create one JSON file at
$XDG_CONFIG_HOME/gkit/profiles/<app>.json, or at
~/.config/gkit/profiles/<app>.json when XDG_CONFIG_HOME is unset:
{
"version": 1,
"name": "my-app",
"providers": {
"posthog": {
"config": {
"host": "https://us.posthog.com",
"projectId": "12345"
},
"secrets": {
"apiToken": "env:MY_APP_POSTHOG_TOKEN"
}
},
"gsc": {
"config": {
"siteUrl": "sc-domain:example.com"
},
"secrets": {
"serviceAccountFile": "env:MY_APP_GSC_SERVICE_ACCOUNT_FILE"
}
},
"hubspot": {
"config": {},
"secrets": {
"accessToken": "env:MY_APP_HUBSPOT_ACCESS_TOKEN"
}
}
}
}Profiles contain non-secret provider defaults and env: references only. Keep
the referenced values in the team's secret manager and inject them into the
gkit process at runtime. Do not put plaintext credentials in the profile,
repository, Agent instructions, command arguments, or shell startup files.
For local use, gkit also loads an optional profile-adjacent environment file at
~/.config/gkit/profiles/<app>/.env after the profile is selected. Keep this
file outside the repository with mode 0600; explicitly supplied process
environment values take precedence over values in the file.
Select a profile explicitly:
gkit --profile my-app posthog doctor
gkit --profile my-app gsc doctor
gkit --profile my-app hubspot doctorOr bind it for one process through the environment:
GKIT_PROFILE=my-app gkit posthog doctor--profile takes precedence over GKIT_PROFILE. One invocation never merges
or falls back to another App profile. Compare multiple Apps by running separate
invocations and joining their outputs outside gkit.
Run doctor before making a provider request. It checks the selected profile
and its provider configuration without printing secret values:
gkit --profile my-app gsc doctor
gkit --profile my-app hubspot doctorStart with the exact example returned by describe and keep --dry-run while
reviewing the request:
gkit --profile my-app gsc api call \
--operation-id gsc.properties.list \
--input '{}' \
--out ./gsc-properties-plan.json \
--dry-runRemove --dry-run only when the profile and request are correct:
gkit --profile my-app gsc api call \
--operation-id gsc.properties.list \
--input '{}' \
--out ./gsc-properties.jsonArtifacts use no-replace behavior by default. Choose a new output path for a
later run, or add --force only after reviewing the existing destination.
DataForSEO operations that can spend money additionally require both
--allow-spend and an explicit --max-spend-usd limit.
HubSpot uses one profile-bound private-app access token and calls the REST API
directly; @hubspot/cli and hs are not runtime dependencies. The V1 surface
uses HubSpot's current 2026-03 date-versioned endpoints and exposes only
reviewed reads. CRM Search remains a POST because that is HubSpot's read API,
but create, update, delete, send, and import operations are inventory-only and
cannot be dispatched.
gkit --profile my-app hubspot doctor
gkit describe --id hubspot.crm.objects.search
gkit --profile my-app hubspot api call \
--operation-id hubspot.crm.objects.search \
--input @hubspot-search.json \
--out ./hubspot-contact-search.json \
--dry-runHubSpot artifacts can contain PII and confidential business data, including
contact and owner names or email addresses, ticket text, event URLs and
properties, object and association identifiers, company or deal details, and
pipeline or property metadata. Results are therefore artifact-only: the CLI
prints a compact envelope and receipt, never the unbounded CRM payload. Keep
artifacts access-controlled and request only the reviewed properties required
for the analysis. Search pages are capped at 200 and one search query cannot
page beyond 10,000 results; other list surfaces use lower reviewed page and
total-result bounds documented by describe.
Agents do not need provider-specific CLIs or their own copies of credentials.
A repository can add the following contract to its AGENTS.md:
## Growth provider access
- Use `gkit` for all growth-provider access.
- The default App profile for this repository is `<app-name>`.
- Before a live request, run `gkit --profile <app-name> <provider> doctor`.
- Discover capabilities with `gkit --schema`,
`gkit docs --provider <provider>`, and
`gkit describe --id <capability-id>`.
- Never read, record, or print provider secrets.The Agent only needs to know that it should use gkit and which App profile owns the task. CLI installation and secret access belong to the machine or runtime.
All former standalone provider and local-tool packages were removed after the
sole CLI consumer explicitly selected a hard cutover. There are no compatibility
aliases or deprecated binaries. Historical behavior evidence remains under
packages/gkit/evals.
bun run eval
bun run check-types
bun run test
bun run verify:package