Soloft

Soloft MCP reference

A Model Context Protocol server that lets AI assistants such as Meta Muse read and, with the user's explicit OAuth consent, update a Soloft workspace: clients, projects, invoices, expenses, bookings, content and portfolio.

Overview

ItemValue
MCP endpointPOST https://mcp.soloft.io/mcp
TransportStreamable HTTP, one JSON response per POST (no SSE stream). GET and DELETE return 405.
Protocol versions2025-06-18, 2025-03-26, 2024-11-05 (the requested version is echoed if supported)
Capabilitiestools only. No resources, prompts or sampling.
Authorization serverhttps://auth.soloft.io
AccessRead and write, limited to the scopes the user approves. Write tools create or update workspace records. No tool sends email or messages to a third party, creates a payment link, takes a payment or deletes data, and none changes billing, integrations, team access or account settings.
PlanAny Soloft account can connect. Tool calls require an active trial or subscription (see Errors).
UnitsAmounts are integer cents plus a currency code. Dates are ISO-8601 in the workspace timezone. Ids are UUID strings.

Authentication

OAuth 2.1 authorization code flow with PKCE (S256 only) and RFC 8707 resource indicators. API keys are not supported. Every request to /mcp needs Authorization: Bearer <access_token>.

Discovery

DocumentURL
Protected resource metadata (RFC 9728)https://mcp.soloft.io/.well-known/oauth-protected-resource
Authorization server metadata (RFC 8414)https://auth.soloft.io/.well-known/oauth-authorization-server

An unauthenticated or invalid request returns 401 with WWW-Authenticate: Bearer resource_metadata="https://mcp.soloft.io/.well-known/oauth-protected-resource".

Endpoints

PurposeURL
AuthorizationGET https://auth.soloft.io/authorize
TokenPOST https://auth.soloft.io/token (form-encoded)
RevocationPOST https://auth.soloft.io/revoke
Client registrationPOST https://auth.soloft.io/register (RFC 7591)

Flow

  1. The client sends the user to /authorize with response_type=code, client_id, a registered redirect_uri, scope, state, code_challenge (S256), code_challenge_method=S256 and resource=https://mcp.soloft.io.
  2. The user signs in to Soloft and approves a consent screen that lists each requested permission in plain language.
  3. Soloft redirects to redirect_uri with code and state (or error=access_denied).
  4. The client POSTs to /token with grant_type=authorization_code, code, redirect_uri, client_id, code_verifier and the same resource.
{
  "access_token": "…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "…",
  "scope": "crm:read projects:read invoices:read"
}

Token lifetimes and rules

Scopes

tools/list returns only the tools whose scope the token holds, further narrowed to the modules enabled for the workspace's business type. Read scopes never allow writes.

ScopeGrants
profile:readBusiness profile: name, timezone, currency, plan state and which integrations are connected (as booleans only)
crm:read / crm:writeContacts, activity log and quick notes / create and update contacts, log activity, add notes
projects:read / projects:writeProjects, tasks and milestones / create and update them
invoices:read / invoices:writeInvoices, templates and revenue summary / create and edit draft invoices, create templates, mark an invoice paid
expenses:read / expenses:writeExpenses and summaries / log and update expenses, create categories
calendar:read / calendar:writeBooking links and bookings (names only, no booker emails or join links) / edit booking links and weekly availability
content:read / content:writeContent calendar, social handles, sponsorships / create and update content items, social handles and sponsorships
portfolio:read / portfolio:writeBrands, products and KPIs / update products, create brands and products, checklists and decisions
commerce:read / commerce:writeOrders, catalog items and events (maker, reseller and event-vendor workspaces) / create and edit catalog items, events and suppliers, move an order through non-restocking statuses
inventory:read / inventory:writeStock, raw materials, recipe costs, production runs, suppliers and purchase orders (stock for maker, reseller and event-vendor workspaces; materials, recipes and suppliers for maker and reseller) / create suppliers and draft purchase orders. Nothing here changes stock quantities.
feedback:readCustomer feedback posts per product (creator workspaces)
portal:readClient portal threads for a project
automations:read / automations:writeEmail sequences and enrollments / create inactive draft sequences and add or edit their steps

