Announcing CIMD support for MCP Client registration
Learn more

Braze MCP vs API for AI Agents Integration

Shri Mithran
Director of Marketing

Braze gives an agent a hosted MCP server built for marketers and analysts, and a REST API that thousands of production integrations already depend on. They overlap on analytics, catalogs and content, then diverge on user data, message sends, Canvas edits and whose identity each call carries: a signed-in dashboard user on MCP, a never-expiring workspace key on the API. This guide compares what each path lets a lifecycle agent do and how to run either across many customer workspaces in production.

TL;DR

  • Braze hosts an official remote MCP server at https://mcp.braze.com/mcp (US) and https://mcp.braze.eu/mcp (EU). It shipped in early access on July 23, 2026 and was listed as generally available in Braze's September 17, 2026 release notes, with its Campaigns and Segments tools and Operator Connect still in beta. It exposes 71 tools (37 read, 34 write) across analytics, campaigns, Canvases, catalogs, segments, templates, and Content Blocks. It deliberately returns no user-level PII, Canvas tools are read-only, and no tool sends a message to a named user or writes a user profile.
  • The MCP server takes OAuth only, including SSO, and every call runs with the signed-in user's dashboard permissions across all the workspaces they can reach. A company admin must enable MCP OAuth access, each user needs the "Use MCP Server" permission, Braze keeps an allowlist of client domains, and companies that use IP allowlisting cannot use the server at all.
  • The REST API is served from a different host per Braze instance (for example https://rest.iad-01.braze.com or https://rest.fra-01.braze.eu) and authenticates with a REST API key sent as Authorization: Bearer. Keys belong to one workspace, carry a permission set fixed at creation, never expire, and survive the deletion of the user who created them. A key identifies a workspace integration, not a person.
  • MCP is the faster path for a lifecycle marketer asking Claude how last week's campaigns performed or drafting a template in staging. The API is the right path for headless agents that write user profiles and events with /users/track, trigger API-triggered campaigns and Canvases, manage subscription state, or read individual profiles.
  • Scalekit's braze connector exposes 73 prebuilt tools over the Braze REST API. Each user connects their own Braze key once, Scalekit stores it encrypted and sends it as a Bearer token on every call, and the agent never sees it, so the MCP vs API decision doesn't change your auth infrastructure.

The decision your Braze agent forces first

Your agent needs to work inside your customers' Braze workspaces: tell a lifecycle team which Canvas is losing conversions at step three, check which campaigns are scheduled to send this weekend, push a churn-risk score onto 40,000 profiles, or enter a user into a win-back Canvas the moment your product sees them cancel. Braze now hosts an official Model Context Protocol (MCP) server that Claude, ChatGPT, Cursor, and Codex connect to with a sign-in. It also has a REST API that thousands of production integrations already depend on. They overlap on analytics, catalogs, and content. They diverge on user data, message sends, Canvas edits, and on whose identity each call carries. Here's how to pick.

What Braze MCP and Braze API actually are

Braze MCP

The Braze MCP server is hosted by Braze. You paste https://mcp.braze.com/mcp or https://mcp.braze.eu/mcp into an MCP client and sign in; either endpoint can reach any Braze cluster, though EU customers should use the EU one. Braze's July 23, 2026 release notes introduced the remote server in early access, and the September 17, 2026 release lists it as generally available, "with no local package, configuration file, or API key," while marking its Campaigns and Segments support and Operator Connect as beta.

The first Braze MCP server, released in August 2025, ran locally and needed a REST API key. Braze has deprecated it: it still works but receives no updates, and the remote server has tools the local one lacks.

The 71 tools use names such as get_campaign_dataseries, get_canvas_data_summary, get_segment_list, create_email_template, update_content_block, edit_catalog_items, create_campaign, launch_campaign, and trigger_integration_sync. Three Operator tools (send_operator_prompt, get_operator_result, cancel_operator_job) hand work to Braze's own AI assistant. Braze states plainly that "tools that expose user-level PII are not available."

Braze API

The Braze REST API is served from the REST endpoint of the instance your company was provisioned on: US-01 through US-10, EU-01, EU-02, AU-01, ID-01, JP-01, and KR-01, each with its own host. It covers user data (/users/track, /users/identify, /users/export/ids, aliases), messaging (/messages/send, /campaigns/trigger/send, /canvas/trigger/send, schedules, transactional email), subscription groups and email state, campaign, Canvas, segment, KPI, purchase, and session analytics, catalogs, templates, Content Blocks, and preference centers.

Auth has one shape. A workspace admin creates a REST API key under Settings > APIs and Identifiers > API Keys, names it, picks permissions such as users.track or messages.send, and optionally restricts it to IP addresses and subnets. Requests send the key in an Authorization: Bearer header. A missing or invalid key returns 401; a key without the endpoint's permission returns 403.

Comparing them where it matters for agents

What your agent can actually do

Capability
Braze MCP (mcp.braze.com)
Braze API (REST endpoint per instance)
Campaign and Canvas analytics
Yes
Yes
KPIs, sessions, purchases, custom events
Yes
Yes
Segments
Yes: Read, plus and (beta)
Limited: No create or edit
Build and launch campaigns
Yes
Limited: No create, edit, or launch tools
Canvases
Limited: Four read tools only
Limited
Send or trigger messages to named users
No: No send tools
Yes
Schedule sends
No
Yes
Read individual user profiles
No: No user-level PII by design
Yes
Write profiles, events, purchases
No
Yes
Subscription and email state
No
Yes
Catalogs, templates, Content Blocks
Yes
Yes
Cross-workspace work in one session
Yes: One sign-in reaches every workspace the user can access
No: One key per workspace

The split is intentional. Braze built the MCP server for people who plan and analyze: marketers, analysts, and CRM leads asking questions in a chat window and drafting content with a human reviewing each step. The REST API is where your product talks to Braze about specific users: who did what, who should get which message, and who opted out. An agent that needs to touch a user's profile or send them anything is on the API path.

What the MCP path makes easier

Answering "how did every campaign we launched last week perform, and which Canvases are scheduled to send this weekend" on the raw API takes a list call, a filter on last_edited, one data series call per campaign, a scheduled broadcasts call, and a sum across per-channel stats. The MCP server gives the model the same primitives with Braze-written descriptions, and one sign-in covers the US and EU workspaces together. Braze's usage guide shows exactly that pattern, plus copying templates from a staging workspace into production with create_email_template. Writing the schema is the hard part. Not the API call.

The MCP server also reaches things the REST API leaves to the dashboard: drafting and launching campaigns through the beta Campaigns tools, creating segments, kicking off a Cloud Data Ingestion sync with trigger_integration_sync, and delegating a task to Braze's Operator.

The tradeoff is that Braze owns the surface. The campaign and segment tools are beta, the local server's tools already gave way to a different remote set, and Braze advises against "auto-mode" so a human reviews each action. Campaign edits made through MCP are attributed to the signed-in user and appear in edit history, which is the right behavior for a person and an odd fit for an unattended job.

The auth path each one puts you on

On the MCP path, auth is OAuth in the browser, with SSO if your company requires it. The setup guide says no client ID, client secret, or API key is needed: the client registers itself with Braze. Registration alone is not enough. A company admin must turn on MCP OAuth access and approve the client's redirect URI under Settings > Admin Settings > External Connections, and each user needs the "Use MCP Server" permission, which is off by default, in every workspace they want to reach. Access tokens are short-lived and refresh automatically. Admins can revoke every MCP OAuth token in the company at once. Successful connections are logged to the security event report.

Two constraints matter if you are building your own agent rather than using Claude or Cursor. Braze maintains an allowlist of supported client domains, so an unverified client can be blocked at sign-in. And customers that use dashboard IP allowlisting cannot use the MCP server at all, which in practice rules out many of the security-conscious enterprises a B2B product sells to.

On the direct API path, the credential is a REST API key. Braze's API basics spell out its properties: it belongs to one workspace, its permissions and allowlisted IPs cannot be edited after creation, it has no expiry, and "deleting a user does not delete API keys that user created." To change scope, you create a new key and replace the old one. The key also only works against its own instance's REST host, so your agent has to know whether a customer lives on rest.iad-03.braze.com or rest.fra-02.braze.eu.

The difference that matters most for agents is identity. An MCP call runs as a Braze dashboard user; Braze says access "mirrors your dashboard user permissions" and "an agent can never exceed your own access." A REST call runs as a key. Braze knows which permissions the key has and nothing about the person behind the agent request. What the user can't do, the agent can't do: on the API path, that only holds if each user's key is created with that user's permissions.

Both paths still need per-user isolation

In a multi-tenant B2B agent, MCP gives you an OAuth grant per user and the direct API gives you a key per user or per workspace. In neither case does the path itself solve storage, rotation, or revocation; those are infrastructure problems regardless of which path you choose.

Braze sharpens the problem on the API side. The convenient setup is one broad key per customer workspace with users.track, messages.send, user export, and every analytics permission checked. That key can export any profile in the workspace and message any user in it. A reporting assistant used by a junior analyst then carries the same reach as the integration that sends password resets. The safer setup is several narrow keys per workspace, one per role, each created with only the permissions that role needs, which multiplies the secrets you hold and the mapping you maintain between your users and Braze keys.

Recommended reading: access control for multi-tenant AI agents

What you own in production

On the MCP path, Braze hosts the server, writes the tool schemas, and enforces each user's permissions. You own each user's OAuth session in a client Braze has allowlisted, the admin setup in every customer company, and the gaps. Tools only run inside a conversation someone starts, so nothing happens when a user cancels a subscription in your product. User profiles, sends, and subscription state are not reachable. Braze does not document rate limits or quotas for the MCP server.

On the API path, you own schemas, batching, retries, and the credential lifecycle. Braze's rate limits are per workspace and differ by endpoint. /users/track accepts up to 75 objects combined across attributes, events, and purchases per request. Messaging endpoints accept up to 50 named recipients per request, and broadcast sends are limited to 250 requests per minute overall and 10 per minute per unique audience. /users/export/ids allows 250 requests per minute for workspaces onboarded on or after August 22, 2024, and those workspaces must pass fields_to_export. Many list and analytics endpoints share a 250,000 requests per hour budget that resets on the clock hour, not on a rolling window. A 429 comes with lowercase x-ratelimit-limit, x-ratelimit-remaining, and x-ratelimit-reset headers, and Braze tells you to honor X-RateLimit-Retry-After when it is present.

Braze also has no general-purpose webhook for "a user's profile changed." Events flow out of Braze through its data export products, not through a subscription your agent registers per key, so a headless Braze agent is usually driven by your own product's events rather than by Braze's.

When to use MCP, when to use the API

Use Braze MCP when:

  • A lifecycle marketer in Claude asks how last week's campaigns did by channel, and get_campaign_dataseries plus get_campaign_list answer it without a dashboard export.
  • A CRM lead wants a weekly Canvas health summary across US and EU workspaces from one sign-in, using get_canvas_data_summary and get_workspaces.
  • A content team copies email templates and Content Blocks from staging to production with create_email_template and update_content_block, with a person reviewing each write.
  • You want to draft and launch campaigns or build segments conversationally, accept that those tools are beta, and your customer does not use IP allowlisting.

Use the Braze API when:

  • The agent runs headless: your product sees a cancellation, and the agent writes a churn_risk attribute with braze_users_track and enters the user into a win-back Canvas with braze_canvas_trigger_send.
  • The workflow is a deterministic pipeline: nightly subscription syncs with braze_subscription_group_status_set_v2, or suppression checks against braze_email_unsubscribes_list and braze_email_hard_bounces_list.
  • The task touches individual users, such as a support agent reading one profile's message history with braze_users_export_by_ids, which the MCP server excludes by design.
  • You serve many customer workspaces across Braze instances, need keys scoped per role, and must respect per-endpoint limits and the 50-recipient and 75-object batch caps.

The credential problem that exists on both paths

Both paths hand you a Braze credential. Neither hands you a vault. A multi-tenant agent serving 40 customer companies, each with a US and an EU workspace and three agent roles per workspace, holds 240 REST API keys on the API path if it scopes keys properly. Each key never expires, is bound to one instance host, cannot have its permissions changed, and stays valid after the employee who created it leaves. Each must be stored encrypted, kept out of logs and LLM context, mapped to exactly one workspace and role, and revoked in the Braze dashboard when the customer churns.

The MCP path changes the count, not the problem: an OAuth session per marketer, living in a chat client, gated by an admin setting in each customer company, and unavailable to every customer that turned on IP allowlisting. The tempting shortcut on the API path is one all-permissions key per workspace. Fewer secrets, larger blast radius per secret: one leaked key can export every profile in the workspace and message every user in it.

Scalekit's braze connector stores each user's Braze key encrypted in the token vault and sends it as a Bearer token on every call, so the MCP vs API decision doesn't change your auth infrastructure. Your agent passes an identifier; credentials never touch the agent runtime or the LLM context.

Recommended reading: OAuth vs API keys for AI agents

How to connect a Braze agent with Scalekit

Scalekit's braze connector is an API-path connector built by Scalekit with 73 tools: 39 read, 34 write, and none destructive. It covers campaign, Canvas, segment, send, KPI, session, purchase, and custom event analytics; API-triggered campaign and Canvas sends and schedules; message sends and schedules; transactional email; user tracking, identification, aliases, and export; subscription groups, email subscription state, unsubscribes, hard bounces, and invalid SMS numbers; catalogs, email templates, Content Blocks, the media library, and preference centers. It authenticates with a Bearer token: each user connects their Braze REST API key once, and Scalekit attaches it to every call.

Prerequisites and the connection name

In the Scalekit dashboard, go to AgentKit > Connections and create a Braze connection. The name you give it is the connection_name your code passes, and the string must match the dashboard exactly. This is the most common integration error.

Plan the keys before users connect them. Braze permissions are fixed at creation, so create one key per agent role in each workspace: an analytics key for the reporting assistant, and a separate key with only the user-tracking and Canvas-trigger permissions for the lifecycle pipeline. Copy SCALEKIT_ENVIRONMENT_URL, SCALEKIT_CLIENT_ID, and SCALEKIT_CLIENT_SECRET from Developers > API Credentials into .env.

pip install scalekit-sdk-python python-dotenv langchain-openai

Authorize each user once

get_or_create_connected_account returns the connected account for an identifier. If it is not ACTIVE, get_authorization_link returns a link to Scalekit's Hosted Connect Widget. For a Bearer-token connection like Braze, the widget shows a form where the user enters the credentials the connection requires, instead of an OAuth consent screen. Scalekit encrypts and stores what they enter; your code never receives the key. Because a Braze key belongs to one workspace, make the identifier specific to the user and the workspace.

import os from dotenv import load_dotenv from scalekit import ScalekitClient load_dotenv() scalekit_client = ScalekitClient( env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], client_id=os.environ["SCALEKIT_CLIENT_ID"], client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], ) actions = scalekit_client.actions CONNECTION_NAME = "braze" # must match the connection name in AgentKit > Connections identifier = "acme_us_prod_user_5520" # your app's stable ID for this user in this Braze workspace account = actions.get_or_create_connected_account( connection_name=CONNECTION_NAME, identifier=identifier, ) if account.connected_account.status != "ACTIVE": link = actions.get_authorization_link( connection_name=CONNECTION_NAME, identifier=identifier, ) print("Open this link and enter your Braze REST API key:", link.link) input("Press Enter after submitting the form...") account = actions.get_or_create_connected_account( connection_name=CONNECTION_NAME, identifier=identifier, ) if account.connected_account.status != "ACTIVE": raise RuntimeError(f"Braze is {account.connected_account.status}, not ACTIVE")

