HubSpot team runbook — WBR CLI
Goal: Anyone on GTM / RevOps can run the versioned, reviewed weekly HubSpot WBR dry-run from brainforge-platform without a single owner. Secrets stay in 1Password / env — never in git.
Canonical path: knowledge/sales/crm/hubspot/ (GTM / RevOps). Deeper integration docs (MCP, architecture, Linear enrichment) live under knowledge/platform/integrations/hubspot/.
What you use when
| Situation | Tool |
|---|---|
| Browse / answer questions in chat | HubSpot MCP in Cursor (default for agents) — see hubspot-api-setup.md and HUBSPOT_MCP_SETUP_STEPS.md |
| Weekly WBR HubSpot evidence (markdown summary) | REST API (volume / sheet-shaped output) via npm run hubspot:wbr:* from repo root (this doc) |
One-time setup (per machine)
1. Repo up to date
cd /path/to/brainforge-platform
git pull origin main
node scripts/ensure-git-submodules.mjs2. Node
Use Node 18+ (repo root lists 22.x for deploy; local 18+ is fine for these scripts).
3. TLS (macOS / some corporate networks)
hubspot:wbr:dry-run:op runs through tools/hubspot-api-service/scripts/hubspot-op-run.mjs, which sets NODE_EXTRA_CA_CERTS=/etc/ssl/cert.pem on macOS when that file exists and the variable is not already set.
If you still see unable to get local issuer certificate, set it yourself (or point at your corporate bundle):
export NODE_EXTRA_CA_CERTS=/etc/ssl/cert.pem4. HubSpot API dependencies
One-time install for tools/hubspot-api-service:
npm run hubspot:install5. Token (shared automation private app)
The token lives in 1Password — see hubspot-api-setup.md and 1password-cli-setup.md.
Preferred: 1Password CLI (op run)
-
Install and sign in:
op signin. -
In
tools/hubspot-api-service/:cp op-run.env.example op-run.env -
Edit
op-run.envsoHUBSPOT_ACCESS_TOKEN=op://…points at your vault/item/field (op item list --vault "Brainforge AI Team" | grep -i hubspot). -
From repo root:
npm run hubspot:wbr:dry-run:op
op-run.env must contain only op:// references (no raw pat-…). It is gitignored at the repo root.
Fallback: export or .env
export HUBSPOT_ACCESS_TOKEN="pat-na1-…"Optional: tools/hubspot-api-service/.env from .env.example, or brainforge-platform/.env — the HubSpot client loads repo root first, then service (service wins if both set a value). Do not commit tokens.
Why WBR could miss the token before: Scripts that used dotenv/config only read .env from process.cwd(). If you ran from the repo root while the token lived only under tools/hubspot-api-service/.env, it was never loaded. The shared client now loads from fixed paths so npm run hubspot:wbr:dry-run behaves the same regardless of cwd.
Commands (from repo root)
| Command | What it does |
|---|---|
npm run hubspot:install | npm install inside tools/hubspot-api-service |
npm run hubspot:wbr:dry-run | WBR weekly dry-run; expects HUBSPOT_ACCESS_TOKEN in the environment or .env. Writes tools/hubspot-api-service/output/wbr-dry-run-latest.md (gitignored). |
npm run hubspot:wbr:dry-run:op | Same as above with op run and op-run.env. Pass script args after --, e.g. npm run hubspot:wbr:dry-run:op -- --monday=2026-04-06 |
Example
npm run hubspot:wbr:dry-run:op -- --monday=2026-04-06Weekly [Actual] WBR workflow
- Skill:
.cursor/skills/gtm-wbr-weekly-actuals/SKILL.md - Spec:
knowledge/sales/gtm/wbr-actual-weekly-spec.md - Metric definitions:
knowledge/sales/gtm/wbr-metric-source-map.md
Gate 1 = evidence tables only (no sheet write); Gate 2 = publish after explicit approval. Mostly Google MCP + HubSpot MCP; use hubspot:wbr:dry-run:op when you want a sheet-shaped HubSpot summary in markdown.