Connect an AI client (MCP)

These docs are also a machine-readable server. If your team builds with an AI coding agent — Cursor, VS Code, Claude Code, or anything that speaks the Model Context Protocol — point it here and it can search this guide and the API reference while you integrate. Each question returns the five most relevant sections, not whole pages: ask one specific question at a time.

The docs MCP server

Streamable-HTTP endpoint, no credentials needed:

https://docs.rostergiving.com/mcp

Add to Cursor  ·  Add to VS Code

Cursor or VS Code by hand — add a remote MCP server named roster-docs with the URL https://docs.rostergiving.com/mcp and no headers.

Claude Code

claude mcp add --transport http roster-docs https://docs.rostergiving.com/mcp

Claude (claude.ai / Desktop) — Settings → Connectors → Add custom connector, name it roster-docs and paste the URL above. No auth fields needed.

Anything else — it is a standard MCP server over streamable HTTP; add it the way your client adds remote servers.

Whole pages as plain text — the server returns sections, not pages. To read a whole page, an agent can start at https://docs.rostergiving.com/llms.txt, which lists every page, and add .md to any page address to get its Markdown, such as https://docs.rostergiving.com/import-churches.md.

The API MCP server — execute real sandbox calls

This one acts: it imports churches, opens donor sessions, reads the event feed and fires the sandbox simulators — authenticated with your own sk_test key, sent per-request as a Bearer token. The MCP proxy (operated by Scalar) forwards the Authorization header in passthrough mode; the Roster API receives your key exactly as a direct HTTP call would — and, as always, keeps only a hash:

https://mcp.scalar.com/@rostergiving/rostergiving-f322b7f1

Keep the key out of every configuration file. Store it in an environment variable with a name of your own, such as ROSTER_KEY (some clients refuse to expand variables that hold their own credentials), and write only a reference to it in the client's configuration. Each client writes the reference its own way:

Claude Code — add the server to your project's .mcp.json. Claude Code expands ${ROSTER_KEY} from the environment it was started in, so the file holds only the reference and can be committed:

{
  "mcpServers": {
    "roster-api": {
      "type": "http",
      "url": "https://mcp.scalar.com/@rostergiving/rostergiving-f322b7f1",
      "headers": { "Authorization": "Bearer ${ROSTER_KEY}" }
    }
  }
}

Do not run claude mcp add with --header "Authorization: Bearer $ROSTER_KEY": your shell replaces $ROSTER_KEY with the key before Claude Code runs, and the resolved key is written to Claude Code's configuration file.

Cursor — in Cursor's mcp.json, an environment variable is written ${env:ROSTER_KEY}:

{
  "mcpServers": {
    "roster-api": {
      "url": "https://mcp.scalar.com/@rostergiving/rostergiving-f322b7f1",
      "headers": { "Authorization": "Bearer ${env:ROSTER_KEY}" }
    }
  }
}

VS Code — in .vscode/mcp.json, a promptString input with "password": true asks for the key once, and VS Code stores it securely:

{
  "inputs": [
    {
      "type": "promptString",
      "id": "roster-key",
      "description": "Roster sandbox API key (sk_test_...)",
      "password": true
    }
  ],
  "servers": {
    "roster-api": {
      "type": "http",
      "url": "https://mcp.scalar.com/@rostergiving/rostergiving-f322b7f1",
      "headers": { "Authorization": "Bearer ${input:roster-key}" }
    }
  }
}

A client that does not recognize the reference sends it as written, and the API answers 401 (see Connection troubleshooting). Whatever the client, prove the connection before a write.

Add to Cursor  ·  Add to VS Code  — then add the Authorization header to the server's config with a reference to your key, in the form shown above for that client.

Calls without a key (or with a revoked one) get the API's normal opaque 401 — the MCP server adds no credentials of its own. Clients must support per-request headers for API execution. If your connector does not, use the documentation server there.

Your sk_test key comes from the API keys page of your partner workspace (your workspace owner can issue and rotate it). The owner can copy the current sandbox key again from the Integration Guide; a live key is shown once and stored hashed — see Introduction for the conventions.

How API execution works

The API server uses Scalar's dynamic mode. Your client discovers four functions: search-documentation, summarize-openapi-specs, search-openapi-operations and execute-request. Every API operation is available through discovery and execution; they are not separate functions in the client menu. The MCP operation catalog lists them, generated from the same contract.

Both servers list the same four functions. Both are run by Scalar for the same Roster documentation and API, in its dynamic mode, which always offers these four functions: that is why the names repeat. The servers differ in one setting: the API server forwards the Authorization header your client sends to the Roster API, and the documentation server does not. If you connected both, your client lists these names twice, once under each server name you chose. Only the API server, whose URL starts with https://mcp.scalar.com/@rostergiving/ (roster-api in the commands above), carries your key: run discovery and execute-request there. An execute-request on the documentation server answers 401, even when your client sends it the Authorization header. If your client can send the header, connect only the API server: it also answers search-documentation with the same results. Connect the documentation server alone where headers are not possible.

