MCP Server
The Sutra MCP server lets AI agents interact with the Admin API through the Model Context Protocol. It works with Claude Desktop, Claude Code, ChatGPT connectors, Cursor, Windsurf, and any other MCP-compatible client.
Prerequisites
API access is included automatically on Silver and Gold accounts.
The MCP server can be used in two ways:
- Hosted remote MCP — add
https://mcp.sutra.co/mcp as a custom remote MCP server in a compatible AI client. The client opens Sutra's OAuth login and consent flow; no local package or token is required.
- Local stdio MCP — run
@sutraspaces/mcp-server locally with npx or a global install. Local setup supports OAuth or a manually created API token.
Local stdio setup supports two ways to authenticate:
- OAuth (recommended) — no token to copy. On first run the server opens your browser, you log in to Sutra and approve access, and the token is cached locally and refreshed automatically. This is the easiest way to get started.
- API token — set the
SUTRA_API_TOKEN environment variable to a token you create under Settings → Sutra API. Best for headless/server environments where a browser isn't available. See authentication.md.
If SUTRA_API_TOKEN is set in a local stdio setup, the server uses it and skips OAuth. Otherwise it uses OAuth.
Hosted Remote MCP
Use this when your AI client supports remote MCP servers or custom connectors.
https://mcp.sutra.co/mcp
Add that URL as a custom remote MCP server in your AI client's connector settings, then sign in to Sutra when prompted. Hosted MCP uses OAuth and the same Admin API scopes as direct API calls. If the OAuth grant has only read scopes, hosted MCP exposes only read tools (list_... and get_... tools). Mutating tools are exposed when the grant includes at least one write/action scope; the Admin API still enforces the exact required scope on every tool call.
Hosted MCP never exposes internal Lotus Help Center or Blog tools. Those tools require server-side internal Lotus credentials and are only available in local/internal stdio setups.
Local Installation
npm install -g @sutraspaces/mcp-server
Or run directly with npx (no install needed):
# OAuth — opens your browser to log in on first run
npx -y @sutraspaces/mcp-server
# Or with an API token (no browser)
SUTRA_API_TOKEN="sutra_live_sk_..." npx -y @sutraspaces/mcp-server
Requires Node.js 18 or later.
Local Authentication with OAuth
When no SUTRA_API_TOKEN is set, the server runs a standard OAuth 2.1 Authorization Code flow with PKCE:
- The server prints a login URL and opens it in your default browser. (If a browser can't open automatically — e.g. over SSH — copy the URL from the terminal.)
- You log in to Sutra and approve the requested permissions on the consent screen.
- The browser returns to a local one-time callback, the server exchanges the authorization code for a token, and caches it.
Your Sutra account must be on Silver or Gold before login will work — the consent screen will tell you if it isn't. Access tokens are short-lived (1 hour); the server holds a rotating refresh token and renews them silently, so you normally log in only once per machine.
Tokens are stored in ~/.sutra/credentials.json (file mode 600). Refresh tokens rotate on every use, so the cache is tied to one machine — don't copy credentials.json to another host.
You can manage credentials directly:
# Log in (or re-authorize) without starting the server
npx -y @sutraspaces/mcp-server login
# Clear cached credentials for the configured issuer
npx -y @sutraspaces/mcp-server logout
By default OAuth grants all scopes your account can authorize. To request a narrower set, set SUTRA_SCOPES to a space-separated scope list (see scopes.md) before logging in.
Local Configuration
| Variable |
Required |
Description |
SUTRA_API_TOKEN |
No* |
Your Sutra Admin API token (sutra_live_sk_...). *Required only if you are not using OAuth. When set, OAuth is skipped. |
SUTRA_OAUTH_ISSUER |
No |
OAuth issuer base URL (default: https://api.sutra.co). Must be https:// (only loopback hosts may use http://). Separate from the Admin API URL. |
SUTRA_SCOPES |
No |
Space-separated scopes to request during OAuth login (default: all scopes your account can authorize) |
SUTRA_CONFIG_DIR |
No |
Directory for cached OAuth credentials (default: ~/.sutra) |
SUTRA_BASE_URL |
No |
Override the API URL (default: https://api.sutra.co/api/admin/v1) |
SUTRA_LOTUS_TOKEN |
No |
Internal scoped admin key (sutra_admin_...) for local/internal stdio Lotus tools. Add help_center:read, help_center:write, blog:read, and/or blog:write to the same key as needed. Not used by hosted MCP. |
SUTRA_HELP_CENTER_BASE_URL |
No |
Override the Help Center API URL (default: https://api.sutra.co/api/v4/lotus/help) |
SUTRA_BLOG_BASE_URL |
No |
Override the Blog API URL (default: https://api.sutra.co/api/v4/lotus/blog) |
SUTRA_HELP_CENTER_TOKEN and SUTRA_BLOG_TOKEN are still accepted as backwards-compatible aliases, but new setups should use one SUTRA_LOTUS_TOKEN.
The MCP server uses the same scopes as direct API calls, whether authenticated by OAuth or an API token. A grant with spaces:read can list admin-manageable spaces through the MCP server; one with membership_spaces:read can list the user's limited membership-space inventory. See scopes.md for the full scope list.
Mutating MCP tools accept an optional idempotency_key argument, which the server forwards as the Admin API Idempotency-Key header. Use a stable key when retrying a write operation after a network failure. Bulk tools and externally side-effecting tools such as send_broadcast require it.
Design tools are available when the token includes the design scopes:
design:read for get_design_capabilities, get_space_design, and get_design_preview_link
design:write for validate_space_design and create_or_update_design_draft
design:publish for publish_design_draft and restore_design_draft
assets:write for import_design_asset
media:read and media:write for Admin media upload tools
Local Setup
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json. With OAuth you don't embed a token — the server opens your browser the first time it starts:
{
"mcpServers": {
"sutra": {
"command": "npx",
"args": ["-y", "@sutraspaces/mcp-server"]
}
}
}
To use an API token instead, add it under env:
{
"mcpServers": {
"sutra": {
"command": "npx",
"args": ["-y", "@sutraspaces/mcp-server"],
"env": {
"SUTRA_API_TOKEN": "sutra_live_sk_..."
}
}
}
}
Tip: if your client doesn't surface the login prompt on first start, run npx -y @sutraspaces/mcp-server login once in a terminal to authorize, then start the client.
Claude Code
# OAuth (opens browser on first run)
claude mcp add sutra -- npx -y @sutraspaces/mcp-server
# Or with an API token
claude mcp add sutra -- env SUTRA_API_TOKEN=sutra_live_sk_... npx -y @sutraspaces/mcp-server
Other MCP Clients
Point your MCP client at npx -y @sutraspaces/mcp-server. The server communicates over stdio. Leave the environment empty to authenticate with OAuth, or set SUTRA_API_TOKEN to use a token.
The MCP server exposes tools for Admin API operations plus a small number of agent-oriented helpers. Tools use the same request parameters, response formats, and public IDs (sp_, mem_, contact_, usr_, etc.) as the REST API documented in openapi.yaml.
Deep Traversal
| Tool |
Description |
get_space_deep |
Recursively fetch a space and all nested content — content blocks, messages, reflections, and child spaces — in one call. Rich text is converted to plain text. Configurable depth, item limits, and reflection inclusion. |
This tool has no direct REST API equivalent. It orchestrates multiple API calls internally and returns a single nested object representing the full space hierarchy. Useful for agents that need to understand an entire course or community at once.
Spaces
| Tool |
API Endpoint |
list_spaces |
GET /spaces |
list_membership_spaces |
GET /me/membership_spaces |
get_space |
GET /spaces/{space_id} |
list_child_spaces |
GET /spaces/{space_id}/children |
create_space |
POST /spaces |
create_child_space |
POST /spaces/{space_id}/children |
attach_child_space |
PUT /spaces/{space_id}/children/{child_space_id} |
update_child_space_placement |
PATCH /spaces/{space_id}/children/{child_space_id}/placement |
detach_child_space |
DELETE /spaces/{space_id}/children/{child_space_id} |
update_space |
PATCH /spaces/{space_id} |
update_space_settings |
PATCH /spaces/{space_id}/settings |
update_space_appearance |
PATCH /spaces/{space_id}/appearance |
set_space_image |
POST /spaces/{space_id}/images |
update_space_payment |
PATCH /spaces/{space_id}/payment |
delete_space |
DELETE /spaces/{space_id} |
reorder_child_spaces |
PATCH /spaces/{space_id}/children/reorder |
Use list_spaces for spaces the token can administer through the Admin API. Use list_membership_spaces for a read-only inventory of spaces where the token user is a member. Membership spaces with admin_access: false still return 404 from admin subresource tools such as list_members.
Use sp_... IDs, not slugs. For normal course and section pages, pass placement.surface = "auto" so Sutra chooses the collection/list surface. To make an existing child visible, use attach_child_space or update_child_space_placement, not create_content.
update_space covers the General settings core (name, description, format, privacy, visibility, member limit, registration gates, behavior flags, shareable link, archive/unarchive). update_space_settings covers behavioral settings (scheduling, notifications, content behavior, display, registration, SEO, members map, Cobolt indexing, list/post display). update_space_appearance covers theme and layout — note a base-color write cascades the parent's full theme to all descendants. set_space_image ingests cover/logo/thumbnail/meta images from a URL. update_space_payment enables or disables paid access (plans system) with guarded preconditions and teardown. get_space returns the detail read with nested settings, appearance, payment, and website objects.
Members
| Tool |
API Endpoint |
list_members |
GET /spaces/{space_id}/members |
get_member |
GET /spaces/{space_id}/members/{member_id} |
add_member |
POST /spaces/{space_id}/members |
update_member |
PATCH /spaces/{space_id}/members/{member_id} |
remove_member |
DELETE /spaces/{space_id}/members/{member_id} |
approve_member |
POST /spaces/{space_id}/members/{member_id}/approve |
bulk_add_members |
POST /spaces/{space_id}/members/bulk |
bulk_remove_members |
POST /spaces/{space_id}/members/bulk_delete |
bulk_update_member_property_values |
PATCH /spaces/{space_id}/members/properties/bulk |
list_members and list_contacts accept member-property filters through property_key / property_value for one filter or a property_filters array for multiple filters. These filters require member_properties:read.
| Tool |
API Endpoint |
list_contacts |
GET /spaces/{space_id}/contacts |
get_contact |
GET /spaces/{space_id}/contacts/{contact_id} |
get_contact_property_values |
GET /spaces/{space_id}/contacts/{contact_id}/properties |
update_contact_property_values |
PATCH /spaces/{space_id}/contacts/{contact_id}/properties |
bulk_update_contact_property_values |
PATCH /spaces/{space_id}/contacts/properties/bulk |
Document Content
Use these tools for visible lesson/page content. They mutate the Tiptap document, then refresh the legacy content-block mirror internally.
Document mutations validate renderer-sensitive node contracts before writing. actionbutton nodes must include a non-empty attrs.buttonText label, and successful replace/insert/update responses may include top-level warnings and repairs arrays for canonicalization such as UID repair, spacing expansion, or button defaults.
| Tool |
API Endpoint |
get_document_capabilities |
GET /document/capabilities |
get_document |
GET /spaces/{space_id}/document |
replace_document |
PUT /spaces/{space_id}/document |
insert_document_nodes |
POST /spaces/{space_id}/document/nodes |
update_document_node |
PATCH /spaces/{space_id}/document/nodes/{node_uid} |
delete_document_node |
DELETE /spaces/{space_id}/document/nodes/{node_uid} |
move_document_node |
PATCH /spaces/{space_id}/document/nodes/{node_uid}/placement |
Use structure tools for space cards and child placement. Generic document tools reject managed space-card nodes so database relationships cannot drift from document JSON.
Special Blocks
Use these tools when you need configurable special blocks without hand-authoring the raw renderer node shape. They cover info_box, icon_text, quote, badge, divider, and contact_form. Pass surface: "document" for the normal visible document or surface: "registration_page" for the editable registration page draft. Contact forms can bind custom fields to member properties; call list_special_block_types with a space_id first to inspect available member_property_bindings.
| Tool |
API Endpoint |
list_special_block_types |
GET /document/special_block_types, GET /spaces/{space_id}/document/special_block_types, or GET /spaces/{space_id}/registration_page/special_block_types |
list_special_blocks |
GET /spaces/{space_id}/document/special_blocks or GET /spaces/{space_id}/registration_page/special_blocks |
get_special_block |
GET /spaces/{space_id}/document/special_blocks/{node_uid} or GET /spaces/{space_id}/registration_page/special_blocks/{node_uid} |
create_special_block |
POST /spaces/{space_id}/document/special_blocks or POST /spaces/{space_id}/registration_page/special_blocks |
update_special_block |
PATCH /spaces/{space_id}/document/special_blocks/{node_uid} or PATCH /spaces/{space_id}/registration_page/special_blocks/{node_uid} |
delete_special_block |
DELETE /spaces/{space_id}/document/special_blocks/{node_uid} or DELETE /spaces/{space_id}/registration_page/special_blocks/{node_uid} |
Registration Pages
Registration page tools edit the draft registration page first. Visitors see the currently published page until publish_registration_page copies the draft live and enables the registration gate. Publishing requires both content:write and spaces:write.
| Tool |
API Endpoint |
get_registration_page |
GET /spaces/{space_id}/registration_page |
replace_registration_page |
PUT /spaces/{space_id}/registration_page |
insert_registration_page_nodes |
POST /spaces/{space_id}/registration_page/nodes |
update_registration_page_node |
PATCH /spaces/{space_id}/registration_page/nodes/{node_uid} |
delete_registration_page_node |
DELETE /spaces/{space_id}/registration_page/nodes/{node_uid} |
move_registration_page_node |
PATCH /spaces/{space_id}/registration_page/nodes/{node_uid}/placement |
publish_registration_page |
POST /spaces/{space_id}/registration_page/publish |
| Tool |
API Endpoint |
create_media_upload |
POST /spaces/{space_id}/media_uploads |
complete_media_upload |
POST /media_uploads/{media_id}/complete |
get_media_upload |
GET /media_uploads/{media_id} |
cancel_media_upload |
DELETE /media_uploads/{media_id} |
create_media_reference |
POST /spaces/{space_id}/media_references |
For local files, call create_media_upload, upload bytes to the returned presigned PUT URL with the returned headers, then call complete_media_upload. Video upload storage currently preserves Sutra's production sutra-froala/uploads/... input convention so the existing video processing pipeline can find the source object.
For external Loom, YouTube, or Vimeo media, use create_media_reference; do not create an upload session for a URL-only embed.
Content Blocks
| Tool |
API Endpoint |
list_content |
GET /spaces/{space_id}/content |
get_content_block |
GET /content/{block_id} |
create_content |
POST /spaces/{space_id}/content |
update_content |
PATCH /content/{block_id} |
delete_content |
DELETE /content/{block_id} |
reorder_content |
PATCH /spaces/{space_id}/content/reorder |
Content block tools are the legacy mirror surface. Prefer Document Content tools for new visible content workflows.
Design
| Tool |
API Endpoint |
get_design_capabilities |
GET /design/capabilities |
get_space_design |
GET /spaces/{space_id}/design |
validate_space_design |
POST /spaces/{space_id}/design/validate |
create_or_update_design_draft |
POST /spaces/{space_id}/design_drafts |
publish_design_draft |
POST /design_drafts/{draft_id}/publish |
restore_design_draft |
POST /design_drafts/{draft_id}/restore |
import_design_asset |
POST /design/assets/import |
get_design_preview_link |
POST /design_drafts/{draft_id}/preview_link |
Use the draft workflow for page designs: read capabilities, read the current design and content_digest, validate proposed nodes, create a draft, call get_design_preview_link to mint a short-lived unauthenticated browser preview, then publish. Publish returns 409 conflict when live content changed or when the draft would remove protected user-owned content without explicit confirmation.
Website
Website mode turns a top-level space into a public website with a header (a navbar) and footer. It is root-scoped (any managed space resolves to its website root) and enabling it requires the Silver plan or above. Enabling auto-creates a default header + footer; author them with the share-block and navbar tools.
| Tool |
API Endpoint |
get_space_website |
GET /spaces/{space_id}/website |
update_space_website |
PATCH /spaces/{space_id}/website |
list_share_block_configs |
GET /spaces/{space_id}/share_block_configs |
get_share_block_config |
GET /spaces/{space_id}/share_block_configs/{id} |
create_share_block_config |
POST /spaces/{space_id}/share_block_configs |
update_share_block_config |
PATCH /spaces/{space_id}/share_block_configs/{id} |
delete_share_block_config |
DELETE /spaces/{space_id}/share_block_configs/{id} |
list_navbar_configs |
GET /spaces/{space_id}/navbar_configs |
get_navbar_config |
GET /spaces/{space_id}/navbar_configs/{id} |
create_navbar_config |
POST /spaces/{space_id}/navbar_configs |
update_navbar_config |
PATCH /spaces/{space_id}/navbar_configs/{id} |
delete_navbar_config |
DELETE /spaces/{space_id}/navbar_configs/{id} |
duplicate_navbar_config |
POST /spaces/{space_id}/navbar_configs/{id}/duplicate |
update_space_website toggles website mode and points the site at header/footer share blocks. A site_header share block's content is a navbar node referencing a navbar config (links, logo, title, alignment); a site_footer holds freeform blocks. delete_share_block_config returns 409 config_in_use when the block is the active header or footer — repoint or disable website mode first.
Header and navbar style shapes (and their allowed values) live in get_design_capabilities under website: a share block's CSS goes under style.styles with fullWidth: true for an edge-to-edge bar, and its content layout keys include flexLayout, flexGap, flexItemSizing (equal or fit), and flexRowAlign (left, center, right). Use flexItemSizing: "fit" plus flexRowAlign: "center" for centered rows of chips or badge pills that should keep their full label widths. The navbar uses named style fields (linkSource, alignment, spacing, …) plus a links array of { id, label, destination, displayAs, target }. create_/update_ of share-block and navbar configs return an advisory warnings array for input the renderer would ignore (e.g. CSS at the top level of a style).
Messages
| Tool |
API Endpoint |
list_messages |
GET /spaces/{space_id}/messages |
get_message |
GET /messages/{message_id} |
create_message |
POST /spaces/{space_id}/messages |
update_message |
PATCH /messages/{message_id} |
delete_message |
DELETE /messages/{message_id} |
Reflections
| Tool |
API Endpoint |
list_reflections |
GET /messages/{message_id}/reflections |
get_reflection |
GET /reflections/{reflection_id} |
create_reflection |
POST /messages/{message_id}/reflections |
update_reflection |
PATCH /reflections/{reflection_id} |
delete_reflection |
DELETE /reflections/{reflection_id} |
Member Properties
| Tool |
API Endpoint |
list_member_properties |
GET /spaces/{space_id}/member_properties |
create_member_property |
POST /spaces/{space_id}/member_properties |
update_member_property |
PATCH /member_properties/{member_property_id} |
delete_member_property |
DELETE /member_properties/{member_property_id} |
get_member_property_values |
GET /spaces/{space_id}/members/{member_id}/properties |
update_member_property_values |
PATCH /spaces/{space_id}/members/{member_id}/properties |
Space Properties
| Tool |
API Endpoint |
list_space_properties |
GET /spaces/{space_id}/space_properties |
create_space_property |
POST /spaces/{space_id}/space_properties |
update_space_property |
PATCH /space_properties/{space_property_id} |
delete_space_property |
DELETE /space_properties/{space_property_id} |
get_space_property_values |
GET /spaces/{space_id}/properties |
update_space_property_values |
PATCH /spaces/{space_id}/properties |
Invitations
| Tool |
API Endpoint |
list_invitations |
GET /spaces/{space_id}/invitations |
get_invitation |
GET /spaces/{space_id}/invitations/{invitation_id} |
create_invitation |
POST /spaces/{space_id}/invitations |
update_invitation |
PATCH /spaces/{space_id}/invitations/{invitation_id} |
delete_invitation |
DELETE /spaces/{space_id}/invitations/{invitation_id} |
resend_invitation |
POST /spaces/{space_id}/invitations/{invitation_id}/resend |
bulk_create_invitations |
POST /spaces/{space_id}/invitations/bulk |
Surveys
| Tool |
API Endpoint |
list_surveys |
GET /spaces/{space_id}/surveys |
get_survey |
GET /surveys/{survey_id} |
get_survey_submissions |
GET /surveys/{survey_id}/submissions |
create_survey |
POST /spaces/{space_id}/surveys |
update_survey |
PATCH /surveys/{survey_id} |
delete_survey |
DELETE /surveys/{survey_id} |
Plans, Enrollments & Payments
| Tool |
API Endpoint |
list_plans |
GET /spaces/{space_id}/plans |
get_plan |
GET /plans/{plan_id} |
create_plan |
POST /spaces/{space_id}/plans |
update_plan |
PATCH /plans/{plan_id} |
delete_plan |
DELETE /plans/{plan_id} |
list_enrollments |
GET /plans/{plan_id}/enrollments |
get_enrollment |
GET /enrollments/{enrollment_id} |
list_payments |
GET /spaces/{space_id}/payments |
get_payment |
GET /payments/{payment_id} |
Plan amounts are integer cents (amount, with amount_cents accepted as a write alias). Creating or updating plans never flips the space-level payment gate — when the gate is off, plan responses carry an advisory warnings array pointing at update_space_payment. While multiple plan selection is enabled, all active plans must share one currency and one billing family. delete_plan soft-deactivates (enrollments are preserved).
Coupons
| Tool |
API Endpoint |
list_coupons |
GET /spaces/{space_id}/coupons |
get_coupon |
GET /coupons/{coupon_id} |
create_coupon |
POST /spaces/{space_id}/coupons |
update_coupon |
PATCH /coupons/{coupon_id} |
delete_coupon |
DELETE /coupons/{coupon_id} |
Broadcasts
| Tool |
API Endpoint |
list_broadcasts |
GET /spaces/{space_id}/broadcasts |
get_broadcast |
GET /broadcasts/{broadcast_id} |
create_broadcast |
POST /spaces/{space_id}/broadcasts |
update_broadcast |
PATCH /broadcasts/{broadcast_id} |
delete_broadcast |
DELETE /broadcasts/{broadcast_id} |
send_broadcast |
POST /broadcasts/{broadcast_id}/send |
get_broadcast_delivery_status |
GET /broadcasts/{broadcast_id}/delivery_status |
Help Center
Help Center tools are internal Lotus tools for local/internal stdio setups only. They are not exposed by hosted MCP. They are available locally when SUTRA_LOTUS_TOKEN is set with help_center:read / help_center:write scopes.
Article create, update, and proposal tools accept heading_font and body_font
to control article typography. Use canonical applies_to_plan tiers:
basic, bronze, silver, and gold.
| Tool |
API Endpoint |
help_list_articles |
GET /api/v4/lotus/help/articles |
help_get_article |
GET /api/v4/lotus/help/articles/{id} |
help_create_article |
POST /api/v4/lotus/help/articles |
help_update_article |
PUT /api/v4/lotus/help/articles/{id} |
help_propose_article |
POST /api/v4/lotus/help/articles/propose |
help_propose_article_update |
POST /api/v4/lotus/help/articles/{id}/propose_update |
help_review_article |
POST /api/v4/lotus/help/articles/{id}/review |
help_publish_article |
POST /api/v4/lotus/help/articles/{id}/publish |
help_list_collections |
GET /api/v4/lotus/help/collections |
help_create_collection |
POST /api/v4/lotus/help/collections |
help_update_collection |
PUT /api/v4/lotus/help/collections/{id} |
help_delete_collection |
DELETE /api/v4/lotus/help/collections/{id} |
Blog
Blog tools are internal Lotus tools for the public /resources surface and are available in local/internal stdio setups only. They are not exposed by hosted MCP. The token needs blog:read for list/get tools and blog:write for create, update, proposal, publish, review, and category tools.
| Tool |
API Endpoint |
blog_list_posts |
GET /api/v4/lotus/blog/posts |
blog_get_post |
GET /api/v4/lotus/blog/posts/{id} |
blog_create_post |
POST /api/v4/lotus/blog/posts |
blog_update_post |
PUT /api/v4/lotus/blog/posts/{id} |
blog_propose_post |
POST /api/v4/lotus/blog/posts/propose |
blog_propose_post_update |
POST /api/v4/lotus/blog/posts/{id}/propose_update |
blog_review_post |
POST /api/v4/lotus/blog/posts/{id}/review |
blog_publish_post |
POST /api/v4/lotus/blog/posts/{id}/publish |
blog_list_categories |
GET /api/v4/lotus/blog/categories |
blog_create_category |
POST /api/v4/lotus/blog/categories |
blog_update_category |
PUT /api/v4/lotus/blog/categories/{id} |
blog_delete_category |
DELETE /api/v4/lotus/blog/categories/{id} |
blog_list_tags |
GET /api/v4/lotus/blog/tags |
Automations
| Tool |
API Endpoint |
list_automations |
GET /spaces/{space_id}/automations |
get_automation |
GET /automations/{automation_id} |
list_automation_members |
GET /automations/{automation_id}/members |
get_automation_member |
GET /automations/{automation_id}/members/{enrollment_id} |
add_automation_member |
POST /automations/{automation_id}/members |
remove_automation_member |
DELETE /automations/{automation_id}/members/{enrollment_id} |
get_automation_capabilities |
GET /automations/capabilities |
create_automation |
POST /spaces/{space_id}/automations |
update_automation |
PATCH /automations/{automation_id} |
delete_automation |
DELETE /automations/{automation_id} |
list_automation_steps |
GET /automations/{automation_id}/steps |
create_automation_step |
POST /automations/{automation_id}/steps |
update_automation_step |
PATCH /automations/{automation_id}/steps/{step_id} |
reorder_automation_steps |
POST /automations/{automation_id}/steps/reorder |
replace_automation_steps |
POST /automations/{automation_id}/steps/replace |
delete_automation_step |
DELETE /automations/{automation_id}/steps/{step_id} |
Read and enrollment tools (list_automations, get_automation, the *_member tools) require automations:read / automations:write. Adding a member triggers the automation flow for that person.
Authoring (create/edit/delete automations and steps, including conditional logic and branching) requires the automations:manage scope. Call get_automation_capabilities first — it returns the available trigger types, the per-action params and public-ID references, and the condition rule catalog. Build or restructure a flow in one call with replace_automation_steps (temp ids for new steps, astep_ ids for existing; omitted steps are removed and their enrollments migrate), or use the per-step tools for surgical edits. Conditional steps require the Silver plan or above (Silver allows one per automation). The survey condition category, the survey_completed trigger, google_calendar_invite, and issue_certificate are not authorable via the API yet — configure those in the Sutra web UI.
Available Resources
The MCP server also exposes small documentation resources that agents can read before choosing tools:
| Resource URI |
Description |
sutra://admin-api/overview |
Core Admin API concepts, public ID prefixes, scopes, pagination, and filtering |
sutra://admin-api/membership-spaces |
Difference between admin-manageable spaces and limited membership-space inventory |
sutra://admin-api/contacts-properties |
Contact listing and member/contact property value workflows |
sutra://admin-api/people-filtering |
Member and contact search, email, state, role, and custom property filtering |
sutra://design/capabilities |
Design node/mark/asset rules, supported fonts, and the safe draft/publish workflow |
How It Works
The MCP server is a stateless wrapper. Each tool call translates directly to one or more Admin API requests using the caller's bearer credential. No Sutra customer data is cached or stored by the MCP server.
AI Agent → MCP Protocol (remote HTTP or local stdio) → Sutra MCP → Sutra Admin API
Pagination is handled automatically for list tools — pass cursor from a previous response to page through results. The get_space_deep tool auto-paginates internally.
Rate limits, scopes, and error codes from the Admin API pass through unchanged. See errors.md for error codes and README.md for rate limit headers.