MCP server
On this page
@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.
Connect from Claude#
The hosted MCP server is https://saaspro.dev/api/mcp. It works in Claude web, Desktop, mobile, Cowork and Claude Code using OAuth; no access token needs to be copied into a chat or configuration file.
- Open SaaS Pro Max in Claude's connector directory.
- Choose Connect. The published connector uses automatic OAuth registration.
- If you use another deployment, add its
/api/mcpaddress as a custom connector instead. - Sign in to SaaS Pro Max with Google and verify your passkey.
- Review the requesting application and its return address, choose one organization and access level, enter a reason, and approve the connection.
- Ask: “List my SaaS Pro Max applications,” or “Compare this week's traffic and errors with last week.”
New here? Create a free workspace before connecting. The coding agent connection guide introduces the available clients and example tasks. It is also linked during sign-up and under Account → Coding agents and MCP.
Your organization role must allow access-token creation (tokens.write). A
free SaaS Pro Max workspace is sufficient; individual tools still require the
relevant module, plan, permission and data. Connect again to choose a different
organization. The connection cannot cross into your other organizations.
For Claude Code:
claude mcp add --transport http saaspro https://saaspro.dev/api/mcp
Run /mcp in Claude Code to complete authentication. Other remote MCP clients
can use the same endpoint with OAuth dynamic client registration and PKCE S256.
Only public OAuth clients (token_endpoint_auth_method: none) are supported.
Coding tools and other assistants#
Choose your client for copyable setup instructions. The hosted server uses Streamable HTTP and OAuth with dynamic client registration. Use a current client version and finish the browser sign-in before asking for your applications.
| Client | Official setup documentation | Authentication |
|---|---|---|
| Claude Code | MCP | /mcp inside Claude Code |
| Codex | MCP | codex mcp login saaspro |
| Cursor | MCP | MCP settings sign-in |
| Cline | MCP | Server OAuth flow; CLI: cline mcp → Authorize OAuth |
| OpenCode | MCP servers | opencode mcp auth saaspro |
| Hermes Agent | MCP | hermes mcp login saaspro |
| OpenClaw | MCP CLI | openclaw mcp login saaspro |
| Factory / Droid | MCP | /mcp inside Droid |
| VS Code / Copilot | MCP servers | Start the server and complete sign-in |
| Gemini CLI | MCP servers | /mcp auth saaspro inside Gemini CLI |
Instructions were checked against official documentation on October 9, 2026. These are direct MCP connections, not directory listings in every client. Client support does not mean every version or configuration has been tested with SaaS Pro Max. For a client without the hosted authentication flow, use the local installation below.
Access levels#
Read-only access is selected by default. Choose write or admin only when the
assistant needs those tools. The consent screen names each requested scope: read for reports and data,
write for module changes, admin for ingestion-key operations, and
offline_access for refresh credentials. Scopes never override your role.
The connector does not authorize payments, organization deletion, member
administration or other operations that require a fresh console passkey.
Disconnect and privacy#
Revoke MCP connection in Account → Personal access tokens to immediately stop both access and refresh credentials, then disconnect it in Claude. Access tokens expire after one hour; refresh credentials rotate on every use and the connection expires after 30 days. Reusing a consumed code or refresh credential revokes the connection. Revocation, membership changes and current permissions are checked server-side on subsequent calls.
The connector shares only requested tool arguments and the resulting data with
your chosen MCP client. PII remains permission-gated. SaaS Pro Max does not
receive the surrounding Claude conversation; ask_saaspromax sends the explicit
question to the platform assistant, whose configured model provider processes
it under the existing assistant settings. Authorization and tool mutations are
audited. OAuth codes and credentials are stored as hashes, never plaintext.
See the privacy policy and contact
hello@saaspro.dev for support.
Troubleshooting#
- Sign-in opens again: sign in with Google, then complete or refresh the passkey step; approval requires a passkey verified within 30 minutes.
- Requested scope is unavailable: ask an organization owner to check your role; the connector cannot grant permissions you do not already have.
- A module is disabled or a report is empty: enable the module and send data from an application before asking for its report.
- Connection expired or refresh replay detected: disconnect and reconnect.
- Registration fails: select automatic registration. This server advertises dynamic registration, not Client ID Metadata Documents.
Local installation#
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 | Public and secret keys by prefix and last4 — never the value |
create_api_key | admin | Create a public or secret key, shown once |
get_install_instructions | read | Framework tracking code 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 |
get_meta_ads_overview | read | Meta ad spend, clicks, results, 6/12/24 h windows, budgets, issues |
list_meta_ads | read | Every Meta ad with creative, hook and hold rate, and its site funnel |
get_meta_ads_breakdowns | read | Meta ads by placement (with site engagement), platform, device, country, age, gender |
list_meta_ads_issues | read | Rejected or stuck ads, wasted placements, excluded placements still spending, likely bot visits |
get_cookieless_status | read | Received cookieless data and installation prerequisites, per app/environment |
get_cookieless_report | read | Daily visitor estimates, history and permission-filtered breakdowns |
get_cookieless_install_instructions | read | Server integration contract; no tracking toggle or secret values |
get_api_capabilities | read | Search the live API and inspect an operation's full schema |
read_api_operation | read | Execute a discovered read operation, including read-only POST queries |
execute_api_operation | write/admin | Execute a discovered API write with existing authorization and audit |
list_commands | read | Discover all shared console actions by feature |
get_command_schema | read | Inspect input fields, permissions and approval requirements |
prepare_command | write/admin | Prepare exact inputs and return a member approval URL |
get_command_authorization | write/admin | Inspect this token's approval and execution status |
execute_command | write/admin | Execute an approved command once, retaining domain safeguards |
ask_saaspromax | write | Ask the platform assistant in natural language; changes come back as proposals to approve |
The discovery tools read the current OpenAPI contract on each call, so new
Management API operations do not require another hand-written MCP wrapper.
Search first, inspect the exact operation ID, then pass its named path, query
and body parameters. Application settings use patchAppsByApp: read get_app
first and send only changed fields. Module arrays replace the full list.
Protected operations listed with consoleOnly: true name the shared command
that performs them as command and use the
shared command workflow: inspect that command's
schema, prepare the exact inputs, let the member approve with a fresh passkey,
then execute once. The connector cannot approve its own actions. Routine
commands, marked execution: direct, run with execute_command and no
approval.
There are 44 MCP tools, 238 API operations and 239 shared commands.
Code installation in another
website is a deployment task, not an application setting.
For Cookieless visitors, call get_cookieless_status for every app. This report
has no on/off setting: Analytics must be enabled and the site's server must
send events to the dedicated endpoint. cookieless: true and
privacyMode: ephemeral in the browser SDK are different collection modes.
The get_install_instructions tool now also accepts React Native, Expo, WordPress and
privacyMode for the supported frameworks.
Every dedicated 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.
readscope can ask, and can watch proposals appear, but not approve them. - The dedicated approval endpoint rejects a
destructiveaction withpasskey_required. Use theai.decide-actionshared command to obtain the member's exact passkey approval and execute through the protected handler.
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 tracking code 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.
writeadds module data.adminadds public and secret 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
developerrole. 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 create 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. - Public and secret keys are shown once.
create_api_keyreturns 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-apiwith 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