Braze MCP server for AI agents

Live

BEARER TOKEN

CUSTOMER ENGAGEMENT

Marketing

Braze gives your agent customer engagement on your Braze workspace: read campaign, Canvas, and segment analytics, trigger campaigns and Canvases, send messages, and track user profiles, events, and subscriptions.

  • Per-user credentials: each call uses the actual user's access token, never a shared bot.
  • Encrypted per-tenant vault: AES-256, resolved at request time, never in LLM context.
  • Scoped before every call: pre-call scope check, 90-day SIEM-exportable audit chain.
Braze
agent · Acme Q3
Run
How did the spring promo campaign do yesterday?
S
braze_campaign_analytics_get
121ms
Lifecycle marketing agent
The spring promo campaign sent 84,200 emails yesterday, with 21,050 opens, 3,410 clicks, and 212 conversions.
Sources: Braze campaign analytics, 1 day
braze
1 campaign
18:29
Message Claude...

Tools your lifecycle marketing agent reaches for on Braze, scoped per user.

CALL ANY TOOL
73 tools for customer engagement in Braze: read campaign, Canvas, segment, and KPI analytics, trigger and schedule campaigns and Canvases, send messages, manage catalogs, templates, and Content Blocks, and update user profiles and subscriptions.
braze_campaign_analytics_get
Get campaign analytics
Get daily performance stats for a campaign over a date range. Returns a data array with one entry per day, holding per-channel stats such as sends, opens, clicks, conversions, and revenue. Use braze_campaign_analytics_get for a campaign's totals; use braze_send_analytics_get for one tracked send; use braze_canvas_analytics_get for Canvases.
Parameters
Name
Type
Required
Description
campaign_id
string
Required
The campaign API identifier, found on the campaign's details page in the Braze dashboard, under Settings > APIs and Identifiers, or from braze_campaigns_list. Example: 4cf9b8b8-3b1c-4a0a-9b9e-2a8b2c1d3e4f.
length
integer
Required
How many days before ending_at to include in the series, between 1 and 100. Example: 14.
ending_at
string
Optional
ISO 8601 datetime the series ends on; defaults to the time of the request. Example: 2026-10-01T23:59:59Z.
braze_campaign_duplicate
Duplicate campaign
braze_campaign_trigger_schedule_create
Create campaign trigger schedule
braze_campaign_trigger_schedule_update
Update campaign trigger schedule
braze_campaign_trigger_send
Send campaign trigger
braze_campaigns_list
List campaigns
braze_canvas_analytics_get
Get canvas analytics
braze_catalog_create
Create catalog
braze_catalog_item_get
Get catalog item
braze_catalog_item_update
Update catalog item
braze_catalog_items_list
List catalog items
braze_catalog_selection_create
Create catalog selection
braze_content_blocks_list
List content blocks
braze_custom_event_analytics_get
Get custom event analytics
braze_custom_events_list
List custom events
braze_email_subscription_status_update
Update email subscription status
braze_email_template_create
Create email template
braze_email_unsubscribes_list
List email unsubscribes
braze_kpi_dau_get
Get kpi dau
braze_kpi_new_users_get
Get kpi new users
braze_messages_schedule_update
Update messages schedule
braze_messages_send
Send messages
braze_preference_center_create
Create preference center
braze_preference_center_url_get
Get preference center url
braze_purchase_products_list
List purchase products
braze_purchase_revenue_get
Get purchase revenue
braze_segments_list
List segments
braze_send_analytics_get
Get send analytics
braze_subscription_group_status_set
Set subscription group status
braze_users_export_by_ids
Users export by ids

For more tools, view docs.

Build your Agent
Same auth pattern across LangChain, OpenAI, Anthropic, and Google ADK.
Python · LlamaIndex
import { ScalekitClient } from "@scalekit-sdk/node";
import { createReactAgent } from "@langchain/langgraph/prebuilt";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);

// Braze tools scoped to this user
const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["braze"], toolNames: [
    "braze_campaigns_list",
    "braze_campaign_analytics_get",
    "braze_campaign_trigger_send"] },
  pageSize: 100,
});

const agent = createReactAgent({ llm, tools });
await agent.invoke({ messages: [{ role: "user", content: "Show yesterday's stats for the spring promo campaign" }] });
import OpenAI from "openai";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);
const openai = new OpenAI();

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["braze"] }, pageSize: 100,
});

const res = await openai.chat.completions.create({
  model: "gpt-5",
  messages: [{ role: "user", content: "Show yesterday's stats for the spring promo campaign" }],
  tools,
});

// Execute the tool call with the user's vaulted Braze access token
await sk.tools.executeTool(res.choices[0].message.tool_calls[0], "user_123");
import Anthropic from "@anthropic-ai/sdk";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);
const anthropic = new Anthropic();

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["braze"] }, pageSize: 100,
});

const msg = await anthropic.messages.create({
  model: "claude-sonnet-5",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Show yesterday's stats for the spring promo campaign" }],
  tools,
});

// Tool call runs with the user's vaulted Braze access token
await sk.tools.executeTool(msg.content, "user_123");
import { Agent } from "@google/adk/agents";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["braze"] }, pageSize: 100,
});

const agent = new Agent({
  name: "lifecycle_marketing_agent",
  model: "gemini-2.5-pro",
  instruction: "Braze tools scoped to this user",
  tools,
});

