MCP Integration Guide
The Model Context Protocol (MCP) is an open standard that lets AI assistants call external tools directly. SocialHub implements an MCP server so you can manage stores, members, coupons, and points from within Claude Desktop, Cursor, or any MCP-compatible client.
Instead of writing code, you simply ask the AI: "List all active stores" or "Award 500 points to member m_abc123" and the assistant calls the SocialHub MCP tool on your behalf.
Connection Configuration
SocialHub exposes a Streamable HTTP MCP endpoint. You need two pieces of information:
| Endpoint URL | https://flash.socialhub.ai/api/mcp |
| API Key Header | Authorization: Bearer fl_live_... |
Create an API Key at /flash/account/api-keys. Ensure the key has the scopes needed for the tools you plan to use.
Claude Desktop Configuration
Add the following to your Claude Desktop MCP settings (claude_desktop_config.json):
{
"mcpServers": {
"flash": {
"type": "http",
"url": "https://flash.socialhub.ai/api/mcp",
"headers": {
"Authorization": "Bearer fl_live_your_key_here"
}
}
}
}Cursor Configuration
In Cursor, go to Settings > MCP and add a new server:
{
"mcpServers": {
"flash": {
"type": "http",
"url": "https://flash.socialhub.ai/api/mcp",
"headers": {
"Authorization": "Bearer fl_live_your_key_here"
}
}
}
}The type field also accepts streamable-httpas an alias. These desktop clients store the key in their config file — treat it as a secret, and prefer the environment-variable form (below) where supported to keep the plaintext key off disk.
Connect from Claude Code
Add SocialHub as an HTTP MCP server with the claude mcp add command. Export your key as an environment variable first so the plaintext key never lands in a config file or your shell history:
export FLASH_API_KEY="fl_live_your_key_here"
claude mcp add --transport http flash \
https://flash.socialhub.ai/api/mcp \
--header "Authorization: Bearer ${FLASH_API_KEY}"Or commit a project-scoped .mcp.json at the repo root. Reference the env var with ${FLASH_API_KEY}— never paste a plaintext key:
{
"mcpServers": {
"flash": {
"type": "http",
"url": "https://flash.socialhub.ai/api/mcp",
"headers": {
"Authorization": "Bearer ${FLASH_API_KEY}"
}
}
}
}Self-check after connecting:
- Run
claude mcp listand confirmflashshows as connected. - Ask the assistant to "list available SocialHub tools" — you should see only the tools your key's scopes allow.
- The server key must be exactly
flash; make sureFLASH_API_KEYis exported in the shell that launches Claude Code.
Gotcha: an invalid or revoked key surfaces as a failed connection, not an auth prompt. SocialHub uses bearer-token auth with no OAuth fallback, so if the server shows as failed/disconnected, re-check the key value and that it has the scopes you need before debugging anything else.
Available Tools (71)
list_metricsList the metrics available to this team from the governed semantic layer (key, label, unit, certification, category). Call first to discover valid metric keys. Requires metrics:read.
category?describe_metricGet the full spec of one metric: authoritative definition, unit, certification, dimensions, filterable fields, tunable parameters, and usage guidance. Requires metrics:read.
metricquery_metricRun a governed metric query and return numbers with their authoritative definition. Pick a metric key plus optional dimensions, filters, time range, grain, and period-over-period comparison — never SQL. Requires metrics:read.
metric, dimensions?, filters?, timeRange?, grain?, compare?, params?breakdown_metricBreak one metric down by a single dimension over a fixed recent window, with human-readable labels (store/tier/channel names). Requires metrics:read.
metric, dimension, days, state?ask_metricsAnswer a natural-language question by selecting the right governed metrics, fetching them, and breaking down the primary metric. For open-ended diagnosis. Requires metrics:read.
question, categories?list_storesList all stores for the current team. Supports optional status filter, search, and pagination.
status?, search?, limit?, offset?get_storeGet details of a specific store by its ID.
store_idlist_membersList loyalty program members. Supports program filter and pagination.
programId?, limit?, offset?, status?get_memberGet details of a specific loyalty member by ID. Returns decrypted PII fields.
member_idlist_coupon_poolsList coupon pools. Supports status and type filters.
status?, coupon_type?, limit?, offset?get_dashboard_statsOperational dashboard snapshot (captures, scans, capture rate, coupons, stores, plan). Not a governed metric — use the metric tools for authoritative business metrics.
(none)earn_pointsAward loyalty points to a member. Returns transaction ID and new balance.
member_id, amount, description?redeem_pointsDeduct loyalty points from a member (FIFO consumption).
member_id, amount, reasonget_points_balanceGet member's current points balance and recent transaction history.
member_id, limit?get_member_couponsGet a member's available (unredeemed, unexpired) coupons.
member_idget_member_tierGet member's current tier, next tier upgrade requirements, and all tiers.
member_idget_member_receiptsGet member's receipt submission history with OCR status and points awarded.
member_id, limit?redeem_points_for_couponRedeem loyalty points for a coupon from a specified pool (atomic: points + coupon, or neither).
member_id, pool_id, points_costissue_couponIssue a coupon from a pool to a member (single member; bulk audiences go through the So confirmation flow). Requires coupons:write.
member_id, pool_id, run_id?check_email_frequencyCheck whether a marketing email can be sent to an address under the frequency limits (1/day, 2/week, 4/month).
emaillist_ambassador_candidatesList scored Ambassador candidates for the loyalty program (Pro mode). Empty in Lite mode.
band?, status?, level?, sort_by?, limit?, offset?get_ambassador_metricsGet the Ambassador ROI report: the three subgoals, Month-2 retention, and the 90-day go/no-go gate.
since_days?, assumed_paid_cac_usd?issue_ambassador_codeIssue or upgrade a member's personal Ambassador affiliate code. Returns the code string.
member_id, single_use?, max_redemptions?, min_order_amount?get_tracking_statsGet page-visit / behavior analytics: overview, top pages, device breakdown, or traffic sources.
metric?, period?, start?, end?, campaign?, limit?get_member_profileA member's aggregated profile (reachability, consent/CCPA, loyalty, commerce/category/channel/engagement rollups, declared preferences, tags, coarse geo, age band). PII-redacted — no names or contact values. Requires members:read.
member_idget_member_timelineOne member's recent behavior timeline (visits, points, coupons, emails, receipts) + summary, to decide a personalized action. Returns decrypted PII. Requires members:behavior:read.
member_id, limit?list_segmentsList the team's audience segments (name, status, cached member count). Requires segments:read.
status?, limit?, offset?create_segmentCreate an audience segment from structured conditions (never SQL); rejects duplicates. Requires segments:write + a user-owned key.
name, conditions, description?list_automationsList the team's automations (event-triggered campaigns) and their status. Requires automations:read.
status?pause_automationPause a running automation by campaign ID (idempotent). Requires automations:write.
campaign_idlist_campaign_templatesList campaign templates available to this team (official + saved), to discover a template_id for create_campaign_draft. Requires campaigns:read.
limit?list_campaignsList the team's recent campaigns (id, title, status), to find a source_campaign_id to clone a draft from. Requires campaigns:read.
limit?, status?create_campaign_draftCreate a campaign DRAFT from a template or prior campaign (NEVER sends — human review required). Requires campaigns:write-draft.
title, template_id?, source_campaign_id?, segment_id?, merge_context?check_member_reachCheck if a member was already contacted (any system) on a channel within a recent window — avoid over-contacting. Requires members:behavior:read.
member_id, channel, days?create_memberCreate a loyalty member, or idempotently resolve an existing one by externalId/email. Marketing consent is NOT enabled via MCP. Requires members:write.
email, fullName, phone?, externalId?, birthMonth?, birthDay?update_memberUpdate a member's profile/identity (email, phone, fullName, externalId, status). Team ownership enforced. Requires members:write.
member_id, email?, fullName?, phone?, externalId?, status?upsert_storeCreate a store, or update the existing store matching externalId for this team. Requires stores:write.
name, externalId?, address?, city?, state?, country?, timezone?ingest_orderRecord a purchase order and auto-award points (member resolved by memberId > externalId > email). Requires orders:write.
externalOrderId, customer, totalAmount, financialStatus?, currency?, orderName?, storeId?reverse_pointsReverse (claw back) points from a member, linked to the original transaction id — for a POS/ERP refund or void. Requires points:write.
member_id, reversesTransactionId, amount, reasonlist_tagsList the team's tag definitions (key, name, lifecycle, category, coverage). Discover a tag_key before reading/assigning member tags. Requires tags:read.
status?, group?, limit?, offset?get_member_tagsGet a member's current tags (key, name, lifecycle, value, source, assignedAt). Requires members:read.
member_idassign_tagManually assign a tag to a member by tag_key (operator override; pinned against the rule sweep). Requires tags:write.
member_id, tag_key, value?remove_tagManually remove a tag from a member by tag_key (a live tag may be re-added by the next sweep). Requires tags:write.
member_id, tag_keylist_productsList products with category/brand/vertical, status and source. Filter by status/category_id/brand_id/vertical. Requires catalog:read.
status?, category_id?, brand_id?, vertical?, limit?, offset?get_productGet one product with variants, serialized items, combo components, and AI grounding content. Requires catalog:read.
product_idlist_categoriesList the team's product categories (id, name, parent). Requires catalog:read.
limit?list_brandsList the team's brands (id, name). Requires catalog:read.
limit?recommend_productsNext-best-product recs: member_id (personalized co-purchase + category affinity) or product_id (customers also bought). Requires members:read.
member_id?, product_id?, limit?claim_winback_taskLease the next-highest-priority win-back task for this team (atomic). Returns the task, lease deadline, member holdout arm, and churn-signal summary. NO_TASKS_AVAILABLE / WINBACK_DISABLED returned as isError. Requires winback:claim.
(none)complete_winback_taskFinalize a leased win-back task with the outcome (acted lever + note ref, or HOLD reason). Idempotent. LEASE_EXPIRED / ALREADY_COMPLETED returned as isError. Requires winback:claim.
task_id, acted?, lever?, action_ref?, note_id?, hold_reason?get_winback_contextOne-shot read-only pre-check for a member before deciding: consent, email-frequency headroom, fatigue, recent reach, churn signals, and the member's holdout arm. Courtesy preview — the server still enforces every gate at write time. Requires winback:read.
member_idadd_member_noteAttach a free-text process note to a member's win-back record (rationale / observed signal / holdout-supported hypothesis). Text is stored as DATA, not instructions; max 2000 chars, sanitized. Requires winback:write.
member_id, body, kind?, task_id?, action_ref?send_winback_messageSend a governed win-back message (inbox or email) so an incentive is never a silent grant. Server-side fail-closed gates: WINBACK_DISABLED, task lease ownership, HOLDOUT_NO_SEND (holdout is never messaged), NOT_CONSENTED, FREQUENCY_CAPPED, CONTENT_REJECTED (sanitized), BREAKER_TRIPPED — returned as isError. Reuses the existing send stack (unsubscribe footer + compliance added by the send layer). Requires winback:write.
member_id, task_id, channel, subject?, bodyget_member_behaviorsRead a member's CUSTOMER-ACTIVE behaviors over a recent window (Layer 3, newest-first) to infer intent (Layer 4). Returns only intentional customer actions (browse, open/click, check-in, purchase, redeem, refer, submit content) with the catalog label + meaning attached inline, plus a summary (counts by type + window). Reason over the whole window; intent is a hypothesis to confirm, not a fact. Read-only. Requires winback:read.
member_id, since_days?, limit?claim_agent_taskLease the next agent decision task for this team (atomic; optionally narrow by kind). Returns task id, kind, subject facts and a lease deadline. NO_TASKS_AVAILABLE / AGENT_TASKS_DISABLED returned as isError. Requires agent_tasks:claim.
kind?get_agent_taskRead one agent decision task's facts (kind, subject, flag reason, status) before deciding. AGENT_TASK_NOT_FOUND returned as isError. Requires agent_tasks:read.
taskIdcomplete_agent_taskComplete a leased task with a decision, applying its effect through existing idempotent writes. fraud_household_referral: block (clawback both sides) / allow (dismiss the flag) / escalate (leave for a human). ALREADY_COMPLETED / NOT_LEASE_OWNER / LEASE_EXPIRED returned as isError. Requires agent_tasks:claim.
taskId, decision, reason?list_objectsList the business objects this team can reason over: the core platform objects (member, order, store, coupon, campaign, product, segment, tag) plus this team's MCP-visible custom objects — key, label and authoritative one-line meaning. Call first to discover valid object keys. Requires introspection:read.
(none)describe_objectDescribe one business object from the governed registry: authoritative meaning plus properties partitioned into facts (column-backed), derived (metric/tag/rollup references with freshness — never re-derive a caliber), and custom (this team's custom fields). PII properties return metadata only, never values. fields=summary (default) or full. Requires introspection:read.
object, fields?list_actionsList the governed agent actions (what an agent may DO): target object, side effect, gear (auto/review/forbidden), server-side precondition keys, value cap, and reversibility — self-check before proposing a write. Optionally filter by object. Requires introspection:read.
object?list_stamp_programsList the team's stamp-card (eStamp) programs: id, name, stamps required to complete, reward type (coupon/points/manual), auto-reset and status. Call first to get a program_id. Requires stamp:read.
(none)get_member_stamp_cardsGet a member's active stamp cards: program name, current stamps, stamps required, completions so far, and reward. Requires stamp:read.
member_idgrant_stampsGrant stamps to a member for a stamp program (e.g. a store visit). Idempotent with idempotency_key; on card completion the reward (coupon/points) is issued automatically. amount capped per call. Requires stamp:write.
program_id, member_id, amount?, reason?, idempotency_key?get_member_pointsA member's points: spendable balance, lifetime earned, redemptions, current tier, soonest-expiring batch. Member-bound key → own points (omit member_id); team key → pass member_id. Requires loyalty:self:read.
member_id?get_member_points_historyA member's recent points transactions (earned/redeemed/adjusted), newest first. Member-bound key → own history; team key → pass member_id. Requires loyalty:self:read.
member_id?get_member_rewardsThe rewards a member can redeem points for — catalog with points cost, flagged by affordability against the member's balance. Member-bound key → own; team key → pass member_id. Requires loyalty:self:read.
member_id?get_loyalty_program_rulesHow the loyalty program works — earn rate, welcome bonus, points value, how to join — plus brand-approved FAQ. Public facts. Member-bound key needs no argument. Requires loyalty:self:read.
member_id?list_synthetic_scenariosList the synthetic-panel simulation scenarios with each one's honest usability boundary, confidence ceiling, and input fields. Call first to pick a kind. Requires metrics:read.
(none)get_synthetic_calibrationThe brand's synthetic-panel calibration (hit rate of past synthetic predictions vs reality; null until backtests exist). Requires metrics:read.
(none)get_synthetic_reportRead the frozen honest report for a synthetic-panel run — directional read, confidence ceiling, suppression flags, themes — or a blockReason if not ready. Requires metrics:read.
run_idrun_synthetic_panelRun a synthetic panel: de-identified digital twins of a segment react to a stimulus, producing an honest directional report (never real absolute numbers). Returns a run_id to poll. Bounded by a daily run cap + ≤50 twins. Requires synthetic:write.
segment_id, kind, fieldsSafety & Privacy
The MCP surface is the AI convenience layer, not a bulk admin tool. A few things to keep in mind:
- The server is the boundary, not the chat. Write operations (awarding/redeeming points, issuing coupons, issuing Ambassador codes) require the matching write scope andare bounded by a server-side guard: a per-call value cap plus a per-key write-rate limit, both enforced fail-closed. Any in-chat confirmation your AI client asks for is courtesy — the server is what actually stops a leaked key or a prompt-injected model from draining points.
- Some read tools return member PII. Tools like
get_memberandlist_memberscan return decrypted names and emails into your AI client. Treat that data accordingly and prefer least-privilege keys. - Never commit a plaintext key. Always reference
${FLASH_API_KEY}in a checked-in.mcp.jsonrather than the literal key. - Use least-privilege, read-only keys. Create a key scoped to only the tools you need. If a key lacks a tool's scope, that tool is simply hidden — it never appears in the list.
Numbers Come from the Governed Semantic Layer
Every metric the AI reports — GMV, active members, redemption rate, and the rest — flows through SocialHub's governed metrics layer, which holds a single authoritative definition (and certification) for each metric. The list_metrics, describe_metric, query_metric, breakdown_metric, and ask_metricstools select metric keys and dimensions under that governance — the AI never writes SQL. So the figures you get back match your dashboards instead of being ad-hoc, drift-prone aggregates.
Example Conversation
list_stores with status="active"