# treg — the tool catalog for your agent

> **OpenRouter, but for agent tools instead of models.** Point an agent at ONE base URL with ONE
> token and it can do the *job*: ~2,600 catalogued endpoints across ~40 providers (SEO and SERP
> data, backlinks, social and trends, people and company enrichment, ads, scraping) — plus your
> own team's keys, skills and CLIs. Every credential is injected **server-side**; nothing
> sensitive lands on the agent's machine, and every call is audited.

**Ask for the task, not the tool.** You do not need to know which vendor sells backlink data, or
to hold an account with them. Search the catalog for what you want to do, read the price, call it.

Why this exists: the tools an agent needs for real work are behind subscriptions nobody buys for a
single run (Semrush $139/mo, Moz $99/mo, Crunchbase $99/mo, Apollo $59/seat), behind signup walls,
or behind no public API at all — invite-only, partner-only, app-review-only. treg carries those
accounts and bills you fractions of a cent per call.

Two kinds of tool answer to the same token, through the same `/call/`:

- **The catalog** — curated external endpoints, callable by id. If nobody on your team holds a key
  for that provider, treg serves eligible endpoints **on its own key**, metered per call against
  the team's prepaid balance (**$1.00 free** on every new team). No provider signup, no
  subscription.
- **Your own tools** — anything a teammate registered: an internal service, a paid API account, an
  OAuth connection, a vendor CLI, a SKILL.md. Callable by the whole team, with the credential held
  server-side. **Your own key always wins over treg's, and those calls are never metered.**

Multi-tenant: a token = a (user, org) membership; resources are org-scoped.

Base URL: {BASE}
Repo: https://github.com/superdesigndev/tools-registry

## The one mechanic: /call/

Two shapes, one endpoint, one token.