Retrieve the Braze tools this account can call

This is not a catalog load. The agent asks for the tools this connected account is authorized to call, then narrows them to the six a campaign reporting assistant needs. Loading all 73 Braze tools would put braze_messages_send, braze_canvas_trigger_send, and braze_users_track in front of a model whose job is to summarize performance. None of the six below changes anything in Braze.

tools = actions.langchain.get_tools( identifier=identifier, connection_names=[CONNECTION_NAME], tool_names=[ "braze_campaigns_list", "braze_campaign_analytics_get", "braze_canvases_list", "braze_canvas_analytics_summary_get", "braze_scheduled_broadcasts_list", "braze_segment_analytics_get", ], page_size=100, ) tool_map = {t.name: t for t in tools} print(sorted(tool_map))

Run the agent loop

The loop runs until the model stops requesting tools. Every call runs with this user's Braze key, so the system prompt tells the model how Braze's list and analytics tools fit together and what to do when the key lacks a permission.

from langchain_core.messages import HumanMessage, SystemMessage, ToolMessage from langchain_openai import ChatOpenAI llm = ChatOpenAI(model="gpt-4o").bind_tools(tools) messages = [ SystemMessage( "You report on Braze campaign and Canvas performance for a lifecycle team. " "Use braze_campaigns_list with sort_direction 'desc' and last_edited_after to find " "recent campaigns, then braze_campaign_analytics_get with campaign_id, length, and " "ending_at for daily per-channel stats. For Canvases, use braze_canvases_list and " "braze_canvas_analytics_summary_get with ending_at and length between 1 and 14. " "Use braze_scheduled_broadcasts_list with an ISO 8601 end_time to see upcoming sends. " "Never guess IDs. If a call returns 403, say this Braze key lacks that permission." ), HumanMessage( "For campaigns edited since 2026-10-19T00:00:00Z, give me sends, unique opens, clicks, " "and conversions for the last 7 days ending 2026-10-28T23:59:59Z. Then list every " "campaign and Canvas scheduled to send before 2026-11-02T00:00:00Z." ), ] while True: response = llm.invoke(messages) messages.append(response) if not response.tool_calls: print(response.content) break for tc in response.tool_calls: tool = tool_map.get(tc["name"]) if tool: result = tool.invoke(tc["args"]) else: result = f"Unknown tool: {tc['name']}" messages.append(ToolMessage(content=str(result), tool_call_id=tc["id"]))

