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:
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.
| Method | When to pick it | Bearer prefix |
|---|---|---|
| API key | Single agent on a single machine, or a server-to-server integration. Fastest to set up. | sta_… |
| OAuth 2.1 | End-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
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:
Authorization: Bearer sta_••••••••••
Or use the x-api-key header if your client doesn't support custom Authorization values:
x-api-key: sta_••••••••••
Bearer prefix is required (RFC 6750)
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
| Purpose | URL |
|---|---|
| Dynamic Client Registration (DCR) | https://app.stablebaseline.io/oauth/register |
| Authorization endpoint | https://app.stablebaseline.io/oauth/authorize |
| Token endpoint | https://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.
| Scope | Grants |
|---|---|
org_admin | Update organisation settings (admin only). |
org_billing | Subscription, cancellation, seat changes, credit purchases (preview-confirm-deduct). |
org_members | Invite, role change, deactivate, remove members; workspace membership. |
org_teams | Team CRUD and per-workspace access grants. |
org_permissions | Resource-permission CRUD with 3-state inheritance overrides. |
org_settings | Org-level settings (JSONB merge) and feature-flag toggles. |
kg_admin | Knowledge-graph scope, ingest, batch control, rebuild. |
lifecycle | Create / 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.
| Flag | Required for |
|---|---|
can_admin_org | updateOrganisation, updateOrgSettings |
can_manage_billing | Subscription, cancellation, credit purchase, seat-change tools |
can_manage_members | Invite, role change, deactivate, remove; workspace membership |
can_manage_teams | Team CRUD + workspace access grants |
can_manage_perms | upsertResourcePermission and friends |
can_manage_kg | All kg_admin tools (scope, rebuild, batch control) |
can_lifecycle | createWorkspace, createProject, updateWorkspace, updateProject |
Common pitfall
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.
// 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
applyXwith the same token returnstoken_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:
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.