StartConceptsPlaybooksFeature docsAPI & MCPChangelog
← All feature docs
Feature docs · /settings/api-keys

Advanced: API Keys & MCP

The power-user path. The default product needs no key: connect your tools and it runs on a schedule. If you want to drive your account from your own scripts or an MCP-compatible agent, issue a Bearer token and your brain becomes scriptable. Six tools cover the verbs that matter: log a capture, update a prospect, append to a plan, mark a meeting outcome, read an account, pull a brief.

Overview

This is an advanced option under Settings, Advanced, not the main flow. Most people never need it: connect your CRM, inbox, and calendar on Connect and the work runs on a schedule. If you want to script your account, the API keys surface turns it into a tenant-scoped MCP server. Issue a key at /settings/api-keys, point any MCP client at your account, and tools/list returns 27 tools. Every write hits the same panel_data store the in-app surfaces use, so scripted and in-product activity stay in sync. The cards below cover the ones you reach for first; ask your client for the full list rather than trusting this page to stay current.

Different from Connect your tools, that page links your CRM, inbox, and calendar for the scheduled runs. API keys are the credential for the advanced, self-driven path.

How it helps you

How to use it

  1. Open /settings/api-keys, click + New key.
  2. Name it (e.g. "nightly brief"), pick the scopes the agent needs.
  3. Copy the key, it's shown once. Paste it into the agent's credential field.
  4. Point the agent at https://<your-domain>/api/v1/mcp as the MCP server URL.
  5. The agent calls tools/list to introspect, then tools/call to invoke. Every call lands in your audit log.

The six tools

// capture.write

log_capture

Drop a free-form note or transcript into the brain. Optionally attach to an account or prospect.

// prospect.write

update_prospect

Create or update a prospect (name, title, email, notes, arbitrary fields).

// plan.write

add_to_plan

Append content to a named section of an account plan ("next_steps", "risks", "champion_notes").

// meeting.write

mark_meeting_outcome

Record the outcome of a meeting ("advance" / "stall" / "lost" or free-form) with notes + next step.

// account.read

read_account

Read an account record. Optionally pull in the plan, recent meetings, or recent captures.

// brief.read

pull_brief

Structured "today / week" summary, accounts active, recent captures, recent meetings, open plan sections.

// usage.write

POST /api/ingest/usage

Push product-usage / consumption data for an account by domain (seats used, active users, contract terms, usage signals). A vendor-neutral REST endpoint, point your warehouse job or ETL at it and the pre-call brief renders consumption-vs-contract, each line cited to the ingested telemetry.

// meddpicc.write

set_meddpicc

Put MEDDPICC evidence on an opportunity by id, any of the eight dimensions as short text. Provided dimensions merge onto the existing record; others are left untouched. This is how a deal earns the evidence the curiosity engine reads to find the gaps worth asking about, without a CRM.

Control-plane tools

Five more tools cover the control plane: check the session, check a licence, report run telemetry, push brain state, pull config. They need no extra scope, a valid key acting on its own account is enough.

Your own client is what calls these. The scheduled runs do not: they run inside our servers and write the same tables directly, so nothing in your rollup depends on an agent remembering to report. The descriptions below say "every skill" because they are written for a skill you drive over MCP.

// session

verify_session

Returns the account, plan, and entitled products. Every skill calls this first and stops if it errors.

// license

check_entitlement

Is this account licensed for a named product? Skills stop and ask the user to connect their account if not.

// telemetry

emit_telemetry

Record a run event, product, skill, counts, outcome, duration. Metadata only. Powers the Activity rollup.

// brain

sync_brain

Push brain state for a scope (signal-weights, icp-registry, decision-log, funnel-brain, ...).

// config

pull_config

Pull the account's plan, entitled products, and feature flags so a skill can adapt at run start.

These back the per-account Activity rollup. The full contract, every tool with its arguments and scopes, is on API & MCP.

Entitlement is enforced per tool. Any tool that reads or writes your data or brain, the six data verbs plus emit_telemetry, sync_brain, start_run, run_heartbeat, connect_integration, and the studio tools, requires the account to hold at least one active paid entitlement (a product, bundle, suite, membership, or team seat). Without one, the server returns not_entitled (MCP error -32003 / HTTP 403) with a pointer to /pricing. The onboarding trio stays open on purpose: verify_session, check_entitlement, and pull_config are always callable so a new user can connect and check status before buying. Entitlement is additive to the scope check, a call must clear both.

Security model

Use cases

// your agent

Wire your own client

Have your agent log captures and update prospects as you work, your brain stays current without context-switching.

// scripts

Cron-driven workflows

A nightly script pulls your brief, summarizes it, posts to Slack. Or a meeting bot logs the outcome into your account plan automatically.

// custom agents

Build your own agent

Wire any agent loop to the MCP server. Tools/list discovers everything; you don't ship custom integrations.

// team automation

Team-wide workflows

An ops team can issue per-process keys ("post-call writer", "weekly forecaster") with the minimum scopes each needs.

Transports: HTTP, REST, and stdio

HTTP is the canonical MCP transport, point any HTTP MCP client at /api/v1/mcp. Every tool is also a plain REST endpoint (below). For clients that only speak stdio, the repo ships a thin local bridge that forwards stdio JSON-RPC to that same HTTP endpoint:

  1. Issue a key here and set it as SALES_AS_CODE_API_KEY.
  2. Run npm run mcp:stdio, or point your stdio client's config at node scripts/mcp-stdio.mjs with the key in the server's env block.
  3. The bridge relays each message to /api/v1/mcp, same tools, same scopes, same audit log. It holds no logic of its own.

Full config example: /docs/api, stdio.

Team keys

By default a key is per-user, it authorizes against your own plan. A team owner can toggle Issue as a team key in the New key dialog to mint a team key instead. A team key still writes into the owner's workspace, but the control-plane tools (verify_session, check_entitlement, pull_config) resolve entitlements against the team's plan: the union of the owner's grants and every product the team's seat packs license. Per-user keys are unchanged and keep working exactly as before.

OAuth-provider mode (optional)

Pasting a key is the default for this advanced path. When a deployment enables it (MCP_OAUTH_ENABLED=true), a client can instead obtain access through a standard OAuth 2.0 authorization-code + PKCE flow, you approve it on a consent screen using your existing login, and the client never sees a key you had to copy. The clever part: the OAuth access token is a managed key. It's minted as a scoped api_keys row, shows up in this list as OAuth (<client>), and you revoke it here like any other.

The HTTP REST surface

The same tools are also available as plain REST endpoints if you prefer not to speak MCP. POST JSON to /api/v1/tools/<name> with a Bearer auth header. Same Bearer key, same scopes, same audit log.

curl -X POST https://salesascode.com/api/v1/tools/log_capture \
  -H 'authorization: Bearer sak_…' \
  -H 'content-type: application/json' \
  -d '{"source":"script","text":"Acme champion confirmed budget for Q3"}'

Related

// deep walkthrough · 2 min