Documentation menu

MCP server

@saaspro/mcp puts SaaS Pro Max inside Claude Code, Claude Desktop, Cursor or any other Model Context Protocol host. The agent can then read your analytics, triage your errors, roll out a flag, and install the SDK into a codebase — with the same permissions the person holding the token has in the console.

It is a thin shell over the Management API: no state, no cache, no stored credential. Every authorization decision is made by the platform, so nothing about your security posture depends on the agent.

Install

claude mcp add saaspro --env SPM_TOKEN=spm_pat_xxxxxxxx -- npx -y @saaspro/mcp

Or write the configuration yourself. Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows):

{
  "mcpServers": {
    "saaspromax": {
      "command": "npx",
      "args": ["-y", "@saaspro/mcp"],
      "env": {
        "SPM_TOKEN": "spm_pat_xxxxxxxx",
        "SPM_HOST": "https://saaspro.dev"
      }
    }
  }
}

Cursor takes the same object in .cursor/mcp.json (per project) or ~/.cursor/mcp.json (global). VS Code uses .vscode/mcp.json with "type": "stdio".

Variable Required Default Meaning
SPM_TOKEN yes spm_pat_… personal or spm_org_… organization token
SPM_HOST no https://saaspro.dev API origin; only preview environments change it

Get a token from Organization → Access tokens (belongs to the team) or Account → Personal access tokens (acts as you).

Tools

Tool Scope What it does
list_organizations read Organizations this token reaches, with its role in each
list_apps read Applications in one organization, with modules and environments
create_app write Create an application and its three environments
get_app read One application's settings and enabled modules
list_api_keys admin Ingest keys by prefix and last4 — never the value
create_api_key admin Mint a public or secret ingest key, shown once
get_install_instructions read Framework snippets with the real key prefix
get_analytics_overview read Visitors, pageviews, sessions, bounce rate, conversions, with deltas
get_timeseries read One metric bucketed over time
get_breakdown read Top pages, sources, campaigns, geo, devices, event names
get_retention read Weekly or monthly cohort retention
get_active_users read DAU, WAU, MAU and stickiness
list_events read The raw event feed, filtered
list_event_names read Event names with counts and unique users
list_funnels read Saved funnels and their steps
create_funnel write Save an ordered funnel
get_funnel_results read Per-step conversion and drop-off
search_people read Person search by text, stage, tag or segment
get_person read One person's dossier
update_person write Stage, tags and CRM fields
list_errors read Error issues by status
get_error read One issue with daily counts, releases and tags; with eventId, one occurrence in full (frames, breadcrumbs, tags, extra, request)
update_error_status write Resolve, ignore or reopen an issue
list_metrics read Metric names, kinds and units
get_metric_series read One metric aggregated, with label filters
list_flags read Feature flags and their rollouts
upsert_flag write Create or replace a flag definition
create_alert_rule write Alert on a metric, error rate, uptime, vital or event volume
list_incidents read Alert incidents, open first
list_campaigns read Campaigns with status counts and delivery statistics
get_campaign_stats read One campaign with sent, delivered, opened and clicked
get_revenue_overview read MRR, ARR, movement, payments
ask_saaspromax write Ask the platform assistant in natural language; changes come back as proposals to approve

Every app-scoped tool takes app, which accepts an application id or the orgSlug/appSlug form list_apps returns.

ask_saaspromax is the escape hatch: it runs the platform's own tool loop and returns a written answer with the tools it used. Prefer a specific tool when you know what you need — it is cheaper, and the raw data is easier to reason about.

When the assistant wants to change something

The platform assistant can act, not only read, so ask_saaspromax has two kinds of outcome. A question that only needs reads comes back as an answer. A question that would change something comes back as an answer plus one or more proposed actions, each with an id, the tool it would call, its arguments, its effect (write, destructive or external) and a human-readable preview of the change. Nothing has been written at that point.

Approving is a separate call, against the assistant endpoints:

curl -X POST -H "Authorization: Bearer $SPM_TOKEN" -H 'content-type: application/json' \
  -d '{"reason":"Agreed in the release channel"}' \
  "$SPM_HOST/api/v1/apps/acme/site/ai/actions/act_1/approve"

GET /apps/{app}/ai/actions lists what is waiting, and /reject declines one with a reason. Approving executes the action, writes the audit row and resumes the conversation, so a later ask_saaspromax in the same conversation can report the outcome.

Two limits apply to an MCP host in particular:

  • A token that could not perform the action itself cannot approve it. read scope can ask, and can watch proposals appear, but not approve them.
  • A destructive action — a deletion, a revocation, a production write, minting a key — cannot be approved through the API at all. It needs a fresh passkey, which only a console session has, so the endpoint answers 403 with passkey_required and a person finishes it in the console.

The design is deliberate: an agent may propose, a person disposes. If your host wants direct writes instead, use the specific tool (upsert_flag, update_error_status, update_person) with a write-scoped token — those act as the token's owner and need no approval.

Resources

saaspro://docs/{slug} serves the deployment's own documentation as markdown: SDK guides, module references, integration setup, the API reference. The list comes from GET /api/v1/docs, so it always matches the platform the token points at rather than a snapshot bundled with the server.

Prompts

Prompt Arguments What it does
integrate_app org?, app? Detect the framework, pick or create an application, install the SDK, wire identify, track, errors, metrics and a flag, then verify events arrive
weekly_report app, range? Traffic, acquisition, funnels, reliability and revenue for a week, against the previous week
investigate_error app, issueId? Read an issue, judge blast radius, find the code, propose a fix, resolve it

The agent skills go further: they carry per-framework reference snippets and an output template, and they trigger on what you ask for rather than needing to be picked from a menu.

Security

  • Scope the token to the job. A read-only token is enough for reporting and error triage. write adds module data. admin adds ingest keys — give it only when the agent is genuinely installing an SDK.
  • Tokens are organization-scoped. An organization token reaches exactly one organization with the developer role. A personal token acts as its owner and reaches that owner's organizations, each with its own role permissions. Neither can delete an organization or an application, change members, or mint further tokens: those need a console session with a fresh passkey.
  • Nothing is stored on your machine. The token is read from the environment and forwarded as a bearer credential. It is never written to disk, never logged, and never included in a tool result. The server logs to stderr only — stdout carries JSON-RPC.
  • Personal data stays gated. Emails and names are masked unless the token's bearer holds people.pii.read.
  • Ingest keys are shown once. create_api_key returns the value in that one response; only a hash is stored. Put it in an environment file, never in source and never in a chat transcript.
  • Every write is audited as an action by the person the token belongs to, tagged via: management-api with the token's id — so a leaked token's blast radius is always answerable.
  • Revocation is immediate. Revoke in the console and the next tool call fails; a personal token also dies the moment its owner leaves the organization.

Troubleshooting

Symptom Cause
SPM_TOKEN is not set on start The host did not pass the environment; check env in the config
Every tool answers unauthorized The token is revoked, expired, or from another deployment — check SPM_HOST
insufficient_scope The token's scope is too narrow; mint one with write or admin
forbidden naming a permission The bearer's role lacks it, or the application has the module off
not_found for an application you can see in the console This token's organization does not contain it

Debug against a real deployment with the inspector:

SPM_TOKEN=spm_pat_xxxxxxxx npx @modelcontextprotocol/inspector npx -y @saaspro/mcp