Deterministic calls with execute_tool

For pipelines, skip the model. execute_tool runs one tool with a fixed input and returns data plus an execution_id you can log. This job runs when your product records subscription cancellations. It writes a churn_risk attribute and a subscription_canceled event for each user with braze_users_track, then enters them into an API-triggered win-back Canvas with braze_canvas_trigger_send. It respects Braze's batch caps: 25 users per /users/track request (one attribute and one event each, 50 objects of the 75 allowed) and 50 recipients per Canvas trigger. The connected account here should hold a key with only the users.track permission and the Canvas trigger permission.

from datetime import datetime, timezone PIPELINE_IDENTIFIER = "acme_us_prod_lifecycle_pipeline" # connected account holding the narrow key WINBACK_CANVAS_ID = os.environ["BRAZE_WINBACK_CANVAS_ID"] # from braze_canvases_list or the dashboard def chunks(items: list, size: int): for i in range(0, len(items), size): yield items[i : i + size] def enter_winback(cancellations: list[dict]) -> None: """cancellations: [{"external_id": "user_123", "plan": "pro", "reason": "price"}]""" now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") for batch in chunks(cancellations, 25): tracked = actions.execute_tool( tool_name="braze_users_track", tool_input={ "attributes": [ {"external_id": c["external_id"], "churn_risk": "high", "last_plan": c["plan"]} for c in batch ], "events": [ { "external_id": c["external_id"], "name": "subscription_canceled", "time": now, "properties": {"plan": c["plan"], "reason": c["reason"]}, } for c in batch ], }, connection_name=CONNECTION_NAME, identifier=PIPELINE_IDENTIFIER, ) print(tracked.execution_id, tracked.data) for batch in chunks(cancellations, 50): sent = actions.execute_tool( tool_name="braze_canvas_trigger_send", tool_input={ "canvas_id": WINBACK_CANVAS_ID, "recipients": [ { "external_user_id": c["external_id"], "context": {"last_plan": c["plan"], "cancel_reason": c["reason"]}, } for c in batch ], }, connection_name=CONNECTION_NAME, identifier=PIPELINE_IDENTIFIER, ) print(sent.execution_id, sent.data.get("dispatch_id"), sent.data.get("notice"))

