MCP & agents

Setup and authentication.

Two production auth methods — API key or OAuth 2.1 — both backed by the same per-credential permission model. Pick one, point your client at the endpoint, verify the connection.

The endpoint

All MCP clients point at the same URL:

uri
https://api.stablebaseline.io/functions/v1/cloud-serve/mcp

Auth methods

Stable Baseline accepts two credential types. Both produce the same McpClientContext server-side, so every tool behaves identically once the bearer is validated.

MethodWhen to pick itBearer prefix
API keySingle agent on a single machine, or a server-to-server integration. Fastest to set up.sta_…
OAuth 2.1End-user signs the agent in. Supports Dynamic Client Registration so your client can self-register.JWT

Option A · API key

In the Stable Baseline web app, open Settings → MCP keys and click Generate new key. Give it a descriptive name (e.g. laptop-claude) and scope it: pick the workspaces and projects this agent should be able to touch, and tick the organisation capabilities the agent needs (see below).

Never share or commit keys

Keys are shown once and start with sta_. Copy the key to your OS keychain or your MCP client's secret store. Rotate per agent per machine — don't share keys.

Send the key as a bearer token:

http
Authorization: Bearer sta_••••••••••

Or use the x-api-key header if your client doesn't support custom Authorization values:

http
x-api-key: sta_••••••••••

Bearer prefix is required (RFC 6750)

The Authorization header must start with the literal string Bearer (note the trailing space). Sending a raw token without the prefix is rejected with HTTP 401. Use x-api-key instead if you need a header without a scheme prefix. Same key, same scopes, same rate limits.

Option B · OAuth 2.1

OAuth is the right choice when an end user wants to sign their agent in themselves. Stable Baseline supports Dynamic Client Registration (RFC 7591), so well-behaved MCP clients can register and start the flow without any manual configuration.

OAuth endpoints

PurposeURL
Dynamic Client Registration (DCR)https://app.stablebaseline.io/oauth/register
Authorization endpointhttps://app.stablebaseline.io/oauth/authorize
Token endpointhttps://app.stablebaseline.io/oauth/token
Public manifest (machine-readable)https://stablebaseline.io/.well-known/mcp.json

OAuth scopes

Each scope maps 1:1 to an organisation capability flag. Request only what the agent needs — the consent screen mirrors the API-key UI, so the user sees the same toggles either way.

ScopeGrants
org_adminUpdate organisation settings (admin only).
org_billingSubscription, cancellation, seat changes, credit purchases (preview-confirm-deduct).
org_membersInvite, role change, deactivate, remove members; workspace membership.
org_teamsTeam CRUD and per-workspace access grants.
org_permissionsResource-permission CRUD with 3-state inheritance overrides.
org_settingsOrg-level settings (JSONB merge) and feature-flag toggles.
kg_adminKnowledge-graph scope, ingest, batch control, rebuild.
lifecycleCreate / update workspaces and projects (delete is browser-only).

Organisation capabilities

Both auth paths surface the same seven organisation-capability toggles when the credential is created (the OAuth consent screen and the API-key UI share one component). They're mandatory for any tool that touches the corresponding domain — without the flag, the relevant tools return accessDenied.

FlagRequired for
can_admin_orgupdateOrganisation, updateOrgSettings
can_manage_billingSubscription, cancellation, credit purchase, seat-change tools
can_manage_membersInvite, role change, deactivate, remove; workspace membership
can_manage_teamsTeam CRUD + workspace access grants
can_manage_permsupsertResourcePermission and friends
can_manage_kgAll kg_admin tools (scope, rebuild, batch control)
can_lifecyclecreateWorkspace, createProject, updateWorkspace, updateProject

Common pitfall

Minted a key and the agent gets accessDenied on member tools? Probably forgot to tick can_manage_members when creating it. Capability flags are off by default — narrow on purpose, not by accident.

Capabilities are a strict ceiling, never an expansion: effective(agent) = user_role ∩ credential_grant. Ticking a flag the underlying user's role doesn't already permit doesn't grant anything — the user's authority always wins.

The estimate-confirm-deduct ritual

Every operation that spends money or credits — subscription change, cancellation, credit purchase, KG scope change, KG rebuild, seat change — uses a two-call contract instead of executing immediately. This keeps agent-driven money and credit moves auditable and reviewable.

ts
// 1. Preview returns a server-minted token plus a human-readable summary.
const { confirmation_token, expires_at, summary } =
  await mcp.previewSubscriptionChange({ tier: "pro", seats: 5 });

// 2. Show the summary to the user, get explicit go-ahead.
//    Then exchange the token for the actual change.
const { applied } = await mcp.applySubscriptionChange({ confirmation_token });
  • Single-use, atomic consume. Replaying applyX with the same token returns token_already_consumed.
  • 10-minute TTL. Long enough for an agent to round-trip with the user; short enough to bound price drift.
  • Stripe idempotency. The token is passed as the Stripe idempotency key, so retries are safe.
  • KG inflation cap. If the actual KG ingest cost exceeds the previewed estimate by more than 10%, the apply call aborts and re-prompts.

Verify the connection

Once configured, your client should list stable-baseline under connected servers. Ask your agent to list the tools:

prompt
What Stable Baseline MCP tools are available?

You should see 180 tools across 18 categories: signup, navigation, folders, documents, diagrams, images, whiteboards, data, improvements, plans, knowledge_graph, organization, members, teams, permissions, billing, kg_admin, settings. If the catalogue is shorter, check your credential's scope and capability flags.