await agent.run("Show yesterday's stats for the spring promo campaign");
Try these prompts
Copy any prompt into your agent. Each maps directly to a Braze tool. Click to copy, paste into your agent, done.
Analytics
Copy the prompt
Copied
Show daily stats for the spring promo campaign over the last 7 days.
Copy the prompt
Copied
What was our daily active user count for the past 2 weeks?
Copy the prompt
Copied
Get the estimated size of the lapsed users segment this month.
Messaging
Copy the prompt
Copied
Send the API-triggered welcome campaign to user 81723.
Copy the prompt
Copied
Schedule these users to enter the onboarding Canvas on Monday at 9am.
Copy the prompt
Copied
List campaigns and Canvases scheduled to send this week.
Users and content
Copy the prompt
Copied
Log a plan_upgraded event and a purchase on user 81723's profile.
Copy the prompt
Copied
Unsubscribe this email address from the marketing subscription group.
Copy the prompt
Copied
Create a Content Block with our new footer HTML.
SEE HOW AUTH WORKS
Each user connects their own Braze access token once, and Scalekit sends it with every call. Credentials stay vaulted, every call is scope checked, and every action is logged.
1
Authorize
Your user connects
Braze
once. We tie it to their identity and the meetings they approved — no shared bot account, no org-wide access
Who:
user ‘A’
when:
Once per user
access:
Limited to user
2
Store
Their
Braze
token lives in a vault scoped to them. User A's meetings are never reachable by an agent acting for user B, even on the same connection
vault:
encrypted
scope:
per-user
tokens:
auto-refreshed
3
Resolve
When your agent calls a
Braze
tool, we fetch the right token server-side. It never touches your agent, never appears in the LLM context, never shows up in your logs
speed:
~40ms
check:
before every call
seen by:
nobody
4
Audit
Every
Braze
tool call is logged — who triggered it, which meeting was fetched, what came back. 90 days of history, tied to the user who authorized it
history:
90 days
export:
SIEM-ready
logged:
every call
Test other agents
See the same per-user auth pattern across other marketing and messaging connectors.
GTM and RevOps Teams
CRM AI agent
Reads the Granola transcript after every call, extracts next steps and updates the HubSpot record, drafts the follow-up in Gmail, and confirms in Slack, all on the rep's own delegated OAuth.
Engineering Teams
Slack triage
Polls Slack for new messages, classifies bugs and support requests with a LangGraph router, files GitHub issues or Zendesk tickets, and confirms in the thread.
Test other agents
See the same per-user auth pattern across other marketing and messaging connectors.
GTM
CRM AI agent
Turn each Granola call transcript into a HubSpot record update, a drafted Gmail follow-up, and a Slack recap.
ENGINEERING
Slack triage agent
Classify new Slack messages as bugs or support requests, file the GitHub issue or Zendesk ticket, and reply in the thread.
Why Scalekit
Secure your agent's access. Connectors ship in minutes
01.
Shared tokens break per-user analytics
A shared Braze access token looks fine in a demo. In production every campaign send looks like one service account, and you cannot tell which user triggered it. Scalekit resolves the credential of the actual user who triggered the agent, never a shared bot.
// shared token
audit → bot_service_account

// scalekit
audit → user_abc ✓
02.
Authentication is not authorization
03.
Multi-tenancy is architectural
04.
Braze today. Ten connectors tomorrow.
“Our agents act across Salesforce, Gong, Google Drive, and more, on behalf of every customer. Scalekit behind the scenes meant we can keep adding tools without ever rebuilding how credentials or tool calling work.”
Venu Madhav Kattagoni
Head of Engineering / Von
FAQs
Frequently Asked Questions
Does the agent access Braze as the user or through a shared token?
As the user. Each user connects their own Braze access token once, and Scalekit sends it with every call. Sends, schedule changes, and profile updates are attributed to that user in your audit trail, not a shared service account.
Where is the Braze access token stored?
In Scalekit's managed AES-256 token vault, namespaced per tenant. To rotate it, the user reconnects with a new access token. Revocation is a single dashboard action. Credentials never appear in prompts, logs, or LLM context.
Can I limit what the agent does in Braze?
Yes. Filter by tool name in listScopedTools to expose only what you want, for example the analytics and list tools without braze_messages_send or braze_campaign_trigger_send, which send messages to real users. Scalekit also enforces scope checks before every API call.
What happens when a user revokes Braze access?
The connection is invalidated on the next tool call. Subsequent requests for that user fail closed with a clear error. Other users in the tenant remain unaffected. The event is logged for audit.
Can the agent send a Braze campaign without writing the message content?
Yes. braze_campaign_trigger_send sends an API-triggered campaign whose content lives in the Braze dashboard, and braze_canvas_trigger_send enters recipients into an API-triggered Canvas. braze_messages_send sends a message with content defined in the request instead.
Start in your coding agent
Up and running in one command
Install the Scalekit skill in your editor of choice. Connector, auth, tools, prompt, all wired up
Claude Code REPL
/plugin marketplace add scalekit-inc/claude-code-authstack
/plugin install agentkit@scalekit-auth-stack
Cursor Code REPL
# ~/.cursor/mcp.json
{
""mcpServers"": {
""braze"": {
""url"": ""https://mcp.scalekit.com/braze"",
""headers"": { ""Authorization"": ""Bearer $SCALEKIT_TOKEN"" }
}
}
}
Codex Code REPL
# ~/.codex/config.toml
[mcp_servers.braze]
url = ""https://mcp.scalekit.com/braze""
auth_env = ""SCALEKIT_TOKEN""
Copilot Code REPL
# .vscode/mcp.json
{
""servers"": {
""braze"": {
""url"": ""https://mcp.scalekit.com/braze"",
""type"": ""http""
}
}
}