Store each dispatch_id with the cancellation records it covered, so a retried job can skip batches that already went out instead of entering the same users into the Canvas twice. If data carries a notice that the Canvas is paused or archived, nothing was sent, and the job should alert rather than report success. When a batch returns 429, wait until the reset time in the rate limit headers before the next one. The Braze MCP server has no equivalent for any of these calls.

Two other tools show where the API path earns its place. braze_users_export_by_ids takes up to 50 external_ids and a fields_to_export list and returns full profiles, including message history, which is what a support agent needs to answer "why didn't this customer get the receipt." braze_subscription_group_status_set_v2 updates several subscription groups for the same users in one request, which is how a preference sync from your own settings page lands in Braze. Neither belongs in a model's default tool set; both fit a pipeline or a narrowly scoped role.

Multi-tool, multi-tenant Braze agents on a virtual MCP server

The braze connector has 73 tools. At roughly 200 tokens each, that is about 14,600 tokens of tool definitions before the agent does any work, and Braze's own MCP server adds about 14,200 for its 71. A model choosing among braze_campaign_analytics_get, braze_send_analytics_get, braze_canvas_analytics_get, and braze_canvas_analytics_summary_get picks the wrong one more often than a model holding only the two it needs. Overreach is the larger risk in Braze: a reporting assistant that also holds braze_messages_send can message a segment on a bad inference, and that cannot be unsent. The fix is not better prompting. It is surface reduction. A Scalekit virtual MCP server declares exactly which tools an agent role can see, and session tokens keep each run bound to one user's connected accounts. Docs: set up a virtual MCP server.