Tools that change stock quantities (creating or cancelling orders, inventory adjustments, production runs, purchase-order receipt) are not available over MCP; do those in Soloft.

Protocol

JSON-RPC 2.0 over POST /mcp. Supported methods: initialize, ping, tools/list, tools/call. Notifications without an id return 202. Request bodies are limited to 256 KB and must be application/json. Requests carrying a browser Origin header that is not on the allowlist are rejected with 403.

POST /mcp
Authorization: Bearer <access_token>
Content-Type: application/json

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18"}}
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{
  "name":"soloft_list_invoices","arguments":{"status":"overdue","limit":5}}}

Tool results are returned as a text content item plus structuredContent holding the same JSON, with isError: false. Every tool carries title and annotations (readOnlyHint, destructiveHint, idempotentHint), and arguments are validated against the tool's JSON Schema.

Tools

All names are prefixed soloft_. List tools return at most 100 rows (default 20). Arguments not in a tool's schema are rejected. tools/list is the authoritative list for a connection; the tables below group tools by scope.

Read tools Read

ToolScopeReturns
soloft_get_profileprofile:readBusiness profile, plan state, connected-integration flags
soloft_get_todayany of crm/projects/invoices/calendar/portal :readTasks due, today's bookings, overdue invoices, stale leads (no activity in 14 days), portal threads awaiting a reply. Sections the connection lacks are named, not guessed.
soloft_list_contacts, soloft_get_contactcrm:readContacts with stage, tags, last activity; one contact with activities, tasks, projects and invoices
soloft_list_activities, soloft_list_notescrm:readActivity log and quick notes
soloft_list_projects, soloft_get_project, soloft_list_tasksprojects:readProjects with status, budget and due date; project detail with milestones and tasks; filtered tasks
soloft_list_invoices, soloft_get_invoice, soloft_list_invoice_templatesinvoices:readInvoices by status, client and date; one invoice with line items; saved templates
soloft_get_revenue_summaryinvoices:readMonth-to-date, year-to-date, outstanding and overdue totals per currency
soloft_list_expenses, soloft_get_expense_summaryexpenses:readExpenses; totals by category and profit and loss
soloft_list_booking_links, soloft_list_bookingscalendar:readMeeting types and availability; upcoming and past bookings
soloft_get_content_calendar, soloft_list_social_handles, soloft_list_sponsorshipscontent:readContent items by week, status and platform; handles; sponsorships
soloft_get_portfolio_summary, soloft_get_productportfolio:readBrands and products with stage and KPIs
soloft_list_orders, soloft_get_order, soloft_get_order_revenue, soloft_list_catalog_items, soloft_list_eventscommerce:readOrders and order revenue, catalog items, events
soloft_get_inventory, soloft_list_raw_materials, soloft_get_recipe_cost, soloft_list_production_runs, soloft_list_suppliers, soloft_list_purchase_ordersinventory:readStock levels, materials, recipe cost, production runs, suppliers, purchase orders
soloft_list_feedback, soloft_get_feedback_postfeedback:readFeedback board posts and comments per product
soloft_get_project_portalportal:readPortal messages and approvals for a project
soloft_list_sequences, soloft_list_enrollmentsautomations:readEmail sequences, steps and who is enrolled

Write tools Write

None of these is destructive. Insert tools accept an optional client_request_id; repeating a call with the same id returns the original record instead of creating a duplicate.

