Reference · v1.1.0 · 29 tools

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.

Get an API key

Sign in to the Studio and go to Settings → Agent access. Click Generate token, give the key a label (e.g. Claude Desktop), and copy the rok_live_… plaintext from the modal — it is shown exactly once. The server stores only the SHA-256 hash and a 12-char visible prefix, so a key cannot be recovered if you lose it.

The same panel lists every active key with its prefix, label, and last-used time. Revoking a key invalidates the server-side context cache immediately, so any client using it stops authenticating on the next request. Owner/admin role required.

Filtering analytics by website

Organizations can run multiple websites against the same Pulse tenant. The analytics read tools — get_analytics, get_analytics_overview, get_top_pages, get_top_referrers — accept an optional clientId argument to scope results to a single site. Without it, every tool returns org-wide totals (backward-compatible).

Discover the IDs first with list_tracking_clients, then pass one in:

# 1. list sites
{"method":"tools/call","params":{"name":"list_tracking_clients","arguments":{}}}

# 2. scope an overview to one of them
{"method":"tools/call","params":{
  "name":"get_analytics_overview",
  "arguments":{ "range":"7d", "clientId":"cl_…" }
}}

When clientId matches a site in the active org, the response includes a filter: { id, clientId, name } block so transcripts read Filter · acme.com (cl_…) rather than echoing back an opaque ID. An unrecognised clientId is treated as zero matches, not an error, so an agent can iterate over sites safely.

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:

TokenScopeCan 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.

Key format: the server stores a SHA-256 hash of the raw key. Keys never appear in logs. Revoking a key sets 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:

  1. Session override — if the caller previously invoked switch_organization, the target org ID lives in KV under mcp:active:<keyHash> for 24 hours.
  2. Key default — for per-user and legacy keys, the organization row the key was issued against.
  3. 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.

ToolCategoryMode
get_current_organization
Return the active organization for the current MCP session.
Organization Read
list_organizations
List organizations available to the authenticated key.
Organization Read
switch_organization
Set a 24-hour active-organization override for this key.
Organization Write
list_contacts
Query contacts with search, filters, sort, and pagination.
Contacts Read
list_contact_fields
List custom contact fields available for filters and edits.
Contacts Read
create_contact_field
Register a new custom contact field.
Contacts Write
update_contact_field
Update or rename a custom contact field.
Contacts Write
delete_contact_field
Delete a custom contact field and strip stored values.
Contacts Write
list_duplicate_contacts
Find duplicate-email contact groups.
Contacts Read
deduplicate_contacts
Bulk merge or delete duplicate contact groups.
Contacts Write
resolve_duplicate_contacts
Resolve one duplicate contact group with an explicit keeper.
Contacts Write
get_contact
Get a single contact by ID.
Contacts Read
create_contact
Create a contact in the active organization.
Contacts Write
list_campaigns
List campaigns, optionally filtered by status.
Campaigns Read
get_campaign_stats
Fetch delivery and engagement stats for one campaign.
Campaigns Read
list_segments
List segments in the active organization.
Campaigns Read
send_campaign
Trigger a campaign send for its assigned segment.
Campaigns Write
get_analytics
Read daily, weekly, or monthly analytics summaries. Optional clientId to filter to one website.
Analytics Read
list_tracking_clients
List website tracking clients and embed credentials.
Analytics Read
create_tracking_client
Create a website tracking client and optional secret.
Analytics Write
delete_tracking_client
Delete a website tracking client.
Analytics Write
get_analytics_overview
Aggregate visitors, sessions, pageviews, bounce, and duration. Optional clientId to filter to one website.
Analytics Read
get_top_pages
List top pages with pageviews, uniques, and visible time. Optional clientId to filter to one website.
Analytics Read
get_top_referrers
List top referrer hosts. Optional clientId to filter to one website.
Analytics Read
list_insights
List generated insight reports.
Insights Read
get_insight_report
Get one insight report with evidence rows.
Insights Read
run_insights
Run all active insight definitions now.
Insights Write
run_insight
Run one insight definition now.
Insights Write
create_custom_insight
Create and run a custom insight from a natural-language prompt.
Insights Write

Full JSONSchema for every tool lives at /mcp-manifest.json.

Error codes

CodeMeaning
-32001Authentication required — missing Authorization: Bearer.
-32002Invalid or expired API key.
-32003Active organization not found (stale override or empty DB).
-32601Unknown method or tool.
-32602Invalid params (missing required input, bad type).

Changelog

v1.1.0
Implicit org scoping. organizationId removed 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 organizationId inputs, org-scoped API keys only.

Next steps