Create the server once per agent role

from scalekit.actions.models.mcp_config import McpConfigConnectionToolMapping vmcp = actions.mcp.create_config( name="braze-campaign-reporter", description="Reports Braze campaign and Canvas performance and posts a weekly digest to Slack", connection_tool_mappings=[ McpConfigConnectionToolMapping( connection_name="braze", tools=[ "braze_campaigns_list", "braze_campaign_analytics_get", "braze_canvases_list", "braze_canvas_analytics_summary_get", "braze_scheduled_broadcasts_list", ], ), McpConfigConnectionToolMapping( connection_name="slack", tools=["slack_send_message"], ), ], ) print(vmcp.config.id, vmcp.config.mcp_server_url)

Mint a session token per user, per run

One server definition serves every user at every customer. Before each run, check that the user's accounts are active and mint a short-lived session token scoped to them. Any MCP client that speaks Streamable HTTP can connect; this example uses langchain-mcp-adapters (pip install langchain-mcp-adapters) and passes the token as a Bearer header.

import asyncio from datetime import timedelta from langchain_mcp_adapters.client import MultiServerMCPClient config_id = vmcp.config.id mcp_server_url = vmcp.config.mcp_server_url user_id = "acme_us_prod_user_5520" accounts = actions.mcp.list_mcp_connected_accounts( config_id=config_id, identifier=user_id, include_auth_link=True, ) not_ready = [ a for a in accounts.connected_accounts if str(a.connected_account_status).upper() != "ACTIVE" ] for a in not_ready: print(f"{a.connection_name} is {a.connected_account_status}: {a.authentication_link}") if not_ready: raise RuntimeError("Connect the accounts above before starting this run") session_token = actions.mcp.create_session_token( mcp_config_id=config_id, identifier=user_id, expiry=timedelta(minutes=30), ).token async def load_tools(): client = MultiServerMCPClient( { "scalekit": { "transport": "streamable_http", "url": mcp_server_url, "headers": {"Authorization": f"Bearer {session_token}"}, } } ) return await client.get_tools() mcp_tools = asyncio.run(load_tools()) print([t.name for t in mcp_tools])

