MCP reference
The ReachOut MCP server exposes contacts, campaigns, segments, and analytics as tools your agent can call directly. It speaks JSON-RPC 2.0 over HTTP and SSE. Every tool operates on a single organization, which is resolved implicitly from your API key.
Endpoint
POST https://reachout-pulse-api.usereachout.com/mcp
Content-Type: application/json
Authorization: Bearer <api_key>
Transports: http (single request/response) and sse (streaming).
Server version is advertised in the initialize response under serverInfo.
Client setup
Use the same endpoint and bearer token in every MCP client. Keep the key out of committed project files unless you reference it through an environment variable.
Claude CLI / Claude Code
claude mcp add --transport http reachout https://reachout-pulse-api.usereachout.com/mcp \
--header "Authorization: Bearer YOUR_API_KEY"
claude mcp list Codex
# ~/.codex/config.toml
[mcp_servers."reachout"]
url = "https://reachout-pulse-api.usereachout.com/mcp"
[mcp_servers."ReachOut".headers]
Authorization = "Bearer YOUR_API_KEY"
# Then verify:
codex mcp list Claude Desktop
{
"mcpServers": {
"reachout": {
"type": "http",
"url": "https://reachout-pulse-api.usereachout.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
} Cursor, LM Studio, and other MCP clients
{
"mcpServers": {
"reachout": {
"transport": "http",
"url": "https://reachout-pulse-api.usereachout.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
Some clients call the key transport; others call it
type. Use HTTP / Streamable HTTP when the client asks for
the transport.
Authentication
Every tools/call requires a bearer token. Three token shapes are accepted:
| Token | Scope | Can switch orgs? |
|---|---|---|
| Per-user API key Studio → Settings → API Keys | Every organization the user is a member of. | Yes — switch_organization works against any of the user's memberships. |
| Legacy org-scoped key Created before user-linking was added | The single org the key was issued for. | No — switch_organization returns an error. |
Master key (PULSE_API_KEY)Server-level secret, self-hosted only | All organizations in the system. | Yes — any org by ID. |
Unauthenticated methods: initialize, tools/list, ping.
revokedAt; subsequent requests with that key return -32002 Invalid API key.
Organization scoping
Tool inputs never include an organization_id parameter. The active org is
resolved per request, in this order:
- Session override — if the caller previously invoked
switch_organization, the target org ID lives in KV undermcp:active:<keyHash>for 24 hours. - Key default — for per-user and legacy keys, the organization row the key was issued against.
- First org — master-key fallback when no override is set: the oldest organization by creation date.
Overrides are validated on every call — if the user's membership in the override org is revoked, the server falls back to the key default and clears the stale override automatically.
Response envelope
Every successful tool response is a single text block. The first two lines are a human-readable header showing the active organization; the rest is JSON.
[organization] Acme Inc (id: org_abc123)
--------------------------------------------------------------
{
"organization": { "id": "org_abc123", "name": "Acme Inc", "slug": "acme" },
"result": { /* tool-specific payload */ }
}
The header is part of the text content the model sees, so any well-behaved client will
surface the active tenant to the user on every tool call. For programmatic parsing, strip the
header and decode the JSON body — result holds the tool payload, organization
is always present.
Errors are emitted with isError: true and the same header prefix where possible.
Tools — organization management
Use these first when you're unsure which tenant is active.
get_current_organization
Returns the active organization and whether the key is user-linked, legacy, or master. No inputs.
list_organizations
Lists orgs the caller can see — all memberships for a user-linked key, every org for a master key, or only the key's own org for a legacy key. No inputs.
switch_organization
Writes a 24-hour active-org override to KV. Target must be accessible to the caller.
{
"organizationId": "org_xyz789"
} Tools — domain surface
All domain tools run against the active org. No tool accepts organizationId.
| Tool | Category | Mode |
|---|---|---|
get_current_organizationReturn the active organization for the current MCP session. | Organization | Read |
list_organizationsList organizations available to the authenticated key. | Organization | Read |
switch_organizationSet a 24-hour active-organization override for this key. | Organization | Write |
list_contactsQuery contacts with search, filters, sort, and pagination. | Contacts | Read |
list_contact_fieldsList custom contact fields available for filters and edits. | Contacts | Read |
create_contact_fieldRegister a new custom contact field. | Contacts | Write |
update_contact_fieldUpdate or rename a custom contact field. | Contacts | Write |
delete_contact_fieldDelete a custom contact field and strip stored values. | Contacts | Write |
list_duplicate_contactsFind duplicate-email contact groups. | Contacts | Read |
deduplicate_contactsBulk merge or delete duplicate contact groups. | Contacts | Write |
resolve_duplicate_contactsResolve one duplicate contact group with an explicit keeper. | Contacts | Write |
get_contactGet a single contact by ID. | Contacts | Read |
create_contactCreate a contact in the active organization. | Contacts | Write |
list_campaignsList campaigns, optionally filtered by status. | Campaigns | Read |
get_campaign_statsFetch delivery and engagement stats for one campaign. | Campaigns | Read |
list_segmentsList segments in the active organization. | Campaigns | Read |
send_campaignTrigger a campaign send for its assigned segment. | Campaigns | Write |
get_analyticsRead daily, weekly, or monthly analytics summaries. | Analytics | Read |
list_tracking_clientsList website tracking clients and embed credentials. | Analytics | Read |
create_tracking_clientCreate a website tracking client and optional secret. | Analytics | Write |
delete_tracking_clientDelete a website tracking client. | Analytics | Write |
get_analytics_overviewAggregate visitors, sessions, pageviews, bounce, and duration. | Analytics | Read |
get_top_pagesList top pages with pageviews, uniques, and visible time. | Analytics | Read |
get_top_referrersList top referrer hosts. | Analytics | Read |
list_insightsList generated insight reports. | Insights | Read |
get_insight_reportGet one insight report with evidence rows. | Insights | Read |
run_insightsRun all active insight definitions now. | Insights | Write |
run_insightRun one insight definition now. | Insights | Write |
create_custom_insightCreate and run a custom insight from a natural-language prompt. | Insights | Write |
Full JSONSchema for every tool lives at /mcp-manifest.json.
Error codes
| Code | Meaning |
|---|---|
-32001 | Authentication required — missing Authorization: Bearer. |
-32002 | Invalid or expired API key. |
-32003 | Active organization not found (stale override or empty DB). |
-32601 | Unknown method or tool. |
-32602 | Invalid params (missing required input, bad type). |
Changelog
- v1.1.0
-
Implicit org scoping.
organizationIdremoved from every tool input schema. Three new tools:get_current_organization,list_organizations,switch_organization. Every response wrapped with the[organization]header and{ organization, result }body. Master-key auth (PULSE_API_KEY) supported alongside per-user and legacy keys. Active-org override persists 24h in KV per API key. - v1.0.0
- Initial release. Per-tool
organizationIdinputs, org-scoped API keys only.
Next steps
- Local AI quickstart — Ollama, LM Studio, Claude Desktop, Cursor configs.
- mcp-manifest.json — machine-readable tool schema.
- llms-full.txt — data model and REST endpoints.