Docs

MCP (AI Agents)

Connect Claude and other AI agents to Servicebay via the Model Context Protocol

Servicebay ships a remote MCP server so AI agents — Claude, ChatGPT, Cursor, VS Code, and anything else that speaks the Model Context Protocol — can work with an organisation's jobs, customers, quotes, and invoices on a user's behalf.

The tools proxy the same REST API: identical validation, sequential IDs, form gates, and calendar sync. MCP never talks to Firestore directly.

Endpoint and transport

https://oauth.servicebay.io/mcp

Streamable HTTP only, dual-era: current spec plus legacy initialize. There is no SSE lane. Clients that only speak HTTP+SSE should go through mcp-remote.

Three credential paths

  1. OAuth (DCR or CIMD) — the client self-registers or presents a Client ID Metadata Document, then runs the authorization-code + PKCE flow. resource is optional and defaults to this MCP URL.
  2. Pre-registered confidential client — create one in OAuth Clients when the host rejects public DCR (notably Perplexity). Max 10 per org; they never expire.
  3. Static API key — Authorization: Bearer sk_live_… when the key's allowedUses includes mcp. A REST-only key is rejected (use_not_allowed). New keys default to the read bundle, 90-day expiry, and REST+MCP. See Authentication.

Admins only

Only active organisation admins can authorize an agent. The connection is bound to a single organisation. Grant read scopes unless you genuinely want the agent creating and deleting records. On scope v2, write does not include delete.

Tools

Tools appear only when the credential holds the matching scope. tools/list order is deterministic: whoami, organisation, list, get, search, fetch, lookup, then writes, then delete.

ToolScopesAnnotationsWhat it does
whoamiAlways listedreadOnlyHintConnected org, credential type (oauth / api-key), effective permission matrix, missingForFullAccess
get_organisationorganisation:readreadOnlyHintOrganisation profile
list_resources{entity}:readreadOnlyHintList a collection. limit 1–100, cursor = REST startAfter. Filters match the REST query params. kind switches inventory vs asset categories. collection switches form templates / rules / submissions, or recurring presets
get_resource{entity}:readreadOnlyHintFetch one record by ID
searchAny of customers / tickets / invoices / quotes / services / inventory / devices / messages :readreadOnlyHintEmail/phone looks up a customer; a bare integer tries job / invoice / quote numbers; otherwise fans out. Result ids look like sb:{entity}:{id}
fetchMatching {entity}:readreadOnlyHintLoad a search hit by sb:{entity}:{id}. Malformed ids (unknown entity, extra colons) are rejected
lookup_customercustomers:readreadOnlyHintLookup by email or phone
create_resource{entity}:writenot destructive, not idempotentCreate. Sequential IDs (jobs, invoices, quotes) are allocated server-side — never supply them
update_organisationorganisation:writedestructiveHint, idempotentHintPUT of the provided fields
update_resource{entity}:writedestructiveHint, idempotentHintPUT by ID
delete_resource{entity}:deletedestructiveHint, idempotentHintDelete by ID. confirm must be true. Cascades are described on the tool (jobs delete their calendar event; payments re-open the invoice)

Entity keys: tickets (jobs), customers, devices, services, inventory, quotes, invoices, payments, calendar-events, stations, tax-rates, ticket-statuses, messages, recurring-schedules, categories, forms, members.

get_organisation is listed only when the credential has organisation:read. fetch rejects ids that are not sb:{entity}:{id} with a known entity key.

search / fetch citations resolve to https://developer.servicebay.io/r/{org}/{entity}/{id} — a login-gated summary that requires Pro admin sign-in. Unknown entities, missing records, and visitors who are not a Pro admin of that org get 404.

devices needs customerId. messages needs ticketId. forms and members are read-only via the API, so write/delete tools never offer those entities.

Step-up

A 403 tool result includes:

{
  "_meta": {
    "mcp/www_authenticate": [
      "Bearer error=\"insufficient_scope\", scope=\"tickets:write\", resource_metadata=\"https://oauth.servicebay.io/.well-known/oauth-protected-resource/mcp\""
    ]
  }
}

A 401 uses error="invalid_token". Clients that understand the MCP WWW-Authenticate convention can re-run consent for the listed scopes.

Origin policy

Origin is checked before the handler runs:

OriginResult
Missing (native / CLI clients)Allowed
https://…Allowed; value is reflected in CORS
http://localhost, 127.0.0.1, ::1Allowed; reflected
null, file:, non-local http403 Forbidden

Optional deny list: Worker var MCP_BLOCKED_ORIGINS (hosts or full origins).

Connecting from Claude Code

claude mcp add --transport http servicebay https://oauth.servicebay.io/mcp

Then run /mcp inside Claude Code to trigger sign-in.

Client guides

Managing access

Connected agents appear under Connected Apps. Revoking disconnects the agent within seconds. If the approving admin leaves or is deactivated, subsequent calls return 403 and the grant is revoked automatically.

Discovery:

https://oauth.servicebay.io/.well-known/oauth-authorization-server