The agent sees six tools instead of 73. The endpoint is static; the identity is per user. Unlike Braze's own MCP server, this endpoint is not subject to the MCP server's restriction on companies that use dashboard IP allowlisting, because it calls the REST API with a key rather than signing a user in (a key created with its own IP allowlist still rejects calls from addresses not on it), and it can include tools Braze MCP doesn't offer, such as braze_canvas_trigger_send, for the one lifecycle role that should hold it.

Observability: every Braze action tied to a user

Every execute_tool call returns an execution_id, and every execution is attributed to a connected account, which maps to one user in one customer workspace. When a CRM lead asks which agent run entered 3,200 users into the win-back Canvas on Tuesday, the answer is a lookup, not an investigation. Store the dispatch_id Braze returns next to the execution_id, and every send ties back to the run and the request that caused it.

Attribution is where the paths differ most. MCP calls run as the signed-in Braze user, and campaign edits appear in Braze's edit history under their name. REST calls run as a key, and Braze records which key, not which person. If one integration key serves a whole customer, every write and every send looks the same from Braze's side, and your execution log is the only record of which of your users asked for it. Shared credentials work for a single user. They do not survive a second user.

Recommended reading: audit trails for agent auth

Which one to build against

If your agent is a marketer's or analyst's assistant in Claude, ChatGPT, or Cursor, summarizing campaign and Canvas performance, comparing workspaces, and drafting templates with a person approving each write, Braze's official MCP server is a good fit, provided the customer doesn't use IP allowlisting and an admin has enabled MCP access. If your agent writes user data, sends or schedules messages, manages subscriptions, reads individual profiles, or runs unattended from your product's events, build against the Braze REST API, where you choose the key's permissions, the tools, and the batching. Either way, you hold a Braze credential per user or per role in every customer workspace, often a key that never expires and can message real customers, and that's what needs production-grade infrastructure.