Ask the agent to discover the exact method and path before calling it. search-openapi-operations returns the two execution identifiers — summarize-openapi-specs does not, so search first. The search result supplies x-scalar-document-version-id at the document level and x-scalar-operation-id on the returned path item. Pass those values as xScalarDocumentId and xScalarOperationId to execute-request. The OpenAPI operationId such as createChurch is not the Scalar execution identifier. Refresh discovery if the reference changes instead of hardcoding these identifiers.

For a POST, execute-request.headers must include a stable Idempotency-Key and, when sending JSON, Content-Type: application/json. Its body is a JSON-encoded string. Authentication comes from your MCP connection's Authorization header, not from a key written into tool arguments. Select https://api.sandbox.rostergiving.com explicitly for sandbox work.

Query parameters travel inside path, already encoded — for example /v1/events?since_cursor=...&type=enrollment.activated. execute-request has no query argument; an unknown argument is dropped silently. The API itself refuses a query parameter the operation does not accept with 400, so a misspelled name inside path (such as cursor on /v1/events, which pages with since_cursor) fails loudly instead of returning the first page again.

Inspect the upstream status and the tool's isError, not only the MCP HTTP status: a successful transport can carry an API 400 or 401. Never report a write as successful without checking the actual API result.

What to run through the MCP

Most operations are safe to run through the API MCP in the sandbox: every read, church creation and import without bank details, church verification with a test EIN, consents, flow settings and allowed origins, the test values in GET /sandbox/fixtures, the webhook test delivery and every simulator under /sandbox/simulate/. A few requests or responses carry something that must not stay in a chat transcript. Send them from your backend:

Operation Why it stays in your backend
createWebhookEndpoint (POST /v1/webhook_endpoints) The response carries the signing secret, once
registerChurchBankAccount, and createChurch or importChurches when a row has bank_account The request carries bank account numbers
createDonorSession (POST /v1/donor_sessions) The response carries the donor's one-time link
createManageSession (POST /v1/manage_sessions) The response carries the donor's one-time link

An AI-assisted integration is therefore hybrid: the assistant can prepare these requests, and read their results afterwards through the API (GET /v1/webhook_endpoints, GET /v1/donor_sessions/{id}), while your backend sends them. In Sandbox certification, that means steps 0 and 2.

Prove the connection before a write

  1. Ask search-documentation how to resume the event feed. Confirm that the answer cites the Roster guide.
  2. Connect the API server with your own sandbox key and refresh tool discovery. You should see the four dynamic functions listed above. The operation catalog explains their scope.
  3. Ask: “List my sandbox churches. Do not create or change anything.” A successful empty list is valid. A 401 means the credential did not reach the API or is invalid; a successful MCP connection alone does not prove API access.
  4. Only then try a synthetic church creation. Ask the assistant to show the environment, source reference and idempotency key before it executes. Compare the returned ID with a direct API read.

Practical prompts

  • “Read the Roster docs and draft an integration that checkpoints every imported church. Do not execute requests.”
  • “Read my sandbox event feed from the saved cursor. Report enrollment IDs from entity_id. Do not infer money received from activation.”
  • “Inspect recent deliveries for this endpoint ID and explain the observed errors. Do not replace or remove the endpoint.”
  • “Prepare a payroll-connected simulation for this supplied scenario enrollment and church. Show the exact request and keep the same idempotency key if we retry.”

Connection troubleshooting

Symptom Check
Only search-documentation is listed on the API URL Refresh tools. If unchanged, the server's API operation publication needs attention
execute-request returns 401 although the same key works with curl The call went through the documentation server (roster-docs), which lists the same four tools but carries no key. Run it on roster-api, the server whose URL starts with https://mcp.scalar.com/@rostergiving/
Discovery works on roster-api, but every execute-request returns 401 (invalid API key) while the same key works with curl Your client did not put the key in the header: it sent the reference itself, such as the literal ${ROSTER_KEY}, or an empty value. Check that the reference uses the syntax your client expands (see the API MCP server), that the variable is set in the environment the client was started from, and restart the client. Then ask for GET /v1/churches again
Execution on roster-api returns 401 and the key does not work with curl either The key is not a valid sandbox key: get the current one from your workspace owner, as described above
A write rejects missing fields Inspect the discovered input schema; do not guess IDs or use a donor's personal information as an identifier
Client cannot supply request headers Use the documentation server; API execution requires a client that can forward your credential
A key worked before rotation Update every client configuration; the previous key may have been revoked

The API MCP is an additional processor of the requests you choose to send through it. Configure credentials in client settings, never in a prompt, and do not commit a configuration containing a resolved key. Keep bank-account registration and other sensitive payloads in your approved server-side integration. Tool availability does not grant access to another partner's records.

Client configuration reference

Use your client's current instructions for credential inputs and configuration location: Claude Code, Cursor and VS Code. The server URL and required Authorization header above are the Roster settings. The reference forms above are the ones these clients document today; for any other client, use its own way to keep a secret out of the configuration file.