**A catalog endpoint** — use its id, and treg picks the credential (yours if you have one, its own
if you don't):

    curl "{BASE}/call/tikhub.tiktok.user.profile?uniqueId=tiktok" \
      -H "X-Treg-Token: $TREG_TOKEN"

**One of your own tools** — take the real upstream URL you would normally call and prefix it; treg
resolves the tool by host and injects the credential:

    curl "{BASE}/call/https://api.stripe.com/v1/charges" \
      -H "X-Treg-Token: $TREG_TOKEN"

- The method, path, query string and body all pass through unchanged.
- **Per-org token** (agents/CI): `X-Treg-Token` alone - the org is baked in.
- **Identity token** (from `treg login`): also send `X-Treg-Org: <team-slug>`.
- Equivalent by tool name: `{BASE}/call/<tool-name>/<path>` (e.g. `/call/stripe/v1/charges`).
- The response is the upstream's, verbatim. On a proxy/auth problem treg returns a 4xx/5xx
  with a JSON `detail`.
- If a request **body** carries SQL/HTML and a hosting edge (Cloudflare/Render) 403s it before
  treg sees it, base64-encode the body and add `X-Treg-Body-Encoding: base64` (also `gzip` or
  `base64+gzip`); treg decodes it server-side, so the upstream still gets the real bytes. The
  `treg` CLI does this automatically on a WAF 403 - you only need it over raw HTTP.

## The catalog — tools you do not have a key for

Curated endpoints across ~40 providers, grouped by what they DO: keyword and rank tracking,
backlinks and authority, AI visibility, trending and discovery, publishing to socials, people and
company enrichment, ads management and creative, measurement. Ask for the task; the catalog tells
you which endpoints serve it, what each costs, and how you would be served. Exact live counts:
`GET {BASE}/catalog/platforms`.

Start from the job, not the vendor:

    treg catalog                                    # every platform, busiest first
    treg catalog search "backlinks for a domain"    # find endpoints by what they DO
    treg catalog get tikhub.tiktok.user.profile     # docs, params, PRICE, and how you'd be served
    treg call tikhub.tiktok.user.profile --query uniqueId=tiktok
    # raw HTTP: GET {BASE}/call/tikhub.tiktok.user.profile?uniqueId=tiktok  + X-Treg-Token

**How a catalogued call is served** — the credential ladder, tried in this order. Note the shape:
your own credential always beats treg's, so connecting a key you already pay for makes those calls
free of the balance rather than duplicating them.
1. the org registered its own tool for that provider → that tool, that key;
2. the org stored a secret for the provider → injected via a virtual tool;
3. neither → **treg's own key**, billed per call to the team's prepaid balance. Fractions of a
   cent (a TikTok profile is ~$0.001); every new team starts with **$1.00 free**. No provider
   signup, no subscription.

An endpoint treg has no published price for is **refused**, not served free — you are told to
connect your own key instead.

**Choosing between providers of one capability — the procedure.** `treg catalog get <id>` lists
every provider serving the same job with `COST`, `WORKS` (the success rate treg has actually
observed, with its sample size), `SPEED` (median) and `LAST OK`. Work down this order:

1. **Match the inputs you actually HAVE.** An endpoint wanting a `profile_url` is not a substitute
   when you hold a name and a domain, whatever it costs. This outranks price every time.
2. **Reliability.** A high `WORKS` with a real sample beats a rounder number with a tiny one:
   `99% (121)` is stronger evidence than `100% (8)`.
3. **Price.** Spreads inside one capability reach 200×, so this is usually where the money is.
4. `LAST OK` breaks ties. A bare age means a real call came back; a **`✓` age is the catalog's own
   verification stamp, not live traffic**; `—` means nobody has verified it and nobody has called it.

If a call fails with **429 / 5xx / a timeout, try the next provider** — you know its parameters, so
you can build its request; tell the human which one you switched to. **Never retry a 4xx
elsewhere**: that is usually your parameters, and retrying burns the team's money on N providers for
one mistake.

treg does **not** choose or fail over for you, by design: only you know which inputs you hold, and
treg relays your request rather than rewriting it.

Money rules for agents:
- The price is shown BEFORE you call (`treg catalog get`, or `estimated_cost_usd` in
  `GET {BASE}/catalog/endpoints/<id>/access`). Tell the human the price before spending
  their balance; batch-confirm once for a series of cheap calls rather than per call.
- Out of balance → HTTP **402** with a machine-actionable body: `balance_micro`,
  `estimated_cost_micro`, `topup_url`. Recovery: `treg balance` (ledger), top up in the
  dashboard (Team → Billing), or connect the org's own key for that provider - own keys
  are never billed to the balance.
- `treg balance` shows the prepaid balance and recent charges; the dashboard Activity page
  shows the exact settled cost of every call.

## Your own tools — what your team already has

The catalog is the public half; this half is yours. Anything a teammate registered — an internal
service, a paid API account, an OAuth connection, a vendor CLI — is callable by the whole team with
the credential held server-side, and never metered. Discover what is there:

- CLI: `treg tool ls` - names, hosts, bindings (which credential is injected where).
- API: `GET {BASE}/tools` with your token → JSON list of `{name, base_url, host, bindings}`.
- `GET {BASE}/meta` → `{public_url, github}` (unauthenticated; handy to confirm the base URL).

Your own tools come in two shapes: HTTP APIs (`treg call`, or the URL-prefix form above) and
**command-line tools** (stripe, gh, vercel, gcloud, …) via `treg run` - treg supplies the
credential and runs the CLI, so you use it without owning or logging into it.

    treg run stripe -- balance retrieve        # runs the `stripe` CLI with the org's key injected

Two tiers (`treg run <tool> --local|--server -- <args>`):
- **`--local`** (default) — the CLI runs on YOUR machine. An admin runs `sudo treg setup-local-run` once
  (Linux AND macOS) so the CLI runs under a dedicated `treg-run` user and the key never touches your own
  user; that setup also installs an egress allow-list so the CLI can reach only the registry + catalog API
  hosts (a rogue CLI feature can't send the key elsewhere), and shared-key runs scrub the key from output.
  You can run a tool whose key you own; a teammate's shared key needs the isolated runner (`TREG_RUN_PROOF`).
- **`--server`** — the CLI runs on the registry server (only catalog-known CLIs are allowed there); output
  is streamed back. Use it when the key must never reach your machine at all.

**`treg shell`** — start a subshell where every registered CLI runs with the credential injected
automatically: `treg shell start`, then use `stripe`, `gh`, … normally (no `treg run`); `exit` reverts it.
`--server-for stripe,…` routes named tools to the server; `--ttl N` auto-closes after N minutes.

**`treg <command>`** — the simplest form, and the one to reach for: put `treg` in front of anything
(`treg claude`, `treg codex`, `treg node server.js`, `treg with -- npm test`) and that ONE command runs
with the team's credentials. treg is the parent process, so only that command and its children are
affected: `treg claude` uses shared team access, plain `claude` is untouched and uses your own local
keys. Nothing is written to any config file. A registered host is credentialed by the server; every
other address goes straight out unread. It needs the `cryptography` package: the installer includes
it, and if it is missing treg offers to add it (the right way for how treg was installed) on first use.
**If you are writing Node:** the built-in `fetch` ignores proxy settings before **Node 24**, so a plain
`fetch()` on older Node is NOT captured and your call goes out with no credential. Use a client that
reads the environment (axios, got, undici `ProxyAgent`) or upgrade to Node 24+. curl, git, python
requests/httpx and Deno are captured at any version. Worked example: `examples/proxy-demo/`.

**`treg shell start --proxy`** — the same shell, plus HTTPS calls **you make yourself** to a registered
API are caught and credentialed. Write an ordinary script against `api.stripe.com` with no key and no
treg code; the call goes through the registry, which injects the credential **on the server**, and the
answer comes back unchanged. Only registered hosts are touched — every other address (including
`api.anthropic.com` / `api.openai.com`) goes straight out and cannot be read. It works by setting
`HTTPS_PROXY` and a trust bundle for that shell only; the system trust store is never modified, and no
vendor key ever reaches the machine. `--proxy-port N` moves
the listener off 18791, `--renew-ca` regenerates the machine's local certificate authority. A
certificate-pinned client will refuse the interception and must use `treg run` or `treg call` instead.

**`treg serve`** — the same proxy as a background service, for your own shell instead of a subshell:
`treg serve start`, then `eval "$(treg serve env)"` in any terminal that should use it;
`treg serve status` shows the port and captured hosts; `eval "$(treg serve env --unset)"` leaves it;
`treg serve stop` ends it. `--foreground` for a service manager. The difference from `--proxy`: a
service writes its port + proxy token to `~/.treg/proxy/proxy.json` (mode 0600) so other terminals can
find it — never a vendor key, but a file on disk the subshell version does not have.

A recipe-only skill that's just CLI instructions (e.g. `stripe-cli`) auto-becomes runnable — `treg upload`
recognizes the catalog CLI and wires the credential, so `treg run` works with no `treg.json`.

## Install the CLI

    curl -fsSL {BASE}/install.sh | sh

Installs the `treg` command (Python 3.12+) and points it at this server. Everything below is
also doable over raw HTTP (see the call protocol) - the CLI is just a thin client.

## Get a token

Three human sign-in doors (email is the identity; the door just proves it):

- **GitHub OAuth** - `treg login` (opens a browser).
- **Email one-time code** - `treg login --email you@company.com` (a 6-digit code is emailed).
- **Invite code** - `treg org join <code> --email you@company.com` (creates you + joins a team).

Agents/CI use a **per-org token** directly: `treg login --token <token>`. Get one from
`treg org create` / `treg org join` (returned once), or ask a team owner. The token goes
in the `X-Treg-Token` header on every call. Never share the upstream key - share access.

## CLI command reference (compact)

    treg --version | version                      print the installed CLI version
    treg update                                   upgrade the CLI in place (re-runs the installer)
    treg login [--email E | --token T]            sign in (GitHub default · email OTP · agent token)
    treg logout
    treg onboard [--mode guided|quick]            guided first-run tutorial (seeds a demo team)

    treg org create "Name"                        make a team, become owner
    treg org ls | org use <slug>                  list / switch the active org
    treg org invite <email> --role viewer|member|admin
    treg org join <code> --email you@company.com  accept an invite (creates you if new)
    treg org members | set-role <user_id> <role>  roster / change a role (owner)
    treg org invites | revoke <invite_id>         pending invites (admin+)
    treg org leave | delete <slug>                self-remove / delete (owner, confirm-by-name)

    treg secret add <name> (--value V | --file F | --dir D) [--kind env|oauth|secret_file]
    treg secret ls | rm <id> | update <id> …
    treg tool add <name> --base-url URL (--secret <id> | --bind 'secret=<id>,name=<Header>,…')
    treg add <name> --base-url URL [--secret <name|id>]   convenience shortcut for `tool add` above
                                                          (`tool add` is the canonical command; `add`
                                                          just resolves --secret by name + defaults to Bearer)
                                                          (register NEW keys via a skill bundle by default —
                                                          see Skills — so the tool carries a recipe; never
                                                          store a secret without binding it to a tool)
    treg tool ls | rm <id> | update <id> …
    treg call <tool> <path>  |  treg call <full-url>     proxy an HTTP call (named or agent-native)
    treg calls [--limit N]                        the proxied-call audit log

    treg run <tool> -- <cli args>                 run a vendor CLI (stripe/gh/vercel…) with the tool's
                                                  credential injected — the CLI runs, you never hold the key
                                                    --local  (default) run on THIS machine
                                                    --server run on the registry server (catalog-known CLIs)
    treg runs [--limit N]                         the CLI-run audit log (local + server, tagged where)
    treg shell start [--server-for a,b] [--ttl N] a subshell where registered CLIs inject automatically
      [--proxy] [--proxy-port N] [--renew-ca]     --proxy also catches HTTPS calls YOU make to a
                                                  registered API (needs the [proxy] extra)
    treg shell stop                               leave it (same as `exit`)
    treg serve start|stop|status|env              the same proxy as a background service; point a
      [--port N] [--foreground] [--renew-ca]      shell at it with: eval "$(treg serve env)"
    treg <command> ... | treg with -- <command>   run ONE command with the team's credentials
                                                  (treg claude · treg node app.js); nothing global
    sudo treg setup-local-run [--run-proof V]     one-time admin setup (Linux + macOS): isolate --local
      [--no-egress] [--refresh-egress]            runs under a dedicated treg-run user + egress allow-list

    treg skill init --dir D | skill add --dir D | skill ls | skill rm <id>
    treg skill install <name> [--all] [--dir D]   pull a shared skill's recipe into .claude/skills/
    treg scan [env|skills] [--dir D]              read-only preview: list the keys & skills upload
                                                  would register (nothing leaves the machine)
    treg upload [env|skills] [--dir D] [--select a,b | --all] [--replace] [--llm …]
                                                  bulk on-ramp: scan a .env AND/OR a skills folder,
                                                  auto-register everything you pick (see Upload below)
    treg oauth connect <name> --client-secret S --scopes <scope…>   mint an auto-refreshed OAuth cred
    treg health [--run]                           validate every secret against its tool's health check
    treg admin stats | orgs | users | grant <user_id> | …           super-admin (cross-tenant)

## Roles (what a member may do)

- **viewer** - call any tool + read the inventory. Nothing else.
- **member** - + register secrets/tools/skills, edit/delete their OWN resources.
- **admin**  - + invite/remove members, edit/delete ANY resource in the team.
- **owner**  - + change roles, transfer ownership, delete the team.

## Auth shapes (how a credential is injected)

Chosen per tool binding - `{location: header|query, name, format, secret_field}`:

- **env** - a static key/token, placed via `format` (e.g. `Authorization: Bearer {secret}`
  in a header, or `?api_key={secret}` in the query).
- **oauth** - an OAuth token blob; treg **auto-refreshes** the access token before it
  expires (so calls never hit a 401). Mint the first token with the hosted browser-consent
  flow: `treg oauth connect <name> --client-secret … --scopes …`.
- **secret_file** - a JSON credential (service-account etc.); treg pulls one field
  (`secret_field`, default `access_token`) and injects it.
- **cli_auth** - a credential captured from a local CLI/keychain during setup.

A tool can carry **several** bindings (e.g. an OAuth bearer + a developer-token header);
treg applies every one on each call.

## Skills (register a whole capability at once)

A skill is a folder registered as one bundle - a recipe + its secrets + its tool(s):

    my-skill/
      SKILL.md     what it does (the recipe / how-to)
      .secret/     credential files (values live here; gitignore it)
      treg.json    the contract - REFERENCES to secrets, never the values

`treg skill init --dir ./my-skill` scans `SKILL.md` + `.secret/` and drafts `treg.json`
(guessing the base_url, finding the secrets). Review it, then `treg skill add --dir
./my-skill` uploads recipe + secrets + tool atomically.

Default when adding a NEW key/endpoint/CLI: pair it with a skill — if none exists, create a
basic one (SKILL.md with frontmatter + one example call) so recipe, secret, and tool register
together.

A teammate installs any registered skill onto their machine with
`treg skill install <name>` (or `--all`) - it writes the recipe to `.claude/skills/<name>/SKILL.md`.

## Upload - the bulk on-ramp (`treg upload`; preview with `treg scan`)

Instead of adding tools/skills one at a time, point treg at what you already have. Bare
`treg upload` does **both** doors for the current dir; `treg upload env` / `treg upload
skills` restrict it (`--dir` sets the location).

- **env door** - scans a `.env`, matches each variable against a catalog of ~80 providers
  (served at `GET /providers.json`), and registers the ones you pick as ready-to-call tools.
  Detection reads NAMES only; the value loads just for the keys you confirm. Config vars
  (`*_HOST`, `*_MODEL`) and app secrets (`SECRET_KEY`, `DATABASE_URL`, `*_WEBHOOK_SECRET`) are
  excluded. A `CLIENT_ID`+`CLIENT_SECRET` pair is detected as OAuth (guided connect, not a
  broken bearer). Basic pairs and query-param keys are handled too.
- **skills door** - scans a directory of skills; for each it uses an existing `treg.json` or
  BUILDS one from the skill's script (base_url + the env var it reads), registering API skills
  as tools and knowledge skills as recipe-only bundles - the whole library in one pass.
- Idempotent: re-run any time (skips what's already registered, or `--replace` to update).
- `--select a,b` picks by name · `--all` takes everything · `treg scan` previews (no network,
  no values) · `--llm --llm-token <key>` resolves unknown keys via an OpenAI-compatible model.
- Non-interactive (agent/CI) runs refuse without `--all`/`--select`, so nothing is imported
  unattended by accident.

## For AI agents (Claude Code / Codex / Gemini)

1. **Start from the task.** Need data you have no key for — backlinks, a TikTok profile, a work
   email, ad creative? `treg catalog search "<what you want to do>"` FIRST. Most of it needs no
   key at all, billed to the team balance; read the price before you spend it.
2. You do NOT hunt for API keys. For one of the team's own tools, take the upstream request you'd
   make, prefix its URL with `{BASE}/call/`, add `X-Treg-Token: <token>` (and `X-Treg-Org: <slug>`
   for an identity token), and send it.
3. Discover the org's own tools with `treg tool ls` or `GET {BASE}/tools`.
4. Prefer a **per-org token** for an agent (scoped to one team), not a human identity token.
5. The registry records who called what - calls are attributed to the token's user.
6. Registering a new key/endpoint/CLI? Default to the skill path (`treg skill init` +
   `skill add`, or `POST {BASE}/skills`) — create a minimal SKILL.md (with frontmatter) if
   none exists. Bare `secret add` + `tool add` only when a recipe adds nothing, and never
   leave a secret unbound to a tool.

Example (an agent calling Intercom with no key on its box):

    curl "{BASE}/call/https://api.intercom.io/me" -H "X-Treg-Token: $TREG_TOKEN"

## Docs & tutorials (links)

- [Interactive tutorial]({BASE}/tutorial): the whole registry hands-on - teams, roles,
  the proxy, tools, skills, auth shapes, admin. Command + expected output per step, plus
  reference panels; deep-link a panel with `#concepts` `#roles` `#auth` `#skills`.
- Two focused tutorials, plain markdown (also interactive cards in the dashboard Help → Tutorial):
  [Import & shell]({BASE}/tutorial-import-shell.md) - turn the CLIs on a machine into team tools
  (`treg scan/upload clis`), shell mode (`treg shell`), and the local-run security sandbox; and
  [Team access control]({BASE}/tutorial-access.md) - which tools each member may use + the
  local-run on/off dial.
- [The official Claude skill]({BASE}/skill.md): the 3-persona (consumer/creator/admin) skill —
  save it to `~/.claude/skills/tools-registry/SKILL.md` (install.sh does this automatically).
- [Web dashboard]({BASE}/): sign in and manage everything in the browser (tools, secrets,
  invites, Try-it, activity, admin). It also has a guided first-run and a screenshot tour.
- [README](https://github.com/superdesigndev/tools-registry/blob/main/README.md): overview,
  quickstart, architecture.
- [USAGE / CLI reference](https://github.com/superdesigndev/tools-registry/blob/main/USAGE.md):
  every command with examples.
- [Design docs](https://github.com/superdesigndev/tools-registry/tree/main/docs/context):
  per-subsystem fragments (proxy, auth/secrets, API, CLI, dashboard, multi-tenancy).

## Notes

- Always read the live `{BASE}/meta` for the current `public_url`, and re-fetch this file at
  `{BASE}/llms.txt` — the catalog grows and prices are re-checked.
- Registered upstreams grow over time - treat `treg tool ls` / `GET /tools` as the source
  of truth, not this file.