FAQs

Does Braze have an official MCP server?

Yes. Braze hosts a remote MCP server for US and EU customers that shipped in early access in July 2026 and was listed as generally available in September 2026, with its campaign and segment tools still in beta. It exposes 71 tools across analytics, campaigns, Canvases, catalogs, segments, templates and Content Blocks.

Can the Braze MCP server send messages or read user profiles?

No. Braze states that tools exposing user-level personal data are not available, Canvas tools are read-only, and no tool sends a message to a named user or writes a user profile. Sends, triggered campaigns and Canvases, profile reads and writes, and subscription state all live on the REST API.

How does Braze MCP authentication work?

The MCP server uses OAuth only, including SSO, and every call runs with the signed-in user's dashboard permissions across the workspaces they can reach. A company admin must enable MCP OAuth access and approve the client, each user needs the Use MCP Server permission, and companies that use dashboard IP allowlisting cannot use the server.

How do Braze REST API keys work?

A workspace admin creates a key with a fixed permission set and optional IP allowlist. The key belongs to one workspace, works only against its own instance's REST host, never expires, and survives the deletion of the user who created it. Changing scope means creating a new key, so Braze identifies a workspace integration, not a person.

When should an agent use the Braze API instead of MCP?

Use the API for headless work driven by your product's events: writing attributes and events, entering users into an API-triggered Canvas, sending or scheduling messages, syncing subscription groups, reading individual profiles for support, and serving many customer workspaces with keys scoped per role. Use MCP for analysis and content work with a person reviewing.

How does Scalekit connect an AI agent to Braze?

Scalekit's Braze connector exposes 73 tools over the REST API. Each user connects their Braze key once through a hosted form, Scalekit stores it encrypted and sends it on every call, and the agent never sees it. You give each agent role only the tools its key permits and serve them through a virtual MCP server.

Build your Braze agent with Scalekit

Browse the Scalekit Braze connector and the Braze connector docs with the full tool list. See Scalekit pricing, or talk to us.

No items found.
On this page
Share this article
Scalekit
Find us on ProductHunt

Acquire enterprise customers with
‍zero upfront cost.

Every feature unlocked. No hidden fees.