ToolScopeEffect
soloft_create_contact, soloft_update_contactcrm:writeCreate or edit a contact. Nothing is sent to the contact.
soloft_log_activity, soloft_add_notecrm:writeRecord a call, meeting or note in the workspace
soloft_create_project, soloft_update_projectprojects:writeCreate or edit a project
soloft_create_task, soloft_update_task, soloft_create_milestone, soloft_update_milestoneprojects:writeCreate or edit tasks and milestones, including marking them done
soloft_create_draft_invoice, soloft_update_draft_invoiceinvoices:writeCreate or edit a draft invoice. It is never sent and no payment link is created; the user reviews and sends it in Soloft.
soloft_mark_invoice_paidinvoices:writeMarks a sent, viewed or overdue invoice as paid, as the Mark paid button does. Nothing is emailed. Drafts and cancelled invoices are refused; an already-paid invoice is returned unchanged. The tool description instructs the assistant to confirm with the user first.
soloft_create_invoice_templateinvoices:writeSave a reusable set of line items
soloft_log_expense, soloft_update_expense, soloft_create_expense_categoryexpenses:writeRecord or correct an expense; add a category (an existing name is returned, not duplicated)
soloft_create_content_item, soloft_update_content_itemcontent:writeCreate or edit a content-calendar item. Nothing is published.
soloft_update_product, soloft_create_product, soloft_create_brandportfolio:writeUpdate a product's stage and KPIs; create a product or brand
soloft_update_booking_link, soloft_set_availabilitycalendar:writeEdit a meeting type; replace a booking link's weekly availability windows. No booking is created or cancelled and nobody is notified.
soloft_create_sequence_draft, soloft_add_sequence_step, soloft_update_sequence_stepautomations:writeCreate an inactive email sequence and edit its steps. Nothing is sent or enrolled; sequences that are active or have live enrollments are refused, and activation happens in Soloft.
soloft_add_social_handle, soloft_update_social_handle, soloft_create_sponsorship, soloft_update_sponsorshipcontent:writeRecord or edit a social handle or a sponsorship deal. Nothing is posted or invoiced.
soloft_toggle_checklist_item, soloft_seed_checklist, soloft_add_decisionportfolio:writeTick a product checklist item, add checklist items, log a product decision
soloft_create_catalog_item, soloft_update_catalog_itemcommerce:writeCreate or edit a catalog item (new items get an empty stock record; quantities are not changed)
soloft_create_event, soloft_update_eventcommerce:writeCreate or edit a sales event, including ending or reopening it
soloft_update_order_statuscommerce:writeMove an order between pending, processing, shipped and delivered. Cancelled or refunded orders are refused because reopening them needs stock changes. No customer email is sent.
soloft_create_supplier, soloft_update_supplier, soloft_create_purchase_ordercommerce:writeCreate or edit a supplier; create a draft purchase order (receiving it and adding stock is done in Soloft)

Write behavior

Errors

ConditionResponse
Missing, invalid, expired or wrong-audience tokenHTTP 401 + WWW-Authenticate header
Rate limit exceededHTTP 429 with Retry-After
Malformed JSON, non-object body, bad jsonrpc or methodHTTP 400, JSON-RPC error -32700 / -32600
Unknown methodJSON-RPC error -32601
Unknown tool nameJSON-RPC error -32602
Token lacks the tool's scopeTool error insufficient_scope
Trial ended and no active subscriptionTool error subscription_inactive with the upgrade URL. Tokens stay valid; no reconnect is needed after subscribing.
Daily write limit reachedTool error write_limit_reached
Invalid tool argumentsTool error invalid_params describing the constraint
Record not found or not payable, concurrent changeTool error such as not_found, not_payable, conflict
Unexpected server errorTool error internal_error with a generic message

A tool error is a normal JSON-RPC result with isError: true:

{"jsonrpc":"2.0","id":3,"result":{
  "content":[{"type":"text","text":"{\"error\":\"insufficient_scope\",\"message\":\"This connection lacks the invoices:write permission.\"}"}],
  "structuredContent":{"error":"insufficient_scope","message":"This connection lacks the invoices:write permission."},
  "isError":true}}

Limits

Testing

Reviewer access with a sample workspace is provided in the submission notes. To verify the server without OAuth, an unauthenticated call should return 401 with the discovery header:

curl -i -X POST https://mcp.soloft.io/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

A health check is available at GET https://mcp.soloft.io/mcp/health.

Data & privacy