<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet title="XSL_formatting" type="text/xsl" href="https://developer.salesforce.com/blogs/wp-content/themes/dfctheme/includes/feed_styles.xsl" ?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
xmlns:podcast="https://podcastindex.org/namespace/1.0"
xmlns:rawvoice="https://blubrry.com/developer/rawvoice-rss/"
xmlns:media="http://search.yahoo.com/mrss/"
	xmlns:dscblog="https://developer.salesforce.com/blog/dscblog/"
>


<channel>
	<title>Salesforce Developers Blog</title>
	<atom:link href="https://developer.salesforce.com/blogs/feed" rel="self" type="application/rss+xml" />
	<link>https://developer.salesforce.com/blogs</link>
	<description>Elevating developer skills and connecting with the Salesforce Developers community</description>
	<lastBuildDate>Wed, 15 Jul 2026 19:28:12 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
	<atom:link rel="hub" href="https://pubsubhubbub.appspot.com/" />
	<itunes:author>Salesforce Developers Blog</itunes:author>
	<itunes:explicit>false</itunes:explicit>
	<itunes:image href="https://developer.salesforce.com/blogs/wp-content/plugins/powerpress/itunes_default.jpg" />
	<itunes:owner>
		<itunes:name>Salesforce Developers Blog</itunes:name>
	</itunes:owner>
	<podcast:medium>podcast</podcast:medium>
	<image>
		<title>Salesforce Developers Blog</title>
		<url>https://developer.salesforce.com/blogs/wp-content/plugins/powerpress/rss_default.jpg</url>
		<link>https://developer.salesforce.com/blogs</link>
	</image>
	<podcast:podping usesPodping="true" />
<site xmlns="com-wordpress:feed-additions:1">244780846</site>	<item>
		<title>Connect Slack to Salesforce with Hosted MCP Servers</title>
		<link>https://developer.salesforce.com/blogs/2026/07/connect-slack-to-salesforce-with-hosted-mcp-servers</link>
		<comments>https://developer.salesforce.com/blogs/2026/07/connect-slack-to-salesforce-with-hosted-mcp-servers#respond</comments>
		<pubDate>Wed, 15 Jul 2026 15:00:37 +0000</pubDate>
		<dc:creator><![CDATA[Philippe Ozil]]></dc:creator>
				<category><![CDATA[Agentforce]]></category>
		<category><![CDATA[APIs and Integrations]]></category>
		<category><![CDATA[App Development]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Data 360]]></category>
		<category><![CDATA[Headless 360]]></category>
		<category><![CDATA[MCP]]></category>
		<category><![CDATA[Model context protocol]]></category>
		<category><![CDATA[Salesforce Hosted MCP Servers]]></category>
		<category><![CDATA[Salesforce Platform]]></category>
		<category><![CDATA[Slackbot]]></category>
		<category><![CDATA[tableau]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206704</guid>
		<description><![CDATA[<p>Discover how Headless 360 brings Salesforce Hosted MCP Servers to Slackbot, giving your teams a single, secure conversational interface to access CRM data, execute flows, and query Tableau.</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/07/connect-slack-to-salesforce-with-hosted-mcp-servers">Connect Slack to Salesforce with Hosted MCP Servers</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p><span style="font-weight: 400">Sales reps need to regularly update their pipeline, check their Tableau quota attainment metrics, and prep their account team for customer calls. As a developer, you&#8217;d have to build a custom app to support these workflows. But with Headless 360, your users can now access Salesforce Platform data and processes through a single Slack conversation, eliminating the need to ever open a Salesforce tab.</span></p>
<p><span style="font-weight: 400">This is all made possible with </span><a href="https://developer.salesforce.com/docs/platform/hosted-mcp-servers/overview"><span style="font-weight: 400">Salesforce Hosted MCP Servers</span></a><span style="font-weight: 400"> connected to </span><a href="https://slack.com/help/articles/202026038-How-to-use-Slackbot"><span style="font-weight: 400">Slackbot</span></a><span style="font-weight: 400">, your AI teammate built right into Slack. It’s the engagement layer where your teams, your AI agents, and everything you&#8217;ve built across the Salesforce ecosystem work together in one place.</span></p>
<p><span style="font-weight: 400">In this post, we&#8217;ll explore why Slack is the best conversational interface for Salesforce, how Salesforce Hosted MCP Servers work within it, how to connect them with Slackbot, and what becomes possible when the Salesforce Platform meets the work operating system where your organization runs.</span></p>
<h2><span style="font-weight: 400">Slack: The engagement layer for the agentic enterprise</span></h2>
<p><span style="font-weight: 400">Slack is the work OS: a shared surface where the people, agents, and data that power your organization come together to move work forward. Through natively-built-in Salesforce Platform features and connected MCP servers, it’s where the full Salesforce ecosystem — Agentforce 360, Data 360, Tableau — becomes accessible through natural conversation, right where teams are already collaborating.</span></p>
<p><span style="font-weight: 400">The screenshot below shows a Salesforce records list and Tableau insights inside of Slack’s desktop app, and the related conversation between a user and Slackbot on the Slack mobile app.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206705" >
			    <img fetchpriority="high" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260710102208/Screenshot-of-Slack-desktop-and-mobile-apps-with-Salesforce-data-integrated-e1783704142975.png?w=1000" class="postimages" width="1000" height="562" alt="Screenshot of Slack desktop and mobile apps with Salesforce data integrated." />
			  </span>
			</p>
<p><span style="font-weight: 400">At the center of that experience is Slackbot: a single AI interface to every conversation, file, channel, and app across your organization. What Slackbot surfaces can be shared, discussed, and acted on by the whole team. And because Slackbot can synthesize your data with the conversations plus your connected tools, it can take the context that builds as you work with your team in Slack and bring it back into your records simply as a natural byproduct of work.</span></p>
<p><span style="font-weight: 400">That&#8217;s what makes Slack uniquely powerful. And because your full business context is now available via MCP to the </span><a href="https://slack.dev/slackbot-mcp-client/"><span style="font-weight: 400">Slackbot MCP client</span></a><span style="font-weight: 400">, tools that once worked in parallel can finally work together, all through a single conversation.</span></p>
<h2><span style="font-weight: 400">Salesforce Hosted MCP Servers: A quick refresher</span></h2>
<p><span style="font-weight: 400">Model Context Protocol (MCP) is an </span><a href="https://modelcontextprotocol.io/"><span style="font-weight: 400">open standard</span></a><span style="font-weight: 400"> that lets AI agents interact with external tools and data sources from various vendors. Salesforce Hosted MCP Servers are our generally available implementation of this standard, giving any MCP-compatible client secure, governed access to run queries, modify records, and execute actions directly from their Salesforce org, without requiring a separate login or custom integration code.</span></p>
<p><span style="font-weight: 400">Salesforce has shipped a set of standard hosted MCP servers out of the box: </span><a href="https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/servers-reference.html"><span style="font-weight: 400">Salesforce servers</span></a><span style="font-weight: 400">, </span><a href="https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/tableau-next.html"><span style="font-weight: 400">Tableau</span></a><span style="font-weight: 400">, and </span><a href="https://developer.salesforce.com/docs/platform/hosted-mcp-servers/references/reference/data-cloud-sql.html"><span style="font-weight: 400">Data 360</span></a><span style="font-weight: 400">. Beyond the standard servers, developers can expose their own org&#8217;s capabilities by building </span><a href="https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/custom-servers.html"><span style="font-weight: 400">custom MCP servers</span></a><span style="font-weight: 400"> with tools — Apex actions, Lightning Flows, Apex REST endpoints, APIs from the API Catalog, Prompt Builder templates, and Agentforce agents — without writing new integration code.</span></p>
<p><span style="font-weight: 400">For a deeper dive on Salesforce Hosted MCP Servers themselves, check out the </span><a href="https://developer.salesforce.com/docs/platform/hosted-mcp-servers/overview"><span style="font-weight: 400">Salesforce Hosted MCP Servers documentation</span></a><span style="font-weight: 400">.</span></p>
<h2><span style="font-weight: 400">Configuring Slack to work with Salesforce Hosted MCP Servers</span></h2>
<p><span style="font-weight: 400">Setting up Slackbot to work with Salesforce Hosted MCP Servers is simple; no URLs to copy, no OAuth configurations to wire up manually, no custom code required. The entire setup lives in the Slack Admin UI and takes just a few steps.</span></p>
<h3><span style="font-weight: 400">Prerequisites</span></h3>
<p><span style="font-weight: 400">Before getting started, you&#8217;ll need:</span></p>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">A paid Slack plan (Business+, Enterprise Select, Enterprise Grid, or Enterprise+) with access to Slackbot and Salesforce</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">At least one Salesforce org already connected to Slack</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Workspace Owner/Admin or Org Owner/Admin access</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Salesforce Administrator access to the connected org</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">One or more a</span><a href="https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/activate-mcp-servers.html"><span style="font-weight: 400">ctive Salesforce Hosted MCP servers</span></a></li>
</ul>
<p><span style="font-weight: 400">If you haven&#8217;t connected Salesforce to Slack yet, follow the steps in the </span><a href="https://slack.com/help/articles/30754346665747-Connect-Salesforce-and-Slack"><span style="font-weight: 400">Connect Salesforce and Slack</span></a><span style="font-weight: 400"> help article first. Once that connection is in place, user authentication is handled automatically. Slackbot uses your existing Slack-Salesforce account mapping, so members don&#8217;t need a separate login.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206706" >
			    <img decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260710102324/Screenshot-of-a-Slack-organization-configuration-showing-a-connected-Salesforce-org-e1783704216319.png?w=1000" class="postimages" width="1000" height="630" alt="Screenshot of a Slack organization configuration showing a connected Salesforce org" />
			  </span>
			</p>
<p><span style="font-weight: 400">Note: Don’t have a Slack workspace yet? Creating one is simple: </span><a href="https://help.salesforce.com/s/articleView?id=slack.slack_salesforce_setup.htm&amp;type=5"><span style="font-weight: 400">follow these steps</span></a><span style="font-weight: 400"> to get started.</span></p>
<h3><span style="font-weight: 400">Step 1: Open MCP server settings</span></h3>
<p><span style="font-weight: 400">The path to MCP server configuration depends on your plan:</span></p>
<p><b>For Business+ and Enterprise Select:</b></p>
<p><span style="font-weight: 400">Admin → Workspace settings → Salesforce → Salesforce MCP Servers</span></p>
<p><b>For Enterprise Grid and Enterprise+:</b></p>
<p><span style="font-weight: 400">Organization name → Tools &amp; settings → Organization settings → Salesforce → MCP Servers</span></p>
<h3><span style="font-weight: 400">Step 2: Add a Salesforce Hosted MCP Server</span></h3>
<ol>
<li style="font-weight: 400"><span style="font-weight: 400">Click </span><b>Add MCP Server</b></li>
<li style="font-weight: 400"><span style="font-weight: 400">Choose the server you want to add from the list of active Salesforce Hosted MCP Servers (e.g., </span><i><span style="font-weight: 400">SObject All</span></i><span style="font-weight: 400">, </span><i><span style="font-weight: 400">Data 360</span></i><span style="font-weight: 400">, </span><i><span style="font-weight: 400">custom servers</span></i><span style="font-weight: 400"><span style="font-weight: 400">)<br />
</span></span>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206708" >
			    <img decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260710102452/Screenshot-showing-a-list-of-available-Salesforce-Hosted-MCP-Servers-that-can-be-added-in-Slack-e1783704310584.png?w=1000" class="postimages" width="1000" height="637" alt="Screenshot showing a list of available Salesforce Hosted MCP Servers that can be added in Slack" />
			  </span>
			</li>
<li style="font-weight: 400"><span style="font-weight: 400">Click </span><b>Add</b><span style="font-weight: 400">, then review the tools the server exposes</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Click </span><b>Next</b></li>
</ol>
<p><span style="font-weight: 400">If you&#8217;re on Enterprise Grid or Enterprise+, you&#8217;ll also select which workspaces the server will be available in before proceeding.</span></p>
<h3><span style="font-weight: 400">Step 3: Configure access</span></h3>
<ol>
<li style="font-weight: 400"><span style="font-weight: 400">Choose who in your organization can use this MCP server via Slackbot:</span>
<ul>
<li style="font-weight: 400"><b>Everyone</b><span style="font-weight: 400">: All members with access to Slackbot</span></li>
<li style="font-weight: 400"><b>Specific people and group</b><span style="font-weight: 400">: Fine-grained control by team or individual</span></li>
<li style="font-weight: 400"><b>No one</b><span style="font-weight: 400"><span style="font-weight: 400">: Install now, enable access later<br />
</span></span>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206709" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260710102555/Screenshot-of-a-dialog-showing-how-to-control-MCP-server-member-access-in-Slack.png?w=613" class="postimages" width="613" height="293" alt="Screenshot of a dialog showing how to control MCP server member access in Slack" />
			  </span>
			</li>
</ul>
</li>
<li style="font-weight: 400"><span style="font-weight: 400">Click </span><b>Connect</b><span style="font-weight: 400"> to finish.</span></li>
</ol>
<p><span style="font-weight: 400">The MCP server is now active and Slackbot can use it on behalf of anyone with access.</span></p>
<h2><span style="font-weight: 400">How Salesforce permissions apply to Slackbot MCP calls</span></h2>
<p><span style="font-weight: 400">Salesforce MCP servers in Slackbot are permission-aware by design. Every action Slackbot takes respects the standard </span><a href="https://developer.salesforce.com/blogs/developer-relations/2017/04/salesforce-data-security-model-explained-visually"><span style="font-weight: 400">Salesforce security model</span></a><span style="font-weight: 400">: field-level security, object permissions, and sharing rules are enforced per user, per request. Users only see and act on what they&#8217;re allowed to in Salesforce. Slack admins can adjust access, update permissions, or remove a server entirely from the Slack organization admin UI at any time.</span></p>
<p>Security is also handled at the Slack user level with prompts to prevent accidental use of MCP tools. The screenshot below shows Slackbot prompting the user to confirm if it can use the <code>CreateAccountSyncMeetingTask</code> custom MCP tool.</p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206710" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260710102633/Screenshot-of-Slackbot-prompting-the-user-to-confirm-use-of-an-MCP-tool.png?w=817" class="postimages" width="817" height="436" alt="Screenshot of Slackbot prompting the user to confirm use of an MCP tool" />
			  </span>
			</p>
<h2><span style="font-weight: 400">Slackbot and Salesforce Hosted MCP Servers in action</span></h2>
<p><span style="font-weight: 400">Once your MCP servers are configured, every member of your team authenticated across Slack and Salesforce gains natural language access to your Salesforce org based on their permissions — directly in the place where they&#8217;re already working. Here&#8217;s what that can look like in practice. We’ll use Northern Trail Outfitters (a fictitious outdoors gear vendor) for the following examples.</span></p>
<h3><span style="font-weight: 400">Triggering a custom business process</span></h3>
<p><span style="font-weight: 400">A Northern Trail Outfitters sales rep has a call in an hour with one of their customers, Alpine Trekkers. Instead of opening Salesforce, navigating to the Account page, cross-referencing the opportunities and cases to prepare for the call, they just ask Slackbot:</span></p>
<p><i><span style="font-weight: 400">&#8220;Run a health check on the Alpine Trekkers account&#8221;</span></i></p>
<p><span style="font-weight: 400">Slackbot uses a tool from the standard </span><a href="https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/sobject-all.html"><span style="font-weight: 400">SObject All MCP server</span></a><span style="font-weight: 400"> to identify the account based on its name. It then calls the custom health check flow tool. The flow retrieves additional data from related cases, opportunities and activities to calculate a health score thanks to precise business rules.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206711" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260710102712/Screenshot-showing-Slackbot-calling-a-custom-MCP-tool-that-runs-an-account-health-check.png?w=712" class="postimages" width="712" height="1000" alt="Screenshot showing Slackbot calling a custom MCP tool that runs an account health check." />
			  </span>
			</p>
<p><span style="font-weight: 400">The health check indicates that the account is at risk because of an unresolved critical support case.</span></p>
<h3><span style="font-weight: 400">Prepping for a sales call</span></h3>
<p><span style="font-weight: 400">Once the sales rep reviews the Alpine Trekkers’ account health, they ask Slackbot to help plan for the customer meeting. Slackbot uses another custom tool to identify the meeting stakeholders (thanks to the Salesforce contacts related to the account) and logs the right information to prepare for the meeting. In the screenshot below, Slackbot calls a custom MCP tool that creates a task to set up an account sync meeting.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206712" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260710102758/Screenshot-of-Slackbot-calling-a-custom-MCP-tool-that-creates-a-task.png?w=948" class="postimages" width="948" height="181" alt="Screenshot of Slackbot calling a custom MCP tool that creates a task" />
			  </span>
			</p>
<h3><span style="font-weight: 400">Pipeline analysis with live Tableau data</span></h3>
<p><span style="font-weight: 400">Thanks to Slackbot’s help with the preparation, the customer meeting goes well and their concerns are addressed. The Alpine Trekkers account is no longer at risk.</span></p>
<p><span style="font-weight: 400">The Northern Trail Outfitters sales manager wants a current read on Q2 pipeline health. Rather than pulling up a Tableau dashboard separately, they ask directly Slackbot:</span></p>
<p><i><span style="font-weight: 400">&#8220;What does Tableau show for Q2 pipeline conversion rates by region?&#8221;</span></i></p>
<p><span style="font-weight: 400">With the </span><a href="https://tableau.github.io/tableau-mcp/docs/hosted-tableau-mcp"><span style="font-weight: 400">Tableau MCP server</span></a><span style="font-weight: 400"> connected, Slackbot queries the semantic layer — respecting row-level security — and returns a trusted, governed answer with visualizations, grounded in actual business metrics. The sales rep can share those insights with the team and hit the ground running, and the conversation about what to do happens right there, next to the data.</span></p>
<h2><b>Conclusion</b></h2>
<p><span style="font-weight: 400">This concludes our tour of how to connect Slackbot to Salesforce Hosted MCP servers. You saw why Slack is the engagement layer for the agentic enterprise and how Salesforce Hosted MCP servers let you run your business with agents thanks to Headless 360. We took a look at how to configure Slackbot to work with Salesforce Hosted MCP servers and saw practical examples of its benefits.</span></p>
<p><span style="font-weight: 400">It’s now your turn to connect Slackbot to your Salesforce org. Start with the </span><a href="https://slack.com/help/articles/52462858006675-Connect-Slackbot-to-Salesforce-with-MCP"><span style="font-weight: 400">Connect Slackbot to Salesforce with MCP</span></a><span style="font-weight: 400"> help article for the full setup guide.</span></p>
<h2><b>Resources</b></h2>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">Documentation: </span><span style="font-weight: 400">Connect Salesforce and Slack</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Documentation: </span><a href="https://slack.com/help/articles/52462858006675-Connect-Slackbot-to-Salesforce-with-MCP"><span style="font-weight: 400">Connect Slackbot to Salesforce with MCP</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">Documentation: </span><a href="https://developer.salesforce.com/docs/platform/hosted-mcp-servers/overview"><span style="font-weight: 400">Salesforce Hosted MCP Servers</span></a></li>
</ul>
<h2><b>About the authors</b></h2>
<p><b>Ashley Mao</b><span style="font-weight: 400"> is a Senior Product Marketing Manager at Salesforce, where she leads product launches across Salesforce and Slack. She enjoys exploring what it means to work alongside agents as teammates, and what’s possible when data and dialogue come together.</span></p>
<p><b>Philippe Ozil</b><span style="font-weight: 400"> is a Principal Developer Advocate at Salesforce, where he focuses on the Salesforce Platform. He writes technical content and speaks frequently at conferences. He is a full-stack developer and enjoys working with APIs, DevOps, robotics, and VR projects. Follow him on </span><a href="https://x.com/PhilippeOzil"><span style="font-weight: 400">X</span></a><span style="font-weight: 400">, </span><a href="https://www.linkedin.com/in/philippeozil/"><span style="font-weight: 400">LinkedIn</span></a><span style="font-weight: 400">, and </span><a href="https://bsky.app/profile/pozil.bsky.social"><span style="font-weight: 400">Bluesky</span></a><span style="font-weight: 400">, and check out his </span><a href="https://github.com/pozil"><span style="font-weight: 400">GitHub projects</span></a><span style="font-weight: 400">.</span></p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/07/connect-slack-to-salesforce-with-hosted-mcp-servers">Connect Slack to Salesforce with Hosted MCP Servers</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://developer.salesforce.com/blogs/2026/07/connect-slack-to-salesforce-with-hosted-mcp-servers/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206704</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260710102841/blog-SF-MCP-developer-hero-1000x563-1.png?w=1000" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260710102841/blog-SF-MCP-developer-hero-1000x563-1.png?w=1000" medium="image" />
	</item>
		<item>
		<title>Announcing the Headless 360 MCP Server Beta</title>
		<link>https://developer.salesforce.com/blogs/2026/07/announcing-the-headless-360-mcp-server-beta</link>
		<comments>https://developer.salesforce.com/blogs/2026/07/announcing-the-headless-360-mcp-server-beta#respond</comments>
		<pubDate>Tue, 14 Jul 2026 15:00:36 +0000</pubDate>
		<dc:creator><![CDATA[Tyson Read]]></dc:creator>
				<category><![CDATA[APIs and Integrations]]></category>
		<category><![CDATA[Developer Tooling]]></category>
		<category><![CDATA[Headless 360]]></category>
		<category><![CDATA[New Developments]]></category>
		<category><![CDATA[Apex triggers]]></category>
		<category><![CDATA[beta]]></category>
		<category><![CDATA[Change Data Capture]]></category>
		<category><![CDATA[MCP]]></category>
		<category><![CDATA[Model context protocol]]></category>
		<category><![CDATA[Salesforce Hosted MCP Servers]]></category>
		<category><![CDATA[Setup operations]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206721</guid>
		<description><![CDATA[<p>The Headless 360 MCP Server (Beta) is a new surface that empowers headless clients to quickly discover and execute complex Salesforce setup and integration operations.</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/07/announcing-the-headless-360-mcp-server-beta">Announcing the Headless 360 MCP Server Beta</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p><span style="font-weight: 400">Agents are helping us move faster and expand what&#8217;s possible in our work. This kind of empowerment is what Salesforce is built for, and it&#8217;s why</span><a href="https://www.salesforce.com/news/stories/salesforce-headless-360-announcement/"> <span style="font-weight: 400">Headless 360</span></a><span style="font-weight: 400"> is bringing the full breadth of the platform’s capabilities to those agents. </span></p>
<p><span style="font-weight: 400">Today, we&#8217;re taking the next big step on that journey. The </span><a href="https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/headless-360-mcp.html"><span style="font-weight: 400">Salesforce Headless 360 MCP Server</span></a><span style="font-weight: 400"> is now available in Beta starting in early July. It builds on the</span><a href="https://developer.salesforce.com/blogs/2026/04/salesforce-hosted-mcp-servers-are-now-generally-available"> <span style="font-weight: 400">hosted MCP servers</span></a><span style="font-weight: 400"> that we made generally available in April, and it&#8217;s one surface that brings Salesforce to your MCP clients.</span></p>
<p><span style="font-weight: 400">In this blog post, we’ll walk you through what’s new and how to get started with the Headless 360 MCP Server (Beta).</span></p>
<h2><span style="font-weight: 400">Use only four tools, not four thousand</span></h2>
<p><span style="font-weight: 400">When we were designing the Headless 360 Server, we needed to come up with a way to bring the thousands of features that Salesforce has built to MCP clients. If we exposed each feature as a distinct MCP tool, a model would have to reason over thousands of tool descriptions and pick the right one. The risk there is that the model would burn a huge amount of context, tokens, and time before it could take action. It&#8217;s also a scale problem that gets harder as we add more features and more APIs in the future. </span></p>
<p><span style="font-weight: 400">So, the Headless 360 Server takes a different shape. It presents an agent with four tools, not thousands. Behind these tools we&#8217;ve put a continuously growing library of skills. The agent&#8217;s surface stays small and stable, and the action surface scales independently.</span></p>
<h2><span style="font-weight: 400">Explore the new tools: Discover, Describe, Dispatch, and Dispatch Read Only</span></h2>
<p><span style="font-weight: 400">The four tools in our Headless 360 Server map to how an agent moves through a request.</span></p>
<ul>
<li style="font-weight: 400"><b>Discover</b><span style="font-weight: 400">: Takes the agent&#8217;s interpretation of what you asked for and runs a semantic search across a vector index of every API and skill we&#8217;ve generated. It returns a ranked set of candidates, so agents spend less time and call fewer MCP tools trying to find what they need.</span></li>
<li style="font-weight: 400"><b>Describe</b><span style="font-weight: 400">: Pulls back the technical contract for a skill with APIs, parameters, dependencies, and the ordered steps. This tool helps an agent verify that the Discover tool is serving helpful results and details the steps an agent needs to take.</span></li>
<li style="font-weight: 400"><b>Dispatch</b><span style="font-weight: 400">: Invokes the chosen skill. It routes to the right endpoint and enforces the user access guards before anything runs.</span></li>
<li style="font-weight: 400"><b>Dispatch Read Only:</b><span style="font-weight: 400"> Runs read-only dispatch actions</span></li>
</ul>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206725" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260710113449/An-image-of-the-Headless-360-MCP-Server-and-its-tools-in-Salesforce-Setup-e1783708503746.png?w=1000" class="postimages" width="1000" height="663" alt="An image of the Headless 360 MCP Server and its tools in Salesforce Setup" />
			  </span>
			</p>
<p><span style="font-weight: 400">You could ask your agent to &#8220;Plan an integration that sends events to AWS when Account records change.&#8221; Your agent can propose and build an integration, saving you the time you&#8217;d otherwise spend clicking through three Setup screens to configure Change Data Capture, a named credential, and the event relay.</span></p>
<p><span style="font-weight: 400">In this example, an MCP client will start by using the </span><b>Discover</b><span style="font-weight: 400"> tool to find the relevant skills for Change Data Capture, Named Credentials, and Event Relay. </span></p>
<p><span style="font-weight: 400">Once it’s found them, it’ll use the </span><b>Describe</b><span style="font-weight: 400"> tool to inspect the API calls it needs to make and the order in which they need to happen. In order to create an event relay, the agent needs to start by creating a named credential. </span></p>
<p><span style="font-weight: 400">Finally, once the agent knows what API calls need to be made, it executes those calls with the </span><b>Dispatch</b><span style="font-weight: 400"> tool. Of course, this same pattern extends beyond the work developers and admins do to the work that business users take on across Salesforce&#8217;s products.</span></p>
<h2><span style="font-weight: 400">Guardrails for MCP clients</span></h2>
<p>Agents are powerful, and it&#8217;s worth talking about the guardrails that are in place today to make sure your MCP clients keep out of trouble. This matters for business users on the Headless 360 MCP Server, and it matters more for admins and developers. Every Salesforce Hosted MCP transaction runs as the authenticated user, scoped through an external client app with the <code>mcp_api</code> scope. CRUD, FLS, sharing rules, profile permissions, and permission sets all apply. If you can&#8217;t do it in Salesforce, your agent can&#8217;t do it through the MCP server. The audit trail attributes actions to you.</p>
<p><span style="font-weight: 400">On top of the gating Salesforce that enforces, most MCP clients also allow you to set tool-level restrictions. If you want to verify the actions that your agent will take on your behalf, you can set your tool-level permissions to have the agent ask for your approval each time it runs a tool. This matters most for admins and developers, who carry wide-ranging permissions in their orgs and should be careful about the changes they and their agents take. As always, follow the best practice of making configuration changes in sandboxes and developer orgs before you take them to production.</span></p>
<h2><span style="font-weight: 400">Up-skilling agents with thousands of new skills</span></h2>
<p><span style="font-weight: 400">We’re launching this Beta with roughly 100 skills that will sit behind our MCP server. We&#8217;re also creating thousands of new skills that sit behind the Headless 360 MCP Server. </span></p>
<p><span style="font-weight: 400">At launch, the majority of these skills will be focused on Setup operations for admins, extending the kind of capabilities in Agentforce for Setup to headless MCP clients. During the Beta, the Headless 360 MCP Server will grow to encompass cloud-specific skills that represent the breadth of what business users can do with Salesforce, too. </span></p>
<p><span style="font-weight: 400">A few of the high-traffic tasks that your agent can handle in July include:</span></p>
<ul>
<li style="font-weight: 400"><b>Managing users:</b><span style="font-weight: 400"> Create, deactivate, freeze and unfreeze, reset or set passwords, assign permission sets and permission set licenses, this includes the full surface that a builder reaches for on the User detail page</span></li>
<li style="font-weight: 400"><b>Managing Apex triggers:</b><span style="font-weight: 400"> Read, write, and deploy Apex triggers</span></li>
<li style="font-weight: 400"><b>Building event-driven integrations:</b><span style="font-weight: 400"> Define platform events, manage Change Data Capture, and manage event relays</span></li>
<li style="font-weight: 400"><b>Creating named credentials:</b><span style="font-weight: 400"> Designate auth mechanisms, endpoints, and certificate handling</span></li>
</ul>
<p><span style="font-weight: 400">Unsurprisingly, there’s a lot of AI being used to generate the skills that back our Headless 360 MCP Server. As part of this project, we created an internal tool called the Headless 360 Factory that scans Salesforce Setup, identifies features that are missing API access, and then generates APIs and skills that agents can use via our MCP server. Feature teams across Salesforce are reviewing these skills now and bringing their own to make sure that all of Salesforce is represented in one MCP server.</span></p>
<h2><span style="font-weight: 400">Join the Beta</span></h2>
<p><span style="font-weight: 400">To join the Beta, go to Salesforce Setup, find the Salesforce Hosted MCP Servers section, look for Headless 360 in the list, and click Activate. We also want your feedback on this server.  Post questions, issues, and comments in our </span><a href="https://github.com/forcedotcom/mcp-hosted"><span style="font-weight: 400">github repo</span></a><span style="font-weight: 400"> for Salesforce Hosted MCP Servers. </span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206726" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260710113521/Screenshot-showing-opt-in-to-the-Headless-360-Server-Beta-e1783708535120.png?w=1000" class="postimages" width="1000" height="718" alt="Screenshot showing opt-in to the Headless 360 Server Beta" />
			  </span>
			</p>
<h2><span style="font-weight: 400">Resources</span></h2>
<ul>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/hosted-mcp-servers-overview.html"><span style="font-weight: 400">Salesforce Hosted MCP Servers Developer Guide</span></a></li>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/blogs/2026/04/salesforce-hosted-mcp-servers-are-now-generally-available"><span style="font-weight: 400">Salesforce Hosted MCP Servers GA Announcement</span></a></li>
<li style="font-weight: 400"><a href="https://github.com/forcedotcom/mcp-hosted"><span style="font-weight: 400">Salesforce Hosted MCP Servers Github Repo</span></a></li>
</ul>
<h2><span style="font-weight: 400">About the author</span></h2>
<p><b>Tyson Read</b><span style="font-weight: 400"> is a Senior Director of Product Management at Salesforce. He works on MCP and event-driven integrations.</span></p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/07/announcing-the-headless-360-mcp-server-beta">Announcing the Headless 360 MCP Server Beta</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://developer.salesforce.com/blogs/2026/07/announcing-the-headless-360-mcp-server-beta/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206721</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260710113047/Generic-C-5-e1783708262122.png?w=1000" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260710113047/Generic-C-5-e1783708262122.png?w=1000" medium="image" />
	</item>
		<item>
		<title>Introducing a New Connect REST API Experience</title>
		<link>https://developer.salesforce.com/blogs/2026/07/introducing-a-new-connect-rest-api-experience</link>
		<comments>https://developer.salesforce.com/blogs/2026/07/introducing-a-new-connect-rest-api-experience#respond</comments>
		<pubDate>Thu, 09 Jul 2026 15:00:01 +0000</pubDate>
		<dc:creator><![CDATA[Ben Sklar]]></dc:creator>
				<category><![CDATA[Agentforce]]></category>
		<category><![CDATA[Announcements]]></category>
		<category><![CDATA[APIs and Integrations]]></category>
		<category><![CDATA[Developer Tooling]]></category>
		<category><![CDATA[New Developments]]></category>
		<category><![CDATA[API Reference]]></category>
		<category><![CDATA[Connect REST API]]></category>
		<category><![CDATA[Developer Guide]]></category>
		<category><![CDATA[OpenAPI Specification]]></category>
		<category><![CDATA[Reference documentation]]></category>
		<category><![CDATA[REST API]]></category>
		<category><![CDATA[salesforce]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206688</guid>
		<description><![CDATA[<p>Introducing the new Connect REST API reference experience to help developers find details faster by bringing endpoints, request and response examples, and in-line versioning into one place.</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/07/introducing-a-new-connect-rest-api-experience">Introducing a New Connect REST API Experience</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p><span style="font-weight: 400">The Connect REST API provides programmatic access to Salesforce features like B2B Commerce, CMS managed content, Experience Cloud sites, files, notifications, topics, and more. If you&#8217;ve built with this API, you’re likely familiar with the legacy version of its reference docs: one page for the resource, another for the request body, and another for the response body. That’s a lot of clicking and scrolling to answer a simple question like, &#8220;What do I send, and what comes back?&#8221;</span></p>
<p><span style="font-weight: 400">Starting July 2026, we’re introducing a single, unified reference page for the core </span><a href="https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-core"><span style="font-weight: 400">Connect REST API</span></a><span style="font-weight: 400"> and other related API families, including </span><a href="https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-agentforce"><span style="font-weight: 400">Agentforce</span></a><span style="font-weight: 400">, </span><a href="https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-chatter"><span style="font-weight: 400">Chatter</span></a><span style="font-weight: 400">, </span><a href="https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-chatter-feeds"><span style="font-weight: 400">Chatter Feeds</span></a><span style="font-weight: 400">, </span><a href="https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-cms"><span style="font-weight: 400">CMS</span></a><span style="font-weight: 400">, </span><a href="https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-commerce"><span style="font-weight: 400">Commerce</span></a><span style="font-weight: 400">, </span><a href="https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-experience-cloud"><span style="font-weight: 400">Experience Cloud</span></a><span style="font-weight: 400">, </span><a href="https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-files"><span style="font-weight: 400">Files and Folders</span></a><span style="font-weight: 400">, and </span><a href="https://developer.salesforce.com/docs/platform/connect-rest-api/references/connect-rest-api-personalization"><span style="font-weight: 400">Personalization</span></a><span style="font-weight: 400">. </span></p>
<p><span style="font-weight: 400">In this post, we&#8217;ll walk through what&#8217;s new, the benefits you&#8217;ll notice right away, and a few things that work differently than before.</span></p>
<h2><span style="font-weight: 400">The old way: Disconnected pages</span></h2>
<p><span style="font-weight: 400">In the previous documentation, the left navigation was a long tree of links, and you chose your API version from a dropdown at the top. Understanding one endpoint required you to assemble the picture from several disconnected pages. And for many people, that meant lots of open browser tabs.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206689" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260708155101/Screenshot-of-the-previous-Connect-REST-API-reference-landing-page--e1783551074220.png?w=1000" class="postimages" width="1000" height="625" alt="Screenshot of the previous Connect REST API reference landing page" />
			  </span>
			</p>
<p><span style="font-weight: 400">Request and response bodies were documented on standalone pages, separate from the resources that actually used them.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206701" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260709080542/Screenshot-of-the-previous-reference-showing-an-individual-topic-page-e1783609561288.png?w=1000" class="postimages" width="1000" height="625" alt="Screenshot of the previous reference showing an individual topic page." />
			  </span>
			</p>
<h2><span style="font-weight: 400">The new Connect REST API reference: One page, three columns</span></h2>
<p><span style="font-weight: 400">The </span><a href="https://developer.salesforce.com/docs/platform/connect-rest-api/references/"><span style="font-weight: 400">new API reference</span></a><span style="font-weight: 400"> brings everything together on a single page with a three-column layout. The left column lists only resources. The center column shows the selected resource. The right column shows request and response examples. Many elements are clickable, so you can expand and collapse details. You can drill down exactly as far as you need into complex objects without ever losing your spot.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206691" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260708155335/Screenshot-of-the-new-reference-with-three-columns-e1783551232746.png?w=1000" class="postimages" width="1000" height="625" alt="Screenshot of the new reference with three columns" />
			  </span>
			</p>
<h2><span style="font-weight: 400">Key improvements</span></h2>
<p><span style="font-weight: 400">We rebuilt the reference around the way developers actually work. Here&#8217;s what stands out:</span></p>
<ul>
<li style="font-weight: 400"><b>Everything in context</b><span style="font-weight: 400">: The request you send and the response you get back now sit right beside the resource that uses them.</span></li>
<li style="font-weight: 400"><b>Extensive examples</b><span style="font-weight: 400">: The right-hand column shows request and response examples for the operation you&#8217;re viewing.</span></li>
<li style="font-weight: 400"><b>Searchability</b><span style="font-weight: 400">: You can use the search box in the left nav to filter down the number of endpoints. You can also use your browser’s </span><b>Find</b><span style="font-weight: 400"> command to locate any piece of text in the whole API reference and highlight every match at once.</span></li>
</ul>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206692" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260708155423/Screenshot-showing-search-results-highlighting-the-word-22reminder22--e1783551283240.png?w=1000" class="postimages" width="1000" height="625" alt="Screenshot showing search results highlighting the word reminder" />
			  </span>
			</p>
<h2><span style="font-weight: 400">Built on OpenAPI</span></h2>
<p><span style="font-weight: 400">The reference now follows the </span><a href="https://www.openapis.org/"><span style="font-weight: 400">OpenAPI Specification</span></a><span style="font-weight: 400"> (OAS), the industry standard for describing REST APIs. Beyond cleaner, more consistent structure, the move to OAS lets us improve the accuracy of the reference itself. And because it&#8217;s a standard spec, you can download it directly and use it with AI agents or code generation workflows. Each API family&#8217;s reference includes a Download button for grabbing its OpenAPI specification</span><i><span style="font-weight: 400">.</span></i></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206693" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260708155506/Screenshot-of-the-OpenAPI-Specification-download-button.-.png?w=640" class="postimages" width="640" height="115" alt="Screenshot of the OpenAPI Specification download button." />
			  </span>
			</p>
<h2><span style="font-weight: 400">Versions throughout</span></h2>
<p><span style="font-weight: 400">We&#8217;ve also retired the per-version snapshots and the version dropdown. In their place is a single, evergreen reference that&#8217;s always current. Version information now lives in-line, throughout the page. For each resource and object, you&#8217;ll see an </span><i><span style="font-weight: 400">Available in</span></i><span style="font-weight: 400"> note, so that you no longer have to pick a version up front just to find out when something shipped.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206694" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260708155713/Screenshot-showing-version-details-appearing-in-line.png?w=714" class="postimages" width="714" height="308" alt="Screenshot showing version details appearing in-line" />
			  </span>
			</p>
<h2><span style="font-weight: 400">What works differently</span></h2>
<p><span style="font-weight: 400">A redesign this big changes a few habits. Here&#8217;s what to know about the new experience.</span></p>
<p><b>To copy a full endpoint path, click it.</b><span style="font-weight: 400"> Click any operation&#8217;s path and a popup appears with the complete request URL, ready to copy and paste.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206695" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260708155741/Screenshot-showing-how-clicking-an-operations-path-opens-a-popup-with-the-full-request-URL-e1783551475784.png?w=1000" class="postimages" width="1000" height="214" alt="Screenshot showing how clicking an operation&apos;s path opens a popup with the full request URL" />
			  </span>
			</p>
<p><b>Field types can include a pattern.</b> Some fields show a regular-expression pattern that describes the values they accept. For example, you might see <code>^(00T|00U)\w*</code>. Reading it left to right: <code>^</code> means the value starts here, <code>(00T|00U)</code> means it begins with either <code>00T</code> or <code>00U</code>, and <code>\w*</code> means any letters, numbers, or underscores follow. In plain terms, that&#8217;s a Salesforce ID that must start with the key prefix <code>00T</code> or <code>00U</code>.</p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206696" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260708155856/Screenshot-of-a-required-path-parameter-showing-its-type-alongside-the-pattern.png?w=760" class="postimages" width="760" height="110" alt="Screenshot of a required path parameter showing its type alongside the pattern" />
			  </span>
			</p>
<p><b>You can&#8217;t deep-link to a request or response body anymore.</b><span style="font-weight: 400"> Because request and response bodies are no longer separate pages, you can&#8217;t link directly to one. Link to the operation instead, and the body appears right there alongside it.</span></p>
<p><b>Navigation</b><span style="font-weight: 400">. To choose a new API family, click </span><b>All Reference</b><span style="font-weight: 400"> or the </span><b>Reference</b><span style="font-weight: 400"> tab.</span></p>
<h2><span style="font-weight: 400">Conclusion</span></h2>
<p><span style="font-weight: 400">The new </span><a href="https://developer.salesforce.com/docs/platform/connect-rest-api"><span style="font-weight: 400">Connect REST API Developer Guide</span></a><span style="font-weight: 400"> lets you discover the details faster with less context switching. Try it out and let us know what would make it even more helpful by clicking the </span><b>Share your feedback</b><span style="font-weight: 400"> button at the bottom of the page.</span></p>
<h2><span style="font-weight: 400">Resources</span></h2>
<ul>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/docs/platform/connect-rest-api"><span style="font-weight: 400">Connect REST API Developer Guide</span></a></li>
<li style="font-weight: 400"><a href="https://www.openapis.org/"><span style="font-weight: 400">The OpenAPI Specification</span></a></li>
</ul>
<h2><span style="font-weight: 400">About the authors</span></h2>
<p><b>Richard Sexton</b><span style="font-weight: 400"> is a Technical Writer at Salesforce specializing in developer docs. Follow him on </span><a href="https://linkedin.com/in/r-sexton"><span style="font-weight: 400">LinkedIn</span></a><span style="font-weight: 400">.</span></p>
<p><b>Ben Sklar</b><span style="font-weight: 400"> is a Director of Product Management at Salesforce responsible for UI API, the Salesforce GraphQL API, the Lightning Data Service, and AI Developer Kit. Ben is a major fan of GraphQL, but when not using GraphQL, you can find him playing ultimate frisbee or skiing during the winter. Follow him on </span><a href="https://www.linkedin.com/in/benjamin-sklar/"><span style="font-weight: 400">LinkedIn</span></a><span style="font-weight: 400">.</span></p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/07/introducing-a-new-connect-rest-api-experience">Introducing a New Connect REST API Experience</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://developer.salesforce.com/blogs/2026/07/introducing-a-new-connect-rest-api-experience/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206688</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260708160246/Generic-D-4-e1783551785970.png?w=1000" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260708160246/Generic-D-4-e1783551785970.png?w=1000" medium="image" />
	</item>
		<item>
		<title>Identify and Fix Performance Regressions Using Deployment Insights in Scale Center</title>
		<link>https://developer.salesforce.com/blogs/2026/07/identify-and-fix-performance-regressions-using-deployment-insights-in-scale-center</link>
		<comments>https://developer.salesforce.com/blogs/2026/07/identify-and-fix-performance-regressions-using-deployment-insights-in-scale-center#respond</comments>
		<pubDate>Tue, 07 Jul 2026 15:30:20 +0000</pubDate>
		<dc:creator><![CDATA[Anand Vardhan]]></dc:creator>
				<category><![CDATA[Apex]]></category>
		<category><![CDATA[APIs and Integrations]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Developer Tooling]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Deployment Insights]]></category>
		<category><![CDATA[Event monitoring]]></category>
		<category><![CDATA[metadata migration]]></category>
		<category><![CDATA[performance regressions]]></category>
		<category><![CDATA[Scale Center]]></category>
		<category><![CDATA[SLA breaches]]></category>
		<category><![CDATA[telemetry engine]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206673</guid>
		<description><![CDATA[<p>The new Deployment Insights feature in Scale Center automatically compares deployment events with platform telemetry to catch performance regressions before they impact your SLAs.</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/07/identify-and-fix-performance-regressions-using-deployment-insights-in-scale-center">Identify and Fix Performance Regressions Using Deployment Insights in Scale Center</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p><span style="font-weight: 400">Imagine this scenario: you deploy a clean metadata migration on a Thursday night. All test suites pass. But by Monday afternoon, API execution times have doubled, database CPU utilization is pinning, and integration partners are flagging Service Level Agreement (SLA) breaches. The deployment clearly introduced a regression, but proving exactly what caused it typically triggers hours of manual correlation, digging through fragmented Event Monitoring logs, filing support cases, and cross-referencing deployment timestamps against ambient traffic spikes.</span></p>
<p><span style="font-weight: 400">The good news is that there’s now a better way to troubleshoot such scenarios with </span><a href="https://help.salesforce.com/s/articleView?id=xcloud.deployment_insights_overview.htm&amp;type=5"><span style="font-weight: 400">Deployment Insights</span></a><span style="font-weight: 400">. This new feature in </span><a href="https://help.salesforce.com/s/articleView?id=xcloud.scale_center_overview.htm&amp;type=5"><span style="font-weight: 400">Scale Center</span></a><span style="font-weight: 400"> automates post-release validation by unifying release events with platform metrics to deterministically isolate performance regressions from ambient traffic noise. </span></p>
<p><span style="font-weight: 400">In this blog post, we’ll walk you through how this telemetry engine functions and how to integrate it into your deployment runbooks to proactively catch stability issues before they impact your SLAs.</span></p>
<h2><span style="font-weight: 400">The post-deployment blind spot</span></h2>
<p><span style="font-weight: 400">Upon initiating a </span><a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_qs_deploy.htm"><span style="font-weight: 400">metadata deployment </span></a><span style="font-weight: 400">within a high-scale environment, conventional observability frameworks often struggle to address three critical architectural challenges:</span></p>
<ul>
<li style="font-weight: 400"><b>Fragmented telemetry correlation:</b><span style="font-weight: 400"> Validating systemic health demands intensive manual effort to bridge siloed metrics, where end user EPT, application server cycles, and Apex resource exhaustion signals remain isolated across disparate logs.</span></li>
<li style="font-weight: 400"><b>The deterministic baseline challenge:</b> <span style="font-weight: 400">Quantifying release-driven degradation requires comparing post-deployment performance against an equivalent peak-load window. Identifying a historical interval that precisely mirrors current traffic volume and utilization patterns is historically tedious and prone to error.</span></li>
<li style="font-weight: 400"><b>Latent architectural regressions:</b> <span style="font-weight: 400">Inefficiencies, such as a </span><a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SOQL_VLSQ.htm"><span style="font-weight: 400">non-selective query</span></a><span style="font-weight: 400"> embedded in new trigger logic, frequently escape detection in staging. These silent performance shifts only surface as critical bottlenecks when production traffic reaches peak utilization.</span></li>
</ul>
<p><span style="font-weight: 400">Deployment Insights eliminates this operational blind spot by unifying release events with Scale Center’s automated telemetry engine, delivering deterministic comparisons to identify exactly how code modifications impact environment stability.</span></p>
<h2><span style="font-weight: 400">Navigation and interpretation of the Deployment Insight Report</span></h2>
<p><span style="font-weight: 400">To generate a Deployment Insights Report, follow the steps below.</span></p>
<ol>
<li style="font-weight: 400"><span style="font-weight: 400">Navigate to the </span><b>Setup Menu</b><span style="font-weight: 400"> in Scale Center.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Go to the </span><b>Deployment Insights</b><span style="font-weight: 400"> section.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Select a specific deployment.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Click the </span><b>Generate Insights Report</b><span style="font-weight: 400"> button to view the report for that deployment.</span></li>
</ol>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206676" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260707074600/Screenshot-representing-how-to-navigate-to-Deployment-Insights-under-Setup-e1783435573329.png?w=1000" class="postimages" width="1000" height="263" alt="Screenshot representing how to navigate to Deployment Insights under Setup" />
			  </span>
			</p>
<p><span style="font-weight: 400">Once generated, the report moves from high-level operational signals down to granular, actionable component details.</span></p>
<h3><span style="font-weight: 400">Delta analysis and top-line telemetry</span></h3>
<p><span style="font-weight: 400">The top of the report delivers an automated delta summary, highlighting immediate efficiency shifts. Instead of looking at raw numbers, it provides percentage-based variances for foundational enterprise metrics. Sections include:</span><b></b></p>
<ul>
<li><b>Change in Errors Before and After Deployment </b>
<ul>
<li><span style="font-weight: 400">This section provides visualization for the anomaly in the errors related to Rowlock timeouts, such as </span><a href="http://google.com/search?q=concurrent+errors+salesforce&amp;rlz=1C5GCCM_en&amp;oq=concurrent+errors+salesforce&amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIICAEQABgWGB4yCAgCEAAYFhgeMg0IAxAAGIYDGIAEGIoFMgYIBBBFGDwyBggFEEUYQDIGCAYQRRhAMgYIBxBFGEDSAQg1NTc2ajBqNKgCALACAQ&amp;sourceid=chrome&amp;ie=UTF-8"><span style="font-weight: 400">c</span><span style="font-weight: 400">oncurrent errors,</span><span style="font-weight: 400"> c</span><span style="font-weight: 400">onnection pool errors</span></a><span style="font-weight: 400">, or callouts, that may have started to increase or decrease post deployment</span></li>
</ul>
</li>
</ul>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206677" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260707074603/Snapshot-of-the-Change-in-Errors-Chart-on-the-Deployment-Insights-Report-e1783435591372.png?w=1000" class="postimages" width="1000" height="350" alt="Snapshot of the Change in Errors Chart on the Deployment Insights Report" />
			  </span>
			</p>
<ul>
<li><b>Change in Performance Before and After Deployment </b>
<ul>
<li><b>Average SOAP and REST API Request Time</b><span style="font-weight: 400">: This metric provides degradation in the performance of the REST API and SOAP API-based requests getting invoked from external integration syncs</span></li>
<li><b>App CPU vs. DB CPU Per Request: </b><span style="font-weight: 400">This</span> <span style="font-weight: 400">metric instantly reveals if your application custom code has started to use more application server cycles (e.g., massive loops, inefficient JSON parsing) or stalling on database execution (e.g., non-selective queries post deployment</span></li>
<li><b>User Experience (EPT)</b><span style="font-weight: 400">: This metric surfaces the overall experience from the response time of UI-based requests that matters most to the end user experience</span></li>
</ul>
</li>
</ul>
<ul>
<li style="list-style-type: none">
<ul></ul>
</li>
</ul>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206678" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260707074605/Snapshot-of-the-Change-in-Performance-Before-and-After-Deployment-takeaways-e1783435605441.png?w=1000" class="postimages" width="1000" height="344" alt="Snapshot of the Change in Performance Before and After Deployment takeaways" />
			  </span>
			</p>
<p><span style="font-weight: 400">Each section provides self-explanatory takeaways for interpretation. The goal here is to provide a unified view of the data, so it&#8217;s easier to quickly identify whether or not a release deployment has actually created an issue in the first place.</span></p>
<h3><span style="font-weight: 400">Specialized diagnostic deep-dives</span></h3>
<p><span style="font-weight: 400">The Deployment Insights Report doesn&#8217;t stop at highlighting whether or not there was a problem, but it also identifies where the problem started post deployment and what actions can be taken up by the users to remediate those errors.</span><span style="font-weight: 400"> </span></p>
<p><span style="font-weight: 400">Beneath the top-line metrics are four dedicated tabs built for rapid, targeted triage</span><span style="font-weight: 400">: Errors, User Experience, API Performance, and Infrastructure Performance. </span></p>
<ul></ul>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206679" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260707074607/Snapshot-of-the-Indepth-Analysis-of-Errors-section-of-the-Deployment-Insights-Report-e1783435619415.png?w=1000" class="postimages" width="1000" height="376" alt="Snapshot of the Indepth Analysis of Errors section of the Deployment Insights Report" />
			  </span>
			</p>
<p><span style="font-weight: 400">To identify a regression in any of the metrics shown, click on the checkbox </span><b>Display numerical change from before to after deployment</b><span style="font-weight: 400"> present in each of the tabular data.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206680" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260707074610/Snapshot-of-the-Indepth-Analysis-of-User-Experience-section-of-the-Deployment-Insights-report-e1783435631948.png?w=1000" class="postimages" width="1000" height="552" alt="Snapshot of the Indepth Analysis of User Experience section of the Deployment Insights report" />
			  </span>
			</p>
<p><span style="font-weight: 400">Here is the tabular representation of each of these sections and the data that it provides for remediation. For each section, it clearly outlines the recommended fix on the entry point.</span></p>
<table>
<tbody>
<tr>
<td><b>Diagnostic Tab</b></td>
<td><b>Engineering Focus</b></td>
<td><b>Concrete Actionable Output</b></td>
</tr>
<tr>
<td><b>Errors</b></td>
<td><span style="font-weight: 400">Concurrency and platform friction</span></td>
<td><span style="font-weight: 400">Identifies</span> <b>Row Lock Errors</b><span style="font-weight: 400"> and </span><b>Concurrent Apex Limits, </b><span style="font-weight: 400">and maps raw database entities back to human-readable object names.</span></td>
</tr>
<tr>
<td><b>User Experience</b></td>
<td><span style="font-weight: 400">Client-side performance</span></td>
<td><span style="font-weight: 400">Provides p75 of page load times for specific page URLs, and highlights exactly which layouts or components regressed</span><span style="font-weight: 400">. </span><span style="font-weight: 400">This value represents the 75th percentile for EPT, which means that 75% of page loads for your users were this fast or faster. We use p75 instead of the average (or 50th percentile) because it more accurately represents the experience of users who encounter slower performance. This metric helps you to identify and focus on issues that affect a significant portion of your user base.</span></td>
</tr>
<tr>
<td><b>API Performance</b></td>
<td><span style="font-weight: 400">Integration layer integrity</span></td>
<td><span style="font-weight: 400">Segregates REST vs. SOAP health, isolating long-running executions (over five seconds) to catch regression trends before they trigger external gateway timeouts.</span></td>
</tr>
<tr>
<td><b>Infrastructure</b></td>
<td><span style="font-weight: 400">System resource consumption</span></td>
<td><span style="font-weight: 400">Pinpoints the dominant entry points (e.g., specific triggers, integration users, or batch jobs) contributing most heavily to App or DB CPU spikes.</span></td>
</tr>
</tbody>
</table>
<h2><span style="font-weight: 400">Under the hood: The telemetry engine architecture</span></h2>
<p><span style="font-weight: 400">Lets now understand the details of how we built the Deployment Insights Telemetry system.</span></p>
<p><span style="font-weight: 400">The system doesn&#8217;t just display linear historical trends; it builds a deterministic comparison model. The platform operates on an asynchronous pipeline that balances the Scale Center UI with backend system-level services to compute performance deltas without adding any runtime overhead to your production instance.</span></p>
<p><span style="font-weight: 400">Here is how the system orchestrates this process behind the scenes:</span></p>
<h3><span style="font-weight: 400">Deployment Telemetry Processing Flow</span></h3>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206681" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260707074612/User-Sequence-diagram-of-the-flow-to-generate-a-Deployment-Insights-Report-e1783435644877.png?w=1000" class="postimages" width="1000" height="784" alt="User Sequence diagram of the flow to generate a Deployment Insights Report" />
			  </span>
			</p>
<p><span style="font-weight: 400">Behind the scenes, the telemetry engine orchestrates a coordinated, four-step lifecycle to deliver deterministic performance insights:</span></p>
<ol>
<li style="font-weight: 400"><b>Deployment Identification:</b> <span style="font-weight: 400">The engine catalogs metadata and managed-package events from a 25-day rolling window, establishing a comprehensive chronology of environment modifications.</span></li>
<li style="font-weight: 400"><b>Sliding Window Calculation:</b> <span style="font-weight: 400">Upon report initiation, a backend heuristic scrutinizes historical load patterns. It performs a four-day retrospective to establish a </span><b>pre-deployment peak hour</b><span style="font-weight: 400"> baseline, aligning it against a verified </span><b>post-deployment peak traffic hour</b><span style="font-weight: 400"> derived from up to a three-day forward-looking analysis.</span></li>
<li style="font-weight: 400"><b>Telemetry Aggregation &amp; Normalization:</b> <span style="font-weight: 400">The system harvests high-fidelity metrics from across the infrastructure layers, specifically isolating fluctuations in app CPU, database execution, EPT, and platform concurrency limits.</span></li>
<li style="font-weight: 400"><b>Signal Isolation:</b> <span style="font-weight: 400">By correlating synchronized high-utilization windows, the engine filters out ambient traffic noise to spotlight architectural regressions driven solely by code changes.</span></li>
</ol>
<h3><span style="font-weight: 400">Architect&#8217;s tip: The Peak Hour Principle</span></h3>
<p><span style="font-weight: 400">Modern enterprise architectures are notoriously complex, generating vast oceans of telemetry. Effective validation requires analyzing performance during high-stakes business windows, where peak system load intersects with critical server-side behaviors. To address this, the engine intelligently identifies these specific peak hours, automating performance comparisons across high-utilization intervals to distinguish genuine production regressions from an optimized baseline.</span></p>
<h3><span style="font-weight: 400">System requirements, considerations, and noise isolation</span></h3>
<p><span style="font-weight: 400">To get the most out of Deployment Insights, architects must keep a few system behaviors and boundary conditions in mind:</span></p>
<ul>
<li style="font-weight: 400"><b>Supported deployment types:</b> <span style="font-weight: 400">The engine can track metadata changes across all standard delivery mechanisms, whether your pipeline pushes changes programmatically (via the Salesforce CLI or direct </span><a href="https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/file_based_zip_file.htm"><span style="font-weight: 400">Metadata API</span></a><span style="font-weight: 400"> calls), promotes work items through DevOps Center, uses native change sets, or installs unlocked packages</span><span style="font-weight: 400">. </span></li>
<li style="font-weight: 400"><b>Minimum traffic thresholds:</b> <span style="font-weight: 400">Because the engine relies on the Peak Hour Principle, the target organization must maintain a baseline of active production traffic. In ultra-low volume orgs’ full copy sandboxes with sporadic usage, the sliding window heuristic may struggle to isolate clear peak-hour baselines.</span></li>
<li style="font-weight: 400"><b>Isolating environmental noise</b><span style="font-weight: 400">: If multiple decoupled teams deploy changes within the same deployment window, or if a seasonal traffic surge (like a scheduled marketing blast) occurs simultaneously, results can become ambiguous. In these scenarios, use th</span><span style="font-weight: 400">e </span><b>Infrastructure</b><span style="font-weight: 400"> tab to isolate the specific entry points. If the DB CPU spike correlates to a specific Apex class modified in your deployment payload, it is a code regression. If the spike is uniformly distributed across unchanged legacy APIs, the shift is likely environmental noise.</span></li>
</ul>
<h2><span style="font-weight: 400">Post-deployment runbook best practices</span></h2>
<p><span style="font-weight: 400">To shift your release cycle from reactive firefighting to automated validation, incorporate Deployment Insights directly into your production deployment runbooks using this checklist:</span></p>
<ol>
<li style="font-weight: 400"><b>Establish a mandatory release gate:</b> <span style="font-weight: 400">Add a Deployment Insights review as a standard checklist item for your deployment team, treating post-release performance validation with the same severity as your automated test runs.</span></li>
<li style="font-weight: 400"><b>Enforce the 24-Hour stabilization window:</b><span style="font-weight: 400"> Do not generate the report immediately after a deployment finishes. Allow the production environment to run for 24 hours, so the telemetry engine can capture a true, representative</span> <b>peak-load business window</b><span style="font-weight: 400">.</span></li>
<li style="font-weight: 400"><b>Analyze percentage-based deltas:</b> <span style="font-weight: 400">Generate the report and scan for color-coded deltas. Focus on any core metric (App CPU, DB CPU, or EPT) that exhibits a regression greater than 15% from the pre-deployment baseline.</span></li>
<li style="font-weight: 400"><b>Bypass manual log triage:</b> <span style="font-weight: 400">If a regression is flagged, skip manually writing Event Log File queries. Use the report’s integrated diagnostic deep-links to pivot directly into a specialized investigation view</span><span style="font-weight: 400"> (such as a </span><b>Concurrent Apex Investigation</b><span style="font-weight: 400">), </span><span style="font-weight: 400">which will automatically load with the exact peak-hour timestamps pre-populated.</span></li>
</ol>
<h2><span style="font-weight: 400">About the author</span></h2>
<p><b>Anand Vardhan</b> <span style="font-weight: 400">is a Product Owner for the Scalability Products Team, helping customers develop scalable solutions on the Customer 360 platform. Anand designs features for Scale Center and Scale Test products. His background includes performance and scale engineering, server-side optimization, Lightning, application design, caching, and managing large data volumes. Follow Anand on </span><a href="https://www.linkedin.com/in/anandvardhan08/"><span style="font-weight: 400">LinkedIn</span></a><span style="font-weight: 400">.</span></p>
<p><span><strong>Ravi Raina</strong> is Director Product Management at Salesforce working on the Scalability Products portfolio.</span></p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/07/identify-and-fix-performance-regressions-using-deployment-insights-in-scale-center">Identify and Fix Performance Regressions Using Deployment Insights in Scale Center</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://developer.salesforce.com/blogs/2026/07/identify-and-fix-performance-regressions-using-deployment-insights-in-scale-center/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206673</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260708081838/Generic-D-6-e1783523931348.png?w=1000" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260708081838/Generic-D-6-e1783523931348.png?w=1000" medium="image" />
	</item>
		<item>
		<title>Build Native Mobile Apps Within Minutes Using Agent Skills</title>
		<link>https://developer.salesforce.com/blogs/2026/07/build-native-mobile-apps-within-minutes-using-agent-skills</link>
		<comments>https://developer.salesforce.com/blogs/2026/07/build-native-mobile-apps-within-minutes-using-agent-skills#respond</comments>
		<pubDate>Thu, 02 Jul 2026 15:00:35 +0000</pubDate>
		<dc:creator><![CDATA[Shalini Jain]]></dc:creator>
				<category><![CDATA[Agentforce]]></category>
		<category><![CDATA[Announcements]]></category>
		<category><![CDATA[App Development]]></category>
		<category><![CDATA[Developer Tooling]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Agent Skills]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[app development]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mobile Skills]]></category>
		<category><![CDATA[Offline Sync]]></category>
		<category><![CDATA[salesforce mobile sdk]]></category>
		<category><![CDATA[smartstore]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206640</guid>
		<description><![CDATA[<p>Accelerate mobile development with the new generally available Mobile Skills, using simple prompts to generate native projects with authentication, offline support, and Mobile SDK built in.</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/07/build-native-mobile-apps-within-minutes-using-agent-skills">Build Native Mobile Apps Within Minutes Using Agent Skills</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p><span style="font-weight: 400">If you&#8217;ve ever built a Salesforce mobile app, you know the drill. You start with an idea, then spend the first two weeks wiring up authentication, setting up sync targets, and debugging offline behavior, long before you write a single line of the business logic your customer actually asked for.</span></p>
<p><span style="font-weight: 400">What if you could skip all of that and just </span><i><span style="font-weight: 400">describe</span></i><span style="font-weight: 400"> what you want? In this post, we&#8217;ll walk through how the new </span><a href="https://github.com/forcedotcom/sf-skills/tree/main/skills/mobile-apps-create"><span style="font-weight: 400">Mobile Skills</span></a><span style="font-weight: 400"> can accelerate your mobile app development, from initial project setup all the way through building real features and functionality.</span></p>
<h2>Getting past the mobile learning curve</h2>
<p><span style="font-weight: 400">Most Salesforce Developers are comfortable with business logic. What trips them up is everything around it, including OAuth handshakes, SDK version mismatches, Xcode build settings, and Gradle configurations. Native mobile development involves significant infrastructure overhead that has nothing to do with the app&#8217;s actual purpose, and it can take days just to get a project into a state where real work can begin.</span></p>
<p><span style="font-weight: 400">Mobile Skills take that entire bootstrapping phase off your plate. They generate a clean, modern project structure with authentication and SDK integration already wired up, so your first task is building a feature, not fighting a toolchain.</span></p>
<h2><b>Built for developers who live in IDEs, not GUIs</b></h2>
<p><span style="font-weight: 400">Mobile Skills output standard source files organized the way a professional iOS or Android project should be. You get a real Xcode workspace or Android Studio project that you can read, refactor, and push to Git. The code is yours from the moment it&#8217;s generated.</span></p>
<h2><b>Skills: How agents go from generic to useful</b></h2>
<p><span style="font-weight: 400">An Agent Skill is a packaged, reusable capability that an AI agent can invoke. Think of it as a well-documented function your AI assistant knows how to call, except instead of returning a string, it can scaffold a project, generate code, configure SDKs, or run commands on your behalf.</span></p>
<p><span style="font-weight: 400">Each skill ships with:</span></p>
<ul>
<li style="font-weight: 400"><b>A clear contract</b><span style="font-weight: 400"> — what it does, what inputs it expects, what it produces</span></li>
<li style="font-weight: 400"><b>Domain knowledge</b><span style="font-weight: 400"> — the patterns, APIs, and conventions for the task</span></li>
<li style="font-weight: 400"><b>Executable instructions</b><span style="font-weight: 400"> — so the agent can actually do the work, not just talk about it</span></li>
</ul>
<p><span style="font-weight: 400">Skills are how you turn a general-purpose AI into a domain expert. A generic LLM might know that the Salesforce Mobile SDK exists. A skill </span><i><span style="font-weight: 400">knows</span></i><span style="font-weight: 400"> the right project template, the right dependencies, and exactly which boilerplate to generate for your org&#8217;s auth flow.</span></p>
<h2><b>Introducing Mobile Skills</b></h2>
<p><span style="font-weight: 400">Mobile Skills give your AI agent everything it needs to build production-quality native mobile apps using Salesforce Mobile SDK, the same SDK that powers Salesforce mobile apps.</span></p>
<p><span style="font-weight: 400">Here&#8217;s what the Mobile Skills are capable of today</span><span style="font-weight: 400">:</span></p>
<ul>
<li>
<h3><b>Create a Mobile SDK app from scratch</b></h3>
</li>
</ul>
<p><span style="font-weight: 400">Describe the app you want, for example </span><i><span style="font-weight: 400">&#8220;Build me a native iOS app for field reps with offline access to Accounts and Contacts&#8221;</span></i><span style="font-weight: 400">, and </span><span style="font-weight: 400">Mobile Skills</span><span style="font-weight: 400"> scaffold a fresh Mobile SDK project, configured for your org, ready to run.</span></p>
<ul>
<li>
<h3><b>Add Mobile SDK to an existing app</b></h3>
</li>
</ul>
<p><span style="font-weight: 400">Already have an iOS or Android app?</span><span style="font-weight: 400"> Mobile Skills</span><span style="font-weight: 400"> can integrate Mobile SDK into your existing codebase without forcing you to start over. They handle dependencies, configuration, and the integration patterns that often trip people up.</span></p>
<ul>
<li>
<h3><b>SmartStore sync</b></h3>
</li>
</ul>
<p><span style="font-weight: 400">Configure encrypted, on-device storage with a single prompt. </span><span style="font-weight: 400">Mobile Skills</span><span style="font-weight: 400"> know the soup definitions, indexing strategies, and query patterns that work, so there’s no more digging through docs to figure out what IndexSpec to use.</span></p>
<ul>
<li>
<h3><b>Mobile sync</b></h3>
</li>
</ul>
<p><span style="font-weight: 400">Set up bidirectional sync between your app and your org with the right sync targets, sync down/up policies, and conflict resolution, and do it all declaratively, from a prompt.</span></p>
<ul>
<li>
<h3><b>Offline-first behavior</b></h3>
</li>
</ul>
<p><span style="font-weight: 400">Tell your agent &#8220;this app needs to work offline&#8221; and </span><span style="font-weight: 400">Mobile Skills</span><span style="font-weight: 400"> wire up the right combination of SmartStore + MobileSync, sets up appropriate cache policies, and handles the edge cases (for example, network transitions, failed syncs, and dirty records) that can take weeks to get right by hand.</span></p>
<ul>
<li>
<h3><b>Authentication and login</b></h3>
</li>
</ul>
<p><span style="font-weight: 400">Basic auth, OAuth flows, and login screens are all generated correctly the first time, following the secure patterns Salesforce recommends.</span></p>
<ul>
<li>
<h3><b>Biometric authentication</b></h3>
</li>
</ul>
<p><span style="font-weight: 400">Add Face ID, Touch ID, or Android biometrics to your app with a single instruction. </span><span style="font-weight: 400"> Mobile Skills</span><span style="font-weight: 400"> handles the platform differences, the fallback flows, and the security best practices.</span></p>
<ul>
<li>
<h3><b>Agentforce chat panel integration</b></h3>
</li>
</ul>
<p><span style="font-weight: 400">Drop a fully-wired Agentforce chat experience into your mobile app. Your end users get an intelligent, contextual agent inside </span><i><span style="font-weight: 400">their</span></i><span style="font-weight: 400"> app, configured to talk to </span><i><span style="font-weight: 400">your</span></i><span style="font-weight: 400"> org, and you don&#8217;t have to read a single integration guide.</span></p>
<h2><b>Getting started with Mobile Skills</b></h2>
<p><span style="font-weight: 400">Mobile Skills are part of </span><a href="https://github.com/forcedotcom/sf-skills"><span style="font-weight: 400">forcedotcom/sf-skills</span></a><span style="font-weight: 400">, the open-source collection of Salesforce Agent Skills for platform development. The repository is public: you can browse it, fork it, contribute to it, and pull skills into whatever agentic tool you&#8217;re already using. Think of it as a growing catalog of things AI agents should know how to do on Salesforce.</span></p>
<h3><b>Works wherever you work</b></h3>
<p><span style="font-weight: 400">Skills in this repository follow the open Agent Skills specification, which means they aren&#8217;t locked to a single tool. Mobile Skills work across surfaces, whether that&#8217;s Agentforce Vibes (available out of the box), Claude Code, Cursor, OpenCode, Codex, or any other agent that supports the spec. To install in a code agent, just run:<br />
<code>npx skills add https://github.com/forcedotcom/sf-skills --skill mobile-apps-create</code><br />
</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206644" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260626111650/image1_da5284-e1782497854718.png?w=1000" class="postimages" width="1000" height="526" alt="Screenshot showing skill installation in Claude CLI" />
			  </span>
			</p>
<h3><b>How it works under the hood</b></h3>
<p><code>/mobile-apps-create</code><span> is the primary entry point — </span><span style="font-weight: 400">a lightweight orchestrator that lives in sf-skills. When you describe what you want to build (for example, &#8220;I need a Salesforce mobile app with offline sync&#8221;), the orchestrator determines which SDK family and platform you&#8217;re targeting, then routes your request to the appropriate individual skill that handles the actual work.</span></p>
<h2><b>A real example</b></h2>
<p><span style="font-weight: 400">It starts with a single sentence. In Agentforce Vibes, describe the app that you want to build. In this example, I’m building an iOS app to manage a store inventory and sync the data back to Salesforce. </span></p>
<p><span style="font-weight: 400">Agentforce Vibes picks up the intent, activates Mobile Skills under the hood — handling Mobile SDK authentication, SmartStore for offline data, and MobileSync for bidirectional Salesforce sync — and starts generating the full app.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206646" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260626111656/image3_435160-e1782497957522.png?w=1000" class="postimages" width="1000" height="647" alt="Screenshot displaying Agentforce Vibes chat panel with the prompt to create a mobile app and Mobile-apps-create skill being invoked by the agent" />
			  </span>
			</p>
<p><span style="font-weight: 400">Within moments, the app is built and running in the iOS simulator. The first thing you see is the standard Salesforce OAuth login screen, secure, familiar, and fully functional. Mobile SDK handles the entire authentication flow, including token management, refresh, and session persistence. No custom auth code required.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206648" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260626111702/image5_7dc8a1-e1782498037153.png?w=1000" class="postimages" width="1000" height="647" alt="Screenshot displaying the login page of the app after it launched in a simulator" />
			  </span>
			</p>
<p><span style="font-weight: 400">After login, the app lands on a home screen with a clean product inventory dashboard. Counts, categories, and visual summaries are all pulled live from the Salesforce org. This isn&#8217;t a mockup; it&#8217;s real data flowing through MobileSync&#8217;s soup-to-cloud sync pipeline, displayed in a native SwiftUI interface.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206647" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260626111659/image4_82883c-e1782498074311.png?w=1000" class="postimages" width="1000" height="647" alt="Screenshot showing the home page of the app in the simulator" />
			  </span>
			</p>
<p><span style="font-weight: 400">Tapping into the Products tab reveals the full inventory list, with each item editable. You can add a new product, update a quantity, or change a description; every modification syncs back to Salesforce automatically. Even if the device goes offline, SmartStore caches changes locally and MobileSync pushes them upstream when connectivity returns.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206650" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260626111711/image7_716480-e1782498178666.png?w=1000" class="postimages" width="1000" height="647" alt="Screenshot showing the Products tab of the app in the simulator" />
			  </span>
			</p>
<p><span style="font-weight: 400">But why stop at inventory management? Back in the Agentforce Vibes prompt, I went ahead and asked the agent to embed an Agentforce chat panel. Just like that, the app now includes a native Agentforce conversational interface right inside the app. The Agentforce SDK handles the agent connection, conversation threading, and action orchestration, all wired up from a single prompt.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206645" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260626111654/image2_5d2329-e1782498218517.png?w=1000" class="postimages" width="1000" height="647" alt="Screenshot showing the Agentforce added to the app" />
			  </span>
			</p>
<p><span style="font-weight: 400">Store Managers can use the Agentforce chat to ask questions like &#8220;Which products are low in stock?&#8221; or ask it to refill stock without ever leaving the app. It&#8217;s not just an app anymore; it&#8217;s an AI-powered mobile experience, built in minutes.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206649" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260626111705/image6_201d89-e1782498252472.png?w=1000" class="postimages" width="1000" height="647" alt="Screenshot of the Agentforce chat panel during an ongoing conversation to order stock replenishment" />
			  </span>
			</p>
<h2><b>What&#8217;s Next</b></h2>
<p><span style="font-weight: 400">The Mobile Skills you see today are the foundation. We&#8217;re actively expanding the library to cover more SDK capabilities, more frameworks, and richer end-to-end app generation flows. If you&#8217;re building mobile apps on Salesforce, this is the moment to plug AI into your workflow, not as a typing assistant, but as a companion engineer who already knows the platform.</span></p>
<p><b>Your feedback matters! Try Mobile Skills, share your </b><a href="https://forms.gle/5cyRGd9tt5JCSk3x7"><b>feedback</b></a><b>, and tell us what to build next.</b></p>
<h2><b>Resources:</b></h2>
<ul>
<li style="font-weight: 400"><a href="https://github.com/forcedotcom/sf-skills"><span style="font-weight: 400">Explore sf-skills on GitHub</span></a></li>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/workshops/agentforce-workshop/agents/1-get-started"><span style="font-weight: 400">Get Started with Agentforce</span></a></li>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/docs/platform/mobile-sdk/overview"><span style="font-weight: 400">Mobile SDK Developer Guide</span></a></li>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/docs/platform/mobile-sdk/guide/install-github.html"><span style="font-weight: 400">Mobile SDK GitHub repository</span></a></li>
</ul>
<h2><b>About the author</b></h2>
<p><span style="font-weight: 400"><strong>Shalini Jain</strong> is a Director of Product Management at Salesforce, where her primary focus lies in shaping the Mobile Platform Experience for developers through AI-driven innovation. Her current initiatives are heavily invested in enhancing developer productivity by bringing agentic AI capabilities directly into the mobile development workflow, as evidenced by the tools highlighted throughout this blog post. Furthermore, she is spearheading new features in Mobile SDK to further streamline and optimize how developers build, test, and ship mobile apps, with the ultimate goal of delivering a truly seamless and intuitive experience for all Salesforce mobile developers.</span></p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/07/build-native-mobile-apps-within-minutes-using-agent-skills">Build Native Mobile Apps Within Minutes Using Agent Skills</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://developer.salesforce.com/blogs/2026/07/build-native-mobile-apps-within-minutes-using-agent-skills/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206640</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260626143403/Generic-B-4-e1782509658601.png?w=1000" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260626143403/Generic-B-4-e1782509658601.png?w=1000" medium="image" />
	</item>
		<item>
		<title>LWC State Managers: Share Reactive State Across Components</title>
		<link>https://developer.salesforce.com/blogs/2026/07/lwc-state-managers-share-reactive-state-across-components</link>
		<comments>https://developer.salesforce.com/blogs/2026/07/lwc-state-managers-share-reactive-state-across-components#respond</comments>
		<pubDate>Wed, 01 Jul 2026 15:00:22 +0000</pubDate>
		<dc:creator><![CDATA[Ben Sklar]]></dc:creator>
				<category><![CDATA[App Development]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Lightning Web Components]]></category>
		<category><![CDATA[Salesforce Releases]]></category>
		<category><![CDATA[@lwc/state]]></category>
		<category><![CDATA[Context API]]></category>
		<category><![CDATA[lightning data service]]></category>
		<category><![CDATA[LWC State Managers]]></category>
		<category><![CDATA[Reactive Programming]]></category>
		<category><![CDATA[State Management]]></category>
		<category><![CDATA[Summer '26 Release]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206634</guid>
		<description><![CDATA[<p>Learn how to use the new generally available @lwc/state module to share reactive data across component trees without prop drilling.</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/07/lwc-state-managers-share-reactive-state-across-components">LWC State Managers: Share Reactive State Across Components</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p><span>State managers are now generally available in Lightning Web Components (LWC)! The Summer &#8217;26 release ships the </span><a href="https://developer.salesforce.com/docs/platform/lwc/guide/state-management.html"><u>@lwc/state</u></a><span> module, providing developers with a first-class, reactive pattern for organizing and sharing application data across component trees without prop drilling, custom events, or pub/sub workarounds, plus a library of ready-made state managers from the </span><code>lightning</code><span> namespace built on the same Lightning Data Service and UI API foundations you already use today.</span></p>
<h2><span>Defining state in LWC with </span><code>defineState</code></h2>
<p><span>A state manager is a dedicated JavaScript module that encapsulates a related set of data (the &#8220;state&#8221;) and the actions that operate on it. You create one with the </span><code>defineState</code><span> function from </span><code>@lwc/state</code><span>, passing a setup function. The setup function&#8217;s first argument is an object of building blocks: </span><code>atom</code><span>, </span><code>computed</code><span>, and </span><code>setAtom</code><span>. </span><code>defineState</code><span> returns a factory; any arguments you pass when you call it flow through to your setup function after that object, so you can parameterize each instance:</span></p>
<ul>
<li><span>An </span><code><span>atom</span></code><span> is a reactive “atomic” value, which is essentially a wrapper around a piece of data that LWC can use to make components and other state managers reactive to changes in that data.</span></li>
<li><span>A </span><code><span>computed</span></code><span> is a lazily-evaluated derivation that recalculates only when its dependencies change.</span></li>
<li><code><span>setAtom</span></code><span> is used whenever you need to modify state.</span></li>
</ul>
<pre language="javascript">import { defineState } from '@lwc/state';

export const createCounter = defineState(({ atom, computed, setAtom }, initialCount = 0) =&gt; {
    const count = atom(initialCount);
    const doubled = computed([count], (countValue) =&gt; countValue * 2);


    const increment = () =&gt; setAtom(count, count.value + 1);


    return { count, doubled, increment };
});
</pre>
<p><span>Any component that references </span><code>count</code><span> or </span><code>doubled</code><span> in a reactive context is automatically re-rendered after </span><code>increment</code><span> runs. Computed values recompute lazily and only when their inputs change, and multiple </span><code>setAtom</code><span> calls in the same tick are batched into a single notification cycle, so you get reactivity without the re-render churn.</span></p>
<h2><span>Sharing state across a component tree with </span><code>fromContext</code></h2>
<p><span>State managers go beyond a single component. You can create an instance at the top of a component tree and consume it in a descendant component below using </span><code>fromContext</code><span>, with no prop drilling, no event handling, and no pub/sub plumbing:</span></p>
<p><span style="font-weight: 400">Example code for the top-level component that instantiates the state manager:</span></p>
<pre language="javascript">import createShopStateManager from 'c/shopState';

export default class App extends LightningElement {
    shopState = createShopStateManager();
}
</pre>
<p><span style="font-weight: 400">Example of a descendant component that reads the same instance via LWC context:</span></p>
<pre language="javascript">import { LightningElement } from 'lwc';
import { fromContext } from '@lwc/state';
import createShopStateManager from 'x/shopState';

export default class Cart extends LightningElement {
    shopState = fromContext(createShopStateManager);

    get cartTotal() {
        return `$${this.shopState.value.cartTotal.toFixed(2)}`;
    }
}
</pre>
<h2><span>Built-in state managers for Salesforce data</span></h2>
<p><span>Salesforce ships a </span><a href="https://developer.salesforce.com/docs/platform/lwc/guide/reference-state-managers.html"><u>collection of state managers</u></a><span> in the </span><code>lightning</code><span> namespace that expose Salesforce data and metadata through the Lightning Data Service. Each one presents a uniform shape:</span></p>
<h3><code><span>status</span></code></h3>
<ul>
<li><code><span>“unconfigured"</span></code><span>: The state manager doesn’t have sufficient configuration information to proceed</span></li>
<li><code><span>“loading"</span></code><span>: The state manager is in the process of obtaining data</span></li>
<li><code><span>“loaded"</span></code><span>: The state manager has loaded data and set the </span><code><span>data</span></code><span> </span><span><span> </span></span><span>property</span></li>
<li><code><span>“error"</span></code><span>: There was an error loading the data. The </span><code><span>error</span></code><span> property contains additional information</span></li>
</ul>
<h3><code><span>data</span></code></h3>
<p><span>When the state manager </span><code>status</code><span> property is </span><code>“loaded"</code><span>, the </span><code>data</code><span> property is in a valid state, and can be used by consumers of the state manager. The form and structure of </span><code>data</code><span> depend on the specific state manager.</span></p>
<h3><code><span>error</span></code></h3>
<p><span>When the state manager </span><code>status</code><span> property is </span><code>“error"</code><span>, the </span><code>error</code><span> property is in a valid state, and contains details of the specific error. If there’s a configuration error with the state manager itself, for example, missing or invalid parameters used in the factory function, </span><code>error</code><span> is usually a simple string. If the error is with the request or response, </span><code>error</code><span> can be a </span><code>FetchResponse</code><span>. However, error handling is complex. See </span><a href="https://developer.salesforce.com/docs/platform/lwc/guide/data-error.html"><u>Handle Errors in Lightning Data Service</u></a><span> for a thorough explanation.</span></p>
<p><span>Available state managers expose record, objectInfo, layout, and related list data. Because state managers can be nested and wired together with </span><code>computed</code><span>, you can build sophisticated, fully reactive data waterfalls, for example: fetch a record to discover its record type, then fetch the matching layout, then fetch the full record using the layout&#8217;s fields.</span></p>
<p><span>Example of a component that consumes a </span><code><span>lightning/stateManagerRecord</span></code><span>:</span></p>
<pre language="javascript">import { LightningElement, api } from 'lwc';
import { getFieldValue } from 'lightning/uiRecordApi';
import createRecordStateManager from 'lightning/stateManagerRecord';
import ACCOUNT_NAME_FIELD from '@salesforce/schema/Account.Name';
import ACCOUNT_INDUSTRY_FIELD from '@salesforce/schema/Account.Industry';

export default class AccountCard extends LightningElement {
    _recordId;

    // The built-in state manager instance. Config takes the schema field refs;
    // recordId is supplied later via the @api setter.
    state = createRecordStateManager({
        fields: [ACCOUNT_NAME_FIELD, ACCOUNT_INDUSTRY_FIELD]
    });

    @api
    set recordId(id) {
        this._recordId = id;
        // Updaters live on the frozen outer shape, so go through .value.
        this.state.value.setRecordId(id);
    }
    get recordId() {
        return this._recordId;
    }

    get displayLabel() {
        const { status, data } = this.state.value;
        if (status !== 'loaded') return 'Loading…';
        const name = getFieldValue(data, ACCOUNT_NAME_FIELD) ?? 'Unknown';
        const industry = getFieldValue(data, ACCOUNT_INDUSTRY_FIELD) ?? '';
        return industry ? `${name} — ${industry}` : name;
    }
}
</pre>
<h2><b>See state managers in action</b></h2>
<p><span style="font-weight: 400">State managers bring a modern, reactive data-flow pattern to LWC that scales from a single component to a full application. Because state managers are plain JavaScript modules with no DOM dependency, you can unit-test them with Jest without mounting a component. You can reuse the same state module across multiple component trees. And because consumers read values from the state manager&#8217;s public shape rather than reaching into its internals, you can refactor how state is stored without updating every consumer. Additionally, with the built-in UI API state managers, you get that same shape for Salesforce data out of the box. Note: state managers are available in Lightning Experience, but not yet supported in Experience Cloud.</span></p>
<p><span style="font-weight: 400">To help you get started, we&#8217;ve published two complete examples in the </span><a href="https://github.com/forcedotcom/state-management/tree/main/examples"><span style="font-weight: 400">forcedotcom/state-management GitHub repository</span></a><span style="font-weight: 400">:</span></p>
<ul>
<li style="font-weight: 400"><b>simple-store</b><span style="font-weight: 400">: A standalone shopping-cart application (</span><a href="https://youtu.be/u-N1kEYB7ts?si=DJlbEz3DeyhqptAU&amp;t=371"><span style="font-weight: 400">demoed at TDX in March 2026</span></a><span style="font-weight: 400">) that shows how multiple components can read and mutate the same state manager entirely through context, with no properties or events. You can run it live on </span><a href="https://stackblitz.com/github/forcedotcom/state-management/tree/main/examples/simple-store"><span style="font-weight: 400">StackBlitz</span></a><span style="font-weight: 400">.</span></li>
<li style="font-weight: 400"><b>platform-state-managers</b><span style="font-weight: 400">: A Salesforce DX project that builds a layout-driven record detail panel using the record and layout state managers. The source is heavily commented, and is the best place to learn the basics.</span></li>
</ul>
<h2><b>More resources</b></h2>
<p><span style="font-weight: 400">Ready to start managing your state? Here are additional resources you need to dive in:</span></p>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">Developer Documentation: </span><a href="https://developer.salesforce.com/docs/platform/lwc/guide/state-management.html"><span style="font-weight: 400">Manage State Across LWC Components</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">GitHub repository (</span><a href="https://github.com/forcedotcom/state-management"><span style="font-weight: 400">forcedotcom/state-management</span></a><span style="font-weight: 400">): Find the platform-state-managers and simple-store examples.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Live playground (</span><a href="https://stackblitz.com/github/forcedotcom/state-management/tree/main/examples/simple-store"><span style="font-weight: 400">Simple Store on StackBlitz</span></a><span style="font-weight: 400">): Explore a full state-manager app in your browser.</span></li>
</ul>
<h2><b>About the Authors</b></h2>
<p><b>Mike Burr</b><span style="font-weight: 400"> is a Principal Member of Technical Staff at Salesforce from the Lightning Data Service team. When he’s not building client data libraries, he&#8217;s busy tweaking his home automation and listening to audiobooks.</span></p>
<p><b>Ben Sklar</b><span style="font-weight: 400"> is a Director of Product Management at Salesforce responsible for UI API, GraphQL API, Lightning Data Service, and AI Developer Kit. Ben is a major fan of GraphQL, but when not using GraphQL, you can find him playing ultimate frisbee or skiing during the winter. Follow him on </span><a href="https://www.linkedin.com/in/benjamin-sklar/"><span style="font-weight: 400">LinkedIn</span></a><span style="font-weight: 400">.</span></p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/07/lwc-state-managers-share-reactive-state-across-components">LWC State Managers: Share Reactive State Across Components</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://developer.salesforce.com/blogs/2026/07/lwc-state-managers-share-reactive-state-across-components/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206634</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260626093251/Generic-A-5-e1782491584474.png?w=1000" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260626093251/Generic-A-5-e1782491584474.png?w=1000" medium="image" />
	</item>
		<item>
		<title>How to Secure Salesforce Hosted MCP Servers</title>
		<link>https://developer.salesforce.com/blogs/2026/06/how-to-secure-salesforce-hosted-mcp-servers</link>
		<comments>https://developer.salesforce.com/blogs/2026/06/how-to-secure-salesforce-hosted-mcp-servers#respond</comments>
		<pubDate>Tue, 30 Jun 2026 15:00:38 +0000</pubDate>
		<dc:creator><![CDATA[Philippe Ozil]]></dc:creator>
				<category><![CDATA[App Development]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206595</guid>
		<description><![CDATA[<p>Learn how to secure Salesforce Hosted MCP Servers from authentication, authorization, permission controls, and logging.</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/06/how-to-secure-salesforce-hosted-mcp-servers">How to Secure Salesforce Hosted MCP Servers</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p><a href="https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/hosted-mcp-servers-overview.html"><span style="font-weight: 400">Salesforce Hosted MCP (Model Context Protocol) Servers</span></a><span style="font-weight: 400"> are one of the key components of Headless 360, letting you extend agents with </span><a href="https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/servers-reference.html"><span style="font-weight: 400">standard</span></a><span style="font-weight: 400"> and </span><a href="https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/custom-servers.html"><span style="font-weight: 400">custom</span></a><span style="font-weight: 400"> capabilities. As you expose tools, prompts, and resources to users, securing access to these servers is critical to protect your data and operations.</span></p>
<p><span style="font-weight: 400">Whether you&#8217;re a developer building MCP servers or an admin managing them, understanding the security model helps you control who can access what, when, and how. In this post, we&#8217;ll cover authentication, authorization, permission controls, and logging best practices for Salesforce Hosted MCP Servers.</span></p>
<h2><span style="font-weight: 400">Understanding the Salesforce Hosted MCP Server security model</span></h2>
<p><span style="font-weight: 400">The Salesforce MCP security model has three layers:</span></p>
<ol>
<li style="font-weight: 400"><b>Authentication:</b><span style="font-weight: 400"> Verifies who&#8217;s making the request</span></li>
<li style="font-weight: 400"><b>Authorization:</b><span style="font-weight: 400"> Determines what they&#8217;re allowed to do</span></li>
<li style="font-weight: 400"><b>Permission controls:</b><span style="font-weight: 400"> Enforce granular access at the object and field level when working with the primitives (tools, prompts and resources) exposed by the server</span></li>
</ol>
<p><span style="font-weight: 400">And, in addition to these security layers, </span><b>logging</b><span style="font-weight: 400"> tracks all activity for audit and compliance.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206605" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260624113313/image2_b02f7e-e1782326005117.png?w=1000" class="postimages" width="1000" height="770" alt="Diagram illustrating the three security layers and logging" />
			  </span>
			</p>
<p><span style="font-weight: 400">The first two layers are directly linked to the MCP standard and the third (permission controls) is specific to the Salesforce Platform. Each security layer builds on the previous one. You can&#8217;t authorize someone until you know who they are. You can&#8217;t enforce permissions without authorization rules.</span></p>
<p><span style="font-weight: 400">Understanding how these layers and logging work together helps you build a defense-in-depth strategy. Let&#8217;s look at each layer in detail.</span></p>
<h3><span style="font-weight: 400">Authentication: Verifying identity</span></h3>
<p><span style="font-weight: 400">Authentication is the first line of defense. It answers the question: &#8220;Who are you?&#8221;</span></p>
<p><span style="font-weight: 400">Authentication and authorization are technically defined as optional for MCP implementations as per the </span><a href="https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization"><span style="font-weight: 400">MCP specification</span></a><span style="font-weight: 400">, but we will assume for the rest of this post that it&#8217;s mandatory in an enterprise context given that without proper security, unauthorized users could access sensitive data or trigger unwanted operations.</span></p>
<p><span style="font-weight: 400">MCP specifies </span><a href="https://datatracker.ietf.org/doc/html/rfc6749"><span style="font-weight: 400">OAuth 2.0</span></a><span style="font-weight: 400"> as its authentication and authorization mechanism. It supports only a subset of OAuth 2.0 — not every authorization flow or grant type is available. Popular clients like Claude and ChatGPT support fewer flows than Salesforce does.</span></p>
<p><span style="font-weight: 400">While MCP is fairly recent, OAuth 2.0 has been around for more than a decade and the Salesforce Platform has a number of mechanisms to integrate with OAuth, whether it acts as a client or a server. This means that, as a Salesforce Developer, you do not have to implement OAuth security. Instead, you control it declaratively through an </span><a href="https://help.salesforce.com/s/articleView?id=xcloud.external_client_apps.htm&amp;type=5"><span style="font-weight: 400">external client app</span></a><span style="font-weight: 400"> (ECA).</span></p>
<p><span style="font-weight: 400">We strongly recommend creating a dedicated ECA per MCP client (one for Claude, one for ChatGPT, one for Cursor, etc.) rather than sharing a single ECA across multiple clients. This helps with controlling access and auditing the client&#8217;s activity.</span></p>
<p><span style="font-weight: 400">When it comes to Salesforce Hosted MCP Servers, we only support the </span><a href="https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_web_server_flow.htm&amp;type=5"><span style="font-weight: 400">authorization code flow</span></a><span style="font-weight: 400"> through the ECA. This means that users have to authenticate with Salesforce when connecting to the MCP server. Their individual Salesforce user account is tied to the MCP session.</span></p>
<p><b>Notes:</b></p>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">There&#8217;s no option to specify a service account with a principal user, such as an integration user, to be used across all sessions. This is an anti-pattern that customers should avoid.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">At this time, there&#8217;s no plan to allow machine-to-machine flows. The human remains in the loop to connect to the org and grant access to the MCP tools.</span></li>
</ul>
<p><span style="font-weight: 400">By default, any user from your org can connect to your ECA and access the MCP servers. However, you can specify authorization rules to control the access.</span></p>
<h3><span style="font-weight: 400">Authorization: Controlling access</span></h3>
<p><span style="font-weight: 400">Authorization tells you what the user can do. Once a user is authenticated, Salesforce evaluates their permissions to determine which resource they can access.</span></p>
<p><span style="font-weight: 400">There are a number of mechanisms that you can put in place to control authorization.</span></p>
<h4><span style="font-weight: 400">Authorize access with OAuth scopes</span></h4>
<p><span style="font-weight: 400">The first level of authorization to access specific resources is handled by </span><a href="https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_tokens_scopes.htm&amp;type=5"><span style="font-weight: 400">OAuth scopes</span></a><span style="font-weight: 400"> when configuring an ECA.</span></p>
<p><span style="font-weight: 400">The new &#8220;Access Salesforce hosted MCP servers (mcp_api)&#8221; scope grants access to Salesforce Hosted MCP Servers. We&#8217;ve released this scope to avoid exposing the &#8220;Manage user data via APIs (api)&#8221; scope that grants full access to the Platform APIs (REST, Tooling, Metadata, etc.).</span></p>
<p><span style="font-weight: 400">As a general rule, it&#8217;s preferable to only expose a limited set of &#8220;safe&#8221; operations to agents via MCP rather than to allow full API access.</span></p>
<h4><span style="font-weight: 400">Restrict access to pre-authorized users</span></h4>
<p><span style="font-weight: 400">With the default ECA configuration, all users from your org can authenticate and access the MCP servers. You can restrict access to specific pre-authorized users by configuring an </span><a href="https://help.salesforce.com/s/articleView?id=xcloud.preauth_user_app_access_through_eca.htm&amp;type=5"><span style="font-weight: 400">app policy</span></a><span style="font-weight: 400">. This lets you select users with specific profiles or permission sets.</span></p>
<p><span style="font-weight: 400">For example, this configuration only allow users with the &#8220;MCP Client User&#8221; permission set to connect to the ECA:</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206606" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260624113407/image6_3e1252-e1782326059603.png?w=830" class="postimages" width="830" height="1000" alt="Screenshot of the ECA configuration showing how to only allow users with the &quot;MCP Client User&quot; permission set" />
			  </span>
			</p>
<h4><span style="font-weight: 400">Enforce IP restrictions</span></h4>
<p><span style="font-weight: 400">In addition to restricting the use of the ECA to specific users, you can apply IP restrictions by only specifying IP ranges to connect. These restrictions are enabled in the default ECA configuration under </span><b>App Authorization</b><span style="font-weight: 400">.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206607" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260624113454/image4_d55bd8.png?w=971" class="postimages" width="971" height="352" alt="Screenshot of the ECA configuration showing how to apply IP restrictions" />
			  </span>
			</p>
<p><span style="font-weight: 400">You can specify trusted IP ranges for all users in the </span><b>Network Access</b><span style="font-weight: 400"> setup menu or for specific user profiles.</span></p>
<h4><span style="font-weight: 400">Shorten refresh token lifetime</span></h4>
<p><span style="font-weight: 400">Once a user logs in with the ECA, they acquire an access token that is passed to all subsequent MCP operations. The token must be refreshed after its lifetime expires.</span></p>
<p><span style="font-weight: 400">The default token lasts for a year, but you can control the duration of the token lifetime and reduce it in production. You can do this to limit the risk of token theft and reuse for malicious intents. To control the token lifetime, go in the ECA configuration and look for </span><b>Refresh Token Policy</b><span style="font-weight: 400"> under App Authorization. </span><a href="https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/create-external-client-app.html"><span style="font-weight: 400">Our documentation</span></a><span style="font-weight: 400"> includes recommendations on how to improve security in this area.</span></p>
<h4><span style="font-weight: 400">Revoke access</span></h4>
<p><span style="font-weight: 400">Should you need to revoke tokens for your ECA before they expire, go to Setup, search for </span><b>OAuth Usage</b><span style="font-weight: 400">, select your ECA, and revoke individual tokens or run a bulk revoke operation.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206608" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260624113541/image5_601ace-e1782326154340.png?w=1000" class="postimages" width="1000" height="285" alt="Screenshot showing how to revoke your ECA&apos;s tokens." />
			  </span>
			</p>
<h4><span style="font-weight: 400">Activate MCP servers</span></h4>
<p><span style="font-weight: 400">By default, all MCP servers are inactive. Only </span><a href="https://help.salesforce.com/s/articleView?id=platform.api_catalog_activate_salesforce_mcp_servers.htm&amp;type=5"><span style="font-weight: 400">activate</span></a><span style="font-weight: 400"> the ones that you intend to expose to agents.</span></p>
<p><span style="font-weight: 400">For example, here we&#8217;ve only activated a custom server and two standard servers:</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206609" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260624113627/image7-e1782326199645.png?w=1000" class="postimages" width="1000" height="445" alt="Screenshot showing three active MCP servers." />
			  </span>
			</p>
<h4><span style="font-weight: 400">Annotate MCP tools</span></h4>
<p><span style="font-weight: 400">While not strictly a security measure, it&#8217;s a best practice to </span><a href="https://help.salesforce.com/s/articleView?id=platform.api_catalog_create_custom_salesforce_mcp_servers.htm&amp;type=5"><span style="font-weight: 400">annotate MCP tools</span></a><span style="font-weight: 400"> that you expose to provide hints about their behavior. Doing so lets agents know how they should use the tools. For example, should the agent ask the user for confirmation when running potentially destructive operations, such as deleting a record, or whether a tool can safely be run multiple times.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206610" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260624113723/image3_c4b552.png?w=831" class="postimages" width="831" height="722" alt="Screenshot of MCP tool annotation configuration" />
			  </span>
			</p>
<p><b>Note:</b><span style="font-weight: 400"> Support for </span><a href="https://modelcontextprotocol.io/specification/2025-06-18/schema#toolannotations"><span style="font-weight: 400">MCP tool annotations</span></a><span style="font-weight: 400"> is optional on the client side and these may not be enforced by all agents.</span></p>
<h3><span style="font-weight: 400">Permission controls: Granular access management</span></h3>
<p><span style="font-weight: 400">You cannot restrict access to a specific MCP server through the ECA configuration, but you control access to the tools that compose those servers.</span></p>
<p><span style="font-weight: 400">MCP tools run with the same permissions as the user who authenticated with the ECA. This means that our </span><a href="https://help.salesforce.com/s/articleView?id=platform.security_data_access.htm&amp;type=5"><span style="font-weight: 400">core security model</span></a><span style="font-weight: 400"> applies at all levels:</span></p>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">Object-level access (CRUD permissions)</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Field-level security (FLS) restrictions</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Record sharing rules</span></li>
</ul>
<p><span style="font-weight: 400">It’s also possible to </span><a href="https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/custom-servers.html"><span style="font-weight: 400">implement custom tools</span></a><span style="font-weight: 400"> with Agentforce, Apex, or Flow to </span><a href="https://developer.salesforce.com/docs/platform/hosted-mcp-servers/guide/security-best-practices.html"><span style="font-weight: 400">address unique security requirements</span></a><span style="font-weight: 400">. If you choose this path, always follow </span><a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_perms_enforcing.htm"><span style="font-weight: 400">security best practices</span></a><span style="font-weight: 400">.</span></p>
<p><span style="font-weight: 400">Be sure to work with permission sets to protect sensitive operations and follow the principle of least privilege. Grant only the permissions that users need to do their jobs. Review permissions regularly and remove access that&#8217;s no longer required.</span></p>
<p>Also, test permissions before deploying to production. For example, run Apex tests and Flow tests on your MCP tools with the <code>runAs</code> <a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_tools_runas.htm"><u>method</u></a> to simulate the behavior of users with different access levels.</p>
<h3><span style="font-weight: 400">Logging: Tracking access</span></h3>
<p><span style="font-weight: 400">Logging creates an audit trail of who accessed what and when. This is essential for security monitoring, compliance, and troubleshooting.</span></p>
<p><span style="font-weight: 400">All actions that are performed by the MCP tools are attributed to the user that connected to the ECA in audit trails. Salesforce automatically logs MCP server activity using Event Monitoring.</span></p>
<p>To access the logs, navigate to <b>Setup</b> and search for <b>Event Log File Browser</b>. Filter Event Type on &#8220;API Total Usage&#8221;. You can identify MCP traffic by filtering the event log CSV files for rows where the <code>API_CLIENT_CATEGORY</code> column matches <code>SALESFORCE_HOSTED_MCP</code>. You&#8217;ll see the users that called the MCP tools and the affected objects (entities) among other details.</p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206611" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260624113811/image1_7551df-e1782326303548.png?w=1000" class="postimages" width="1000" height="234" alt="Screenshot of an event log filtered to show MCP tool calls" />
			  </span>
			</p>
<p>Review logs regularly. Look for errors thanks to <code>STATUS_CODE</code> or unexpected access patterns with <code>USER_NAME</code> or <code>CLIENT_IP</code>. These can indicate security issues or misconfigured permissions.</p>
<h2><span style="font-weight: 400">Conclusion</span></h2>
<p><span style="font-weight: 400">In this post, we’ve reviewed how to secure Salesforce Hosted MCP Servers, and we&#8217;ve covered all of the components that form this layered security architecture, including:</span></p>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">Authentication verifies identity</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Authorization controls what tools users can access</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Permission controls enforce granular data access</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Logging creates an audit trail for compliance and security monitoring</span></li>
</ul>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206612" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260624113847/image8-e1782326340691.png?w=1000" class="postimages" width="1000" height="490" alt="Diagram that summarizes the security architecture for MCP servers and tools" />
			  </span>
			</p>
<p><span style="font-weight: 400">It&#8217;s now up to you to implement these security best practices and protect your data while shipping powerful MCP tools that agents can use.</span></p>
<h2><span style="font-weight: 400">Resources</span></h2>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">Documentation: </span><a href="https://developer.salesforce.com/docs/platform/hosted-mcp-servers"><span style="font-weight: 400">Salesforce Hosted MCP Servers</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">Documentation: </span><a href="https://help.salesforce.com/s/articleView?id=platform.api_catalog_manage_mcp_servers.htm"><span style="font-weight: 400">Manage MCP Servers in API Catalog</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">Documentation: </span><a href="https://help.salesforce.com/s/articleView?id=xcloud.external_client_apps.htm&amp;type=5"><span style="font-weight: 400">External Client Apps</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">Documentation: </span><a href="https://help.salesforce.com/s/articleView?id=sf.perm_sets_overview.htm"><span style="font-weight: 400">Permission Sets</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">GitHub: </span><a href="https://github.com/forcedotcom/mcp-hosted/wiki"><span style="font-weight: 400">Community Wiki</span></a></li>
</ul>
<h2><span style="font-weight: 400">About the author</span></h2>
<p><b>Philippe Ozil</b><span style="font-weight: 400"> is a Principal Developer Advocate at Salesforce, where he focuses on the Salesforce Platform. He writes technical content and speaks frequently at conferences. He is a full-stack developer and enjoys working with APIs, DevOps, robotics, and VR projects. Follow him on </span><a href="https://x.com/PhilippeOzil"><span style="font-weight: 400">X</span></a><span style="font-weight: 400">, </span><a href="https://www.linkedin.com/in/philippeozil/"><span style="font-weight: 400">LinkedIn</span></a><span style="font-weight: 400">, and </span><a href="https://bsky.app/profile/pozil.bsky.social"><span style="font-weight: 400">Bluesky</span></a><span style="font-weight: 400">, and check out his </span><a href="https://github.com/pozil"><span style="font-weight: 400">GitHub projects</span></a><span style="font-weight: 400">.</span></p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/06/how-to-secure-salesforce-hosted-mcp-servers">How to Secure Salesforce Hosted MCP Servers</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://developer.salesforce.com/blogs/2026/06/how-to-secure-salesforce-hosted-mcp-servers/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206595</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260624110231/SingleHeadshot-6-e1782324168910.png?w=1000" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260624110231/SingleHeadshot-6-e1782324168910.png?w=1000" medium="image" />
	</item>
		<item>
		<title>Build Continuous Planning Systems in Agentforce Financial Services</title>
		<link>https://developer.salesforce.com/blogs/2026/06/build-continuous-planning-systems-in-agentforce-financial-services</link>
		<comments>https://developer.salesforce.com/blogs/2026/06/build-continuous-planning-systems-in-agentforce-financial-services#respond</comments>
		<pubDate>Thu, 25 Jun 2026 15:00:31 +0000</pubDate>
		<dc:creator><![CDATA[Vignesh Damodharan]]></dc:creator>
				<category><![CDATA[Agentforce]]></category>
		<category><![CDATA[Apex]]></category>
		<category><![CDATA[App Development]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Account Planning]]></category>
		<category><![CDATA[Business Relationship Plan]]></category>
		<category><![CDATA[data model]]></category>
		<category><![CDATA[Document Generation]]></category>
		<category><![CDATA[financial services]]></category>
		<category><![CDATA[salesforce]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206583</guid>
		<description><![CDATA[<p>Replace static annual planning cycles with continuous account tracking using the Business Relationship Plan data model, admin configurations, and custom Apex logic.</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/06/build-continuous-planning-systems-in-agentforce-financial-services">Build Continuous Planning Systems in Agentforce Financial Services</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p><span style="font-weight: 400">Static, siloed data makes it challenging for financial services organizations and their client relationship managers to accurately, and efficiently develop their annual account plans. </span><a href="https://help.salesforce.com/s/articleView?id=ind.fsc_admin_business_relationship_plan.htm&amp;type=5"><span style="font-weight: 400">Business Relationship Plan (BRP) in Agentforce Financial Services</span></a><span style="font-weight: 400"> provides a robust data model for continuous account planning, replacing static annual planning cycles. With BRP, organizations can track goals in real time and make faster decisions throughout the year.</span></p>
<p><span style="font-weight: 400">Whether adapting to regulatory shifts or launching new products, account teams can use BRP to implement fresh metrics in minutes, surfacing real-time, actionable insights for every client relationship manager. In addition, BRP supports organizational agility by shifting logic ownership from engineering tickets to a simpler admin configuration. Clear extension points enable developers to customize BRP further using Flow, Apex, or Lightning web components.</span></p>
<p><span style="font-weight: 400">In this blog post, we&#8217;ll walk through the BRP architecture and the core data model. We’ll then demonstrate how admins can configure BRP , and how business users can set up and use the system. Finally, we’ll explore how to extend BRP using Apex business logic and document generation.</span></p>
<h2><span style="font-weight: 400">What Business Relationship Plan is (and why it matters)</span></h2>
<p><span style="font-weight: 400">Business Relationship Plan is the layer in </span><a href="https://help.salesforce.com/s/articleView?id=ind.fsc_agents_overview.htm&amp;type=5"><span style="font-weight: 400">Agentforce Financial Services</span></a><span style="font-weight: 400"> that sits on top of the </span><a href="https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_accountplan.htm"><span style="font-weight: 400">AccountPlan</span></a><span style="font-weight: 400"> object in Salesforce. It gives organizations a structure for plan records, objectives, measures, and tasks, and it allows them to extend this model with Flow, Apex, and UI components.</span></p>
<p><span style="font-weight: 400">At a high level, BRP connects:</span></p>
<ul>
<li style="font-weight: 400"><b>Plan</b><span style="font-weight: 400">: Account-level strategy record</span></li>
<li style="font-weight: 400"><b>Objectives</b><span style="font-weight: 400">: Prioritized outcomes with owners</span></li>
<li style="font-weight: 400"><b>Measures</b><span style="font-weight: 400">: Key performance indicators (KPIs) and targets</span></li>
<li style="font-weight: 400"><b>Action Plan</b><span style="font-weight: 400">: Action items tied to objectives</span></li>
<li style="font-weight: 400"><b>Visibility</b><span style="font-weight: 400">: Progress tracking across accounts</span></li>
</ul>
<p><span style="font-weight: 400">When we enable </span><a href="https://help.salesforce.com/s/articleView?id=ind.fsc_eac_setup_einstein_activity_capture_for_financial_services_cloud.htm&amp;type=5"><span style="font-weight: 400">Einstein</span></a><span style="font-weight: 400"> features, we can also add interaction summaries for better context before meetings.</span></p>
<h2><span style="font-weight: 400">Account Plans vs. BRP: What to use when</span></h2>
<p><span style="font-weight: 400">While </span><b>Account Plans</b><span style="font-weight: 400"> serve standard, linear management needs, </span><b>Business Relationship Plan</b><span style="font-weight: 400"> delivers a highly extensible architecture specifically engineered for sophisticated, multi-outcome strategies and deep platform integration.</span></p>
<table>
<tbody>
<tr>
<td><b>Topic</b></td>
<td><b>Account Plans</b></td>
<td><b>Business Relationship Plans</b></td>
</tr>
<tr>
<td><span style="font-weight: 400">Standard objects</span></td>
<td><span style="font-weight: 400">Yes</span></td>
<td><span style="font-weight: 400">Yes</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">Strategic Tracker component</span></td>
<td><span style="font-weight: 400">Yes</span></td>
<td><span style="font-weight: 400">Yes</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">Flexcard Selector component for 360 Information</span></td>
<td><span style="font-weight: 400">No</span></td>
<td><span style="font-weight: 400">Yes</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">Objectives component with measures</span></td>
<td><span style="font-weight: 400">Yes (1:1)</span></td>
<td><span style="font-weight: 400">Yes (1:N)</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">Einstein summary</span></td>
<td><span style="font-weight: 400">No</span></td>
<td><span style="font-weight: 400">Yes</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">Action Plans integration</span></td>
<td><span style="font-weight: 400">Limited </span></td>
<td><span style="font-weight: 400">Yes</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">Omniscript support</span></td>
<td><span style="font-weight: 400">No</span></td>
<td><span style="font-weight: 400">Yes</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">OOTB prompt templates</span></td>
<td><span style="font-weight: 400">No</span></td>
<td><span style="font-weight: 400">Yes</span></td>
</tr>
</tbody>
</table>
<h2><span style="font-weight: 400">Business Relationship Plan architecture at a glance</span></h2>
<p><span style="font-weight: 400">The architecture of Business Relationship Plan spans four layers: </span><b>Data</b><span style="font-weight: 400"> (Plan, Objective, Measure records), </span><b>Experience</b><span style="font-weight: 400"> (Lightning pages and Flexcards), </span><b>Orchestration</b><span style="font-weight: 400"> (Flow, Apex, Omniscript), and </span><b>Insight</b><span style="font-weight: 400"> (Einstein summaries and analytics). </span></p>
<ol>
<li style="font-weight: 400"><span style="font-weight: 400">  </span><b>Data layer:</b><span style="font-weight: 400"> Plan, Objective, Measure, and Task records with standard and custom fields</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">  </span><b>Experience layer: </b><span style="font-weight: 400">Lightning pages, Flexcards, and Strategic Tracker components</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">  </span><b>Orchestration layer:</b><span style="font-weight: 400"> Flow, Omniscript, and Apex automation</span></li>
<li style="font-weight: 400"><span style="font-weight: 400"> </span><b> Insight layer: </b><span style="font-weight: 400">Einstein summaries and dashboard analytics</span></li>
</ol>
<p><span style="font-weight: 400">The diagram below shows how data flows between BRP’s four layers and their components: the Data layer with sObjects, the Experience layer with Lightning components, the Orchestration layer with Flow and Apex, and the Insight layer with Einstein and dashboards.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206585" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260624100953/image1_75eec1-e1782321006742.png?w=1000" class="postimages" width="1000" height="847" alt="Architecture diagram showing BRP’s four layers" />
			  </span>
			</p>
<h2><span style="font-weight: 400">BRP data model: Core objects and relationships</span></h2>
<p><span style="font-weight: 400">Business Relationship Plan offers a technical structure for Account Plan records, objectives, measures, and action plans, connecting client account goals directly to Financial Deal, Opportunities, Cases, and Contacts within the Salesforce data model.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206586" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260624101047/image6-e1782321060644.png?w=883" class="postimages" width="883" height="1000" alt="Diagram showing the components of the BRP architecture" />
			  </span>
			</p>
<h3><span style="font-weight: 400">Core objects</span></h3>
<p><span style="font-weight: 400">While each of the Account Plan entities contains numerous fields, we’ll focus here on the fundamental fields that are essential across all entities to help you understand the core data structure.</span></p>
<p><b><code>AccountPlan</code></b>: The root planning object.</p>
<ul>
<li>Standard fields: <code>Name, AccountId, Status, StartDate, EndDate</code></li>
<li>Key relationships:<code> Account</code> (lookup),<code> Owner</code> (lookup)</li>
</ul>
<p><b><code>AccountPlanObjectiveCategory</code></b>: Categories for classifying objectives.</p>
<ul>
<li>Standard fields: <code>Name, Description, StartDate, EndDate, IsActive</code></li>
</ul>
<p><b><code>AccountPlanObjective</code></b>: Strategic goals within a plan.</p>
<ul>
<li>Standard fields: <code>Name, AccountPlanId, Priority, Status, Owner, StartDate, EndDate, Description</code></li>
<li>Key relationships:<code> AccountPlan</code> (master-detail), <code>Owner</code> (lookup), <code>AccountPlanObjCategory</code> (lookup)</li>
</ul>
<p><b><code>AccountPlanObjectiveMeasure</code></b>: Quantifiable KPIs tracking objective progress.</p>
<ul>
<li>Standard fields: <code>Name, AccountPlanObjectiveId, ValueType, TargetValue, CurrentValue</code></li>
<li>Key relationships:<code> AccountPlanObjective</code> (master-detail), <code>AccountPlanObjMeasCalcDef</code> (lookup)</li>
</ul>
<p><b><code>AccountPlanObjectiveMeasureRela</code></b>: Links measures to related records.</p>
<ul>
<li>Standard fields:<code> Name, AccountPlanObjectiveMeasureId, ReferenceRecordId</code></li>
<li>Key relationships: <code>AccountPlanObjectiveMeasure</code> (master-detail), <code>ReferenceRecord</code> (multi-lookup to Opportunity, Financial Deal, Case, Contact, Campaign, etc.)</li>
</ul>
<p><b><code>ActionPlan</code></b>: Structured task-based execution plans.</p>
<ul>
<li>Standard fields: <code>Name, ActionPlanType, StartDate, EndDate</code></li>
<li>Key relationships: Target (multi-lookup)</li>
</ul>
<p><b><code>ActionPlanItem</code></b>: Individual tasks within an action plan.</p>
<ul>
<li>Standard fields: <code>Name, ActionPlanId, IsRequired, DisplayOrder, DependencyStatus</code></li>
<li>Key relationships: <code>ActionPlan</code> (master-detail), <code>ActionPlanItem</code> (multi-lookup)</li>
</ul>
<p><b><code>Task</code></b>: Action items tied to objectives.</p>
<ul>
<li>Standard fields: <code>Subject, Status, Priority, Due Date, Assigned To</code></li>
<li>Key relationships: What (lookup to Objective)</li>
</ul>
<h3><span style="font-weight: 400">Sample SOQL query</span></h3>
<p><span style="font-weight: 400">The query below retrieves active plans with nested objectives and measures, which is useful for building custom dashboards.</span></p>
<pre language="sql">SELECT Id, Name, Account.Name, Status, StartDate, EndDate,                                                                                                                                                                                                                                                                                                                                                                                
      (SELECT Id, Name, Priority, Status, Owner.Name,
          (SELECT Id, Name, TargetValue, CurrentValue                                                                                                                                                                                                                                                                                                                                                         
           FROM AccountPlanObjectiveMeasures)                                                                                                                                                                                                                                                                                                                                                                                               
       FROM AccountPlanObjectives                                                                                                                                                                                                                                                                                                                                                                                                           
       ORDER BY Priority, CreatedDate)                                                                                                                                                                                                                                                                                                                                                                                                      
  FROM AccountPlan                                                                                                                                                                                                                                                                                                                                                                                                                          
  WHERE Status = 'Active'                                                                                                                                                                                                                                                                                                                                                                                                                   
    AND Account.Industry = 'Banking'                                                                                                                                                                                                                                                                                                                                                                                                        
  ORDER BY StartDate DESC                                                                                                                                                                                                                                                                                                                                                                                                                   
  LIMIT 100
</pre>
<h2><span style="font-weight: 400">Calculation definitions in Business Relationship Plan</span></h2>
<p><span style="font-weight: 400">A </span><a href="https://help.salesforce.com/s/articleView?id=sales.account_plans_objective_measures.htm&amp;type=5"><b>Calculation Definition</b></a><span style="font-weight: 400"> is a core configuration record in BRP that defines the logic for platform-led aggregations. It establishes a technical framework with three fundamental pillars:</span></p>
<ul>
<li style="font-weight: 400"><b>Target object</b><span style="font-weight: 400">: Identify the specific record type for data aggregation</span></li>
<li style="font-weight: 400"><b>Target field</b><span style="font-weight: 400">: Specify the numeric or currency value to be rolled up</span></li>
<li style="font-weight: 400"><b>Rollup type</b><span style="font-weight: 400">: Define the mathematical operation (Sum, Count, Min, or Max)</span></li>
</ul>
<p><span style="font-weight: 400">Furthermore, users can implement conditional logic to filter the underlying data set, ensuring that only qualifying records contribute to the final metric. Once this setup is complete, client relationship managers can leverage these definitions across multiple Account Plan measures without writing a single line of code.</span></p>
<h3><span style="font-weight: 400">Summary of roles</span></h3>
<table>
<tbody>
<tr>
<td><b>Process Step</b></td>
<td><b>Owner</b></td>
<td><b>Key Outcome</b></td>
</tr>
<tr>
<td><span style="font-weight: 400">Define logic</span></td>
<td><span style="font-weight: 400">Admin</span></td>
<td><span style="font-weight: 400">Reusable Calculation Definition</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">Activation</span></td>
<td><span style="font-weight: 400">Admin</span></td>
<td><span style="font-weight: 400">Availability in Measure UI</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">Plan setup</span></td>
<td><span style="font-weight: 400">User</span></td>
<td><span style="font-weight: 400">Strategic measure creation</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">Data mapping</span></td>
<td><span style="font-weight: 400">User</span></td>
<td><span style="font-weight: 400">Associated related records</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">Orchestration</span></td>
<td><span style="font-weight: 400">Platform</span></td>
<td><span style="font-weight: 400">Automated nightly rollups</span></td>
</tr>
</tbody>
</table>
<p><span style="font-weight: 400">This collaborative framework ensures that while admins govern the formula, the platform manages the data, and users focus on results. That is the power of </span><b>Calculation Definitions</b><span style="font-weight: 400">.</span></p>
<p><span style="font-weight: 400">Let’s now take a look at the steps an admin would take to set up calculation definitions in Agentforce Financial Services. Once set up, we’ll then look at how a business user would use the system.</span></p>
<h2><span style="font-weight: 400">The admin experience: Configuring the engine</span></h2>
<p><span style="font-weight: 400">The initial setup phase creates a reusable asset for the entire organization. Once published, these definitions become standard options for all team members during measure creation. </span></p>
<p><span style="font-weight: 400">As an admin, you would follow these steps to configure BRP.</span></p>
<h3><span style="font-weight: 400">Step 1: Access configuration</span></h3>
<p><span style="font-weight: 400">Navigate to </span><b>Setup</b><span style="font-weight: 400"> -&gt; </span><b>Sales Account Plans </b><span style="font-weight: 400">and you will see the calculation definition section. You will see both out-of-the-box (OOTB) logic and custom configurations tailored to your specific business requirements.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206587" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260624101243/image2_37aa44-e1782321182568.png?w=1000" class="postimages" width="1000" height="497" alt="Screenshot of the Configure Plans for Financial Services start screen" />
			  </span>
			</p>
<h3><span style="font-weight: 400">Step 2: Define the data parameters</span></h3>
<p><span style="font-weight: 400">Click on </span><b>New Calculation Definition</b><span style="font-weight: 400"> and populate the following essential fields:</span></p>
<ul>
<li style="font-weight: 400"><b>Identity</b><span style="font-weight: 400">: Assign a Name and unique API Name for the definition</span></li>
<li style="font-weight: 400"><b>Context</b><span style="font-weight: 400">: Provide a clear description, so end users understand what the metric represents</span></li>
<li style="font-weight: 400"><b>Source</b><span style="font-weight: 400">: Select the Target Object (e.g., Financial Deal) and the corresponding Target Field</span></li>
<li style="font-weight: 400"><b>Logic</b><span style="font-weight: 400">: Choose the Rollup Type; the platform automatically infers the data type from your field selection</span></li>
</ul>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206588" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260624101354/image5_c02a90.png?w=949" class="postimages" width="949" height="918" alt="Screenshot of the New Calculation Definition dialog box showing rollup criteria" />
			  </span>
			</p>
<h3><span style="font-weight: 400">Step 3: Implement conditional filters</span></h3>
<p><span style="font-weight: 400">Admins can apply up to five </span><b>conditions</b><span style="font-weight: 400"> to refine the calculation scope. For example, you might exclude records where the status is &#8220;Inactive&#8221; or filter by specific transaction thresholds to ensure metric accuracy.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206589" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260624101439/image4.png?w=913" class="postimages" width="913" height="898" alt="Screenshot of the New Calculation Definition dialog box showing conditional filters" />
			  </span>
			</p>
<h3><span style="font-weight: 400">Step 4: Lifecycle Management</span></h3>
<p><span style="font-weight: 400">New definitions begin in </span><b>Draft</b><span style="font-weight: 400"> mode for review. Transitioning to </span><b>Active</b><span style="font-weight: 400"> status locks the core configuration to prevent unintended changes to live metrics, ensuring consistency across quarterly planning cycles.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206590" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260624101533/image3_9c1ecb-e1782321344245.png?w=1000" class="postimages" width="1000" height="370" alt="Screenshot showing button to activate the calculation definition" />
			  </span>
			</p>
<h2><span style="font-weight: 400">The business user experience: Operationalizing strategy</span></h2>
<p><span style="font-weight: 400">Once activated, these technical definitions are handed off to client relationship managers to drive daily business outcomes.</span></p>
<p><span style="font-weight: 400">Business users would follow these steps:</span></p>
<h3><span style="font-weight: 400">Step 1: Establish the plan hierarchy</span></h3>
<p><span style="font-weight: 400">Users begin by creating an </span><b>Account Plan</b><span style="font-weight: 400"> and defining high-level </span><b>Objectives</b><span style="font-weight: 400">, such as increasing portfolio retention or growing fee income.</span></p>
<h3><span style="font-weight: 400">Step 2: Link measures to logic</span></h3>
<p><span style="font-weight: 400">For each Objective, the user adds a </span><b>measure</b><span style="font-weight: 400">. They define the name and target value, then select the appropriate </span><b>calculation definition</b><span style="font-weight: 400"> from the dropdown to assign the aggregation logic.</span></p>
<h3><span style="font-weight: 400">Step 3: Associate records </span></h3>
<p>The user manually associates relevant records (e.g., Financial Deals) using the <b><code>AccountPlanObjectiveMeasureRela</code></b><b> </b>records. This flexible mapping allows single records to contribute to multiple plans without limit.</p>
<h3><span style="font-weight: 400">Step 4: Automate orchestration</span></h3>
<p><span style="font-weight: 400">The platform executes a nightly scheduled job that processes these associations, applies admin-defined conditions, and updates the </span><b>Current Value</b><span style="font-weight: 400"> field automatically, ensuring that fresh data is available every morning.</span></p>
<h2><span style="font-weight: 400">Architecting for performance: The daily cadence</span></h2>
<p><span style="font-weight: 400">Agentforce Financial Services utilizes a batch approach for these calculations to maintain optimal system performance. This design ensures that today&#8217;s updates to deals or record associations are consistently reflected in the next day&#8217;s planning metrics without creating unnecessary overhead.</span></p>
<h3><span style="font-weight: 400">Workflow example: Tracking Q3 deal revenue</span></h3>
<p><span style="font-weight: 400">Consider a scenario where a financial advisor tracks transaction revenue for a high-net-worth client.</span></p>
<p><b>Phase 1: Admin configuration</b></p>
<ol>
<li style="font-weight: 400"><span style="font-weight: 400">Admin creates an &#8220;Active Deal Transaction Value&#8221; definition targeting the </span><b>Financial Deal</b><span style="font-weight: 400"> object.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Logic is set to </span><b>Sum</b><span style="font-weight: 400"> the transaction field with a filter for active status.</span></li>
</ol>
<p><b>Phase 2: Execution</b></p>
<ol>
<li style="font-weight: 400"><b>Monday</b><span style="font-weight: 400">: The advisor sets up the Account Plan and links eight deals to a new measure.</span></li>
<li style="font-weight: 400"><b>Tuesday</b><span style="font-weight: 400">: The system reflects a $1.45M current value automatically.</span></li>
<li style="font-weight: 400"><b>Quarter-End</b><span style="font-weight: 400">: As new deals close and are associated, the platform tracks the revenue growth until the $2M goal is surpassed.</span></li>
</ol>
<h2><span style="font-weight: 400">Extend Business Relationship Plan with Apex</span></h2>
<p><span style="font-weight: 400">For complex business logic, developers can use Apex to extend BRP functionality. This allows you to implement sophisticated patterns beyond Flow capabilities, such as a nightly scheduled job that computes weighted health scores (on a 0–100 scale) for objectives by analyzing progress from baseline to target. Such automation can programmatically refresh status labels like On Track, At Risk, or Off Track, while utilizing batchable Apex to maintain performance for large-scale deployments exceeding 2,000 records.</span></p>
<h3><span style="font-weight: 400">Prerequisites</span></h3>
<p><span style="font-weight: 400">Before implementing Apex extensions for BRP, ensure that your org meets these requirements:</span></p>
<ul>
<li><b>Salesforce Edition:</b> Enterprise Edition or higher</li>
<li><b>Financial Services Cloud license:</b> Active FSC license</li>
<li><b>Agentforce Financial Services:</b> Enabled in org settings</li>
<li><b>Permission sets:</b> <code>AccountPlan</code> object permissions (Read, Create, Edit) assigned to users</li>
<li><b>Omnistudio runtime</b>: Enabled for Flexcards and Omniscript functionality</li>
<li><b>Custom field access:</b> Ability to create custom fields on <code>AccountPlanObjective</code> and <code>AccountPlanObjectiveMeasure</code> objects</li>
</ul>
<p><span style="font-weight: 400">The following example shows how to customize BRP to track objective health scores.</span></p>
<h3><span style="font-weight: 400">Example: Calculate objective health score</span></h3>
<p><span style="font-weight: 400">To prepare your organization for the Apex calculation, create these custom fields:</span></p>
<ul>
<li><b>On </b><b><code>AccountPlanObjectiveMeasure</code></b><b>:</b>
<ul>
<li><code>BaselineValue__c</code> (Text, 255): Stores the starting value for progress calculation</li>
<li><code>Weight__c</code> (Number, 5,2): Defines the relative importance (weight) of the measure in the objective&#8217;s health score</li>
</ul>
</li>
<li><b>On </b><b><code>AccountPlanObjective</code></b><b>:</b>
<ul>
<li><code>HealthScore__c</code> (Number, 5,2): Stores the calculated weighted health score (0–100)</li>
<li><b>Status picklist update:</b> To use the<code> determineHealthStatus</code> method, add the values <b>On Track</b>, <b>At Risk</b>, and <b>Off Track</b> to the <code>AccountPlanObjective.Status</code> picklist</li>
</ul>
</li>
<li><b><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Crucial Data Note:</b> Ensure that the <code>ValueType</code> field (Number, Currency, or Percent) is set on <code>AccountPlanObjectiveMeasure</code> records before <code>TargetValue</code> and <code>CurrentValue</code> can be persisted.</li>
</ul>
<pre language="java">/**
 * Computes a weighted health score per Account Plan Objective from its measures,
 * then sets HealthScore__c and a text Status from score bands.
 */
public class BRPObjectiveHealthCalculator {

    /**
     * Loads objectives (and related measures), aggregates progress by weight,
     * and updates objectives that have at least one valid weighted measure.
     *
     * @param setOfObjectiveIds Ids of AccountPlanObjective records to recalculate; no-op if null/empty.
     */
    public static void calculateHealthScores(Set setOfObjectiveIds) {
        if (setOfObjectiveIds == null || setOfObjectiveIds.isEmpty()) {
            return;
        }

        // Child subquery: FROM clause must be the child relationship API name + __r (verify in object manager).
        List objectives = [
            SELECT Id, Name, HealthScore__c, Status,
                   (SELECT Id,
                           BaselineValue__c,
                           TargetValue,
                           CurrentValue,
                           Weight__c
                    FROM AccountPlanObjectiveMeasures)
            FROM AccountPlanObjective
            WHERE Id IN :setOfObjectiveIds
        ];

        // Only objectives we actually change are DML’d to avoid unnecessary updates/triggers.
        List objectivesToUpdate = new List();

        for (AccountPlanObjective obj : objectives) {
            // Running totals for weighted average of per-measure progress (0–100 each).
            Decimal weightedScore = 0;
            Decimal totalWeight = 0;

            for (AccountPlanObjectiveMeasure measure : obj.AccountPlanObjectiveMeasures) {
                if (isValidMeasure(measure)) {
                    Decimal progress = calculateProgress(measure);
                    // Null weight defaults to 1 so the measure still counts equally if unspecified.
                    Decimal weight = measure.Weight__c != null ? measure.Weight__c : 1;

                    weightedScore += progress * weight;
                    totalWeight += weight;
                }
            }

            // Skip update when no valid measures contributed weight (avoids divide-by-zero and blank scores).
            if (totalWeight &gt; 0) {
                // Weighted average progress, expressed on a 0–100 scale for storage/display.
                obj.HealthScore__c = (weightedScore / totalWeight);
                obj.Status = determineHealthStatus(obj.HealthScore__c);
                objectivesToUpdate.add(obj);
            }
        }

        if (!objectivesToUpdate.isEmpty()) {
            update objectivesToUpdate;
        }
    }

    /**
     * A measure is included only when baseline, target, and current are all present,
     * so progress and comparisons are well-defined.
     */
    private static Boolean isValidMeasure(AccountPlanObjectiveMeasure measure) {
        return measure.BaselineValue__c != null
            &amp;&amp; measure.TargetValue != null
            &amp;&amp; measure.CurrentValue != null;
    }

    /**
     * Linear progress from baseline toward target, as a percentage (0–100).
     * Values are coerced with Decimal.valueOf in case the fields are numeric types other than Decimal.
     */
    private static Decimal calculateProgress(AccountPlanObjectiveMeasure measure) {
        Decimal baseline = Decimal.valueOf(measure.BaselineValue__c);
        Decimal target = Decimal.valueOf(measure.TargetValue);
        Decimal current = Decimal.valueOf(measure.CurrentValue);

        // Degenerate case: no movement defined; treat as fully achieved to avoid division by zero.
        if (target == baseline) {
            return 100;
        }

        // Raw % along the line from baseline to target; can exceed 0–100 before clamping.
        Decimal progress = ((current - baseline) / (target - baseline)) * 100;
        // Clamp so a single outlier measure cannot push the aggregate beyond 0–100 contribution.
        return Math.min(Math.max(progress, 0), 100);
    }

    /**
     * Maps stored score to a simple status label for reporting/UI.
     */
    private static String determineHealthStatus(Decimal score) {
        if (score &gt;= 80) {
            return 'On Track';
        }
        if (score &gt;= 60) {
            return 'At Risk';
        }
        return 'Off Track';
    }
}
</pre>
<p><b>Usage</b><span style="font-weight: 400">: Call this class from a scheduled Apex job to recalculate health scores nightly.</span></p>
<pre language="java">public class BRPHealthScoreScheduler implements Schedulable {
    public void execute(SchedulableContext ctx) {
       Set objectiveIds = new Set();
      
       for (AccountPlanObjective obj : [
           SELECT Id
           FROM AccountPlanObjective
           WHERE Status = 'In Progress'
           AND AccountPlan.Status = 'Active'
       ]) {
           objectiveIds.add(obj.Id);
       }
      
       if (!objectiveIds.isEmpty()) {
           BRPObjectiveHealthCalculator.calculateHealthScores(objectiveIds);
       }
    }
}
</pre>
<p>Schedule with: <code>System.schedule('BRP Health Score Calculator', '0 0 2 * * ?', new BRPHealthScoreScheduler());</code><span>.</span></p>
<p>Note: <span>For orgs with more than 2,000 active objectives, refactor this into a </span><code>Database.Batchable</code><span> class with a batch size of 200. The </span><code>calculateHealthScores</code><span> method already accepts a </span><code>Set&lt;Id&gt;</code><span>, so the </span><code>batchable execute()</code><span> method can pass each batch directly.</span></p>
<pre language="java">global class ObjectiveHealthScoreBatch implements Database.Batchable {

    global Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator(
            'SELECT Id FROM AccountPlanObjective'
        );
    }

    global void execute(Database.BatchableContext bc, List scope) {
        Set objectiveIds = new Map&lt;Id, SObject&gt;(scope).keySet();
        calculateHealthScores(objectiveIds); // already accepts Set
    }

    global void finish(Database.BatchableContext bc) {
        // optional: send notification, log results
    }
}
</pre>
<h2><span style="font-weight: 400">Extend Business Relationship Plan with Document Generation</span></h2>
<p><a href="https://help.salesforce.com/s/articleView?id=ind.sf_docgen_overview_one.htm&amp;type=5"><span style="font-weight: 400">Salesforce Document Generation</span></a><span style="font-weight: 400"> enables organizations to automatically create Word documents and PowerPoint presentations from Account Plan data. By placing the </span><a href="https://help.salesforce.com/s/articleView?id=ind.fsc_admin_tear_sheets_parent.htm&amp;type=5"><span style="font-weight: 400">Summary Documents</span></a><span style="font-weight: 400"> component on the Account Plan record page, developers can allow users to generate documents on-demand from pre-built templates with merge fields and conditional logic. Generated documents pull live data (objectives, measures, activities, related records) and are stored in Salesforce, where they can be:</span></p>
<ul>
<li><b>Exported</b><span style="font-weight: 400">: Download as native .docx/.pptx formats or convert to PDF </span></li>
<li><span style="font-weight: 400"><b>Shared</b>: Email as attachments or share via public/private links</span></li>
<li><span style="font-weight: 400"><b>Printed</b>: Download and print for client meetings or internal reviews</span></li>
<li><span style="font-weight: 400"><b>Archived</b>: Store for compliance and audit trails<br />
</span></li>
</ul>
<p><span style="font-weight: 400">This simple extension adds a lot of value and can be used for executive summaries, quarterly business reviews, and stakeholder presentations.</span></p>
<h2><span style="font-weight: 400">Best practices for developers</span></h2>
<ul>
<li style="font-weight: 400"><b>Review existing OOTB capabilities first: </b><span style="font-weight: 400">Before building custom components, check available features like Flexcard Selector, Objectives Component, Action Plans, and Summary Documents for complete out-of-the-box functionality to avoid duplicate development</span></li>
<li style="font-weight: 400"><b>Keep objective definitions specific and time-bound</b><span style="font-weight: 400">: Use validation rules to enforce date ranges and clear naming conventions</span></li>
<li style="font-weight: 400"><b>Limit KPIs to meaningful indicators</b><span style="font-weight: 400">: Avoid measure proliferation; focus on three to five key measures per objective</span></li>
<li style="font-weight: 400"><b>Build automation for repetitive tasks</b><span style="font-weight: 400">: Use Flow for measure reminders and status updates</span></li>
</ul>
<h2><span style="font-weight: 400">Conclusion</span></h2>
<p><span style="font-weight: 400">When essential account data is static and siloed, annual account planning becomes more challenging and can easily fail.Business Relationship Plan gives financial services organizations a technical and operational model that they can run every week. With the right data model, UI, and automation, account teams can track goals in real time, act faster, and be more productive.</span></p>
<p><span style="font-weight: 400">For developers, BRP provides a solid foundation with clear extension points. Whether you&#8217;re building Flow automation, Apex business logic, or custom LWC components, the platform supports continuous planning workflows that replace static annual planning cycles.</span></p>
<h2><span style="font-weight: 400">Resources</span></h2>
<ul>
<li style="font-weight: 400"><a href="https://help.salesforce.com/s/articleView?id=ind.fsc_admin_business_relationship_plan.htm&amp;type=5"><span style="font-weight: 400">Business Relationship Plan Overview</span></a></li>
<li style="font-weight: 400"><a href="https://help.salesforce.com/s/articleView?id=ind.fsc_admin_business_relationship_plan_enable.htm&amp;type=5"><span style="font-weight: 400">Enable Business Relationship Plan</span></a></li>
<li style="font-weight: 400"><a href="https://help.salesforce.com/s/articleView?id=ind.fsc_admin_business_relationship_plan_setup.htm&amp;language=en_US&amp;type=5"><span style="font-weight: 400">Business Relationship Plan Setup Guide</span></a></li>
<li style="font-weight: 400"><a href="https://help.salesforce.com/s/articleView?id=ind.fsc_admin_business_relationship_plan_add_flexcard_component.htm&amp;type=5"><span style="font-weight: 400">Add FlexCard Component</span></a></li>
<li style="font-weight: 400"><a href="https://help.salesforce.com/s/articleView?id=ind.fsc_admin_business_relationship_plan_configure_flexipage2.htm&amp;language=en_US&amp;type=5"><span style="font-weight: 400">Configure the Pre-Built Account Plan Lightning Page </span></a></li>
<li style="font-weight: 400"><a href="https://help.salesforce.com/s/articleView?id=ind.fsc_admin_business_relationship_plan_configure_fields.htm&amp;language=en_US&amp;type=5"><span style="font-weight: 400">Configure Fields Specific to BRP</span></a></li>
<li style="font-weight: 400"><a href="https://help.salesforce.com/s/articleView?id=ind.fsc_admin_business_relationship_plan_manage_access.htm&amp;language=en_US&amp;type=5"><span style="font-weight: 400">Manage User Access for BRP </span></a></li>
<li style="font-weight: 400"><a href="https://help.salesforce.com/s/articleView?id=sales.account_plans.htm&amp;type=5"><span style="font-weight: 400">Sales Account Plans Overview</span></a></li>
<li style="font-weight: 400"><a href="https://help.salesforce.com/s/articleView?id=sales.account_plans_setup.htm&amp;language=en_US&amp;type=5"><span style="font-weight: 400">Account Plans Setup</span></a></li>
<li style="font-weight: 400"><a href="https://help.salesforce.com/s/articleView?id=sales.account_plans_strategic_tracker.htm&amp;language=en_US&amp;type=5"><span style="font-weight: 400">Strategic Tracker with Sales Action Plans </span></a></li>
<li style="font-weight: 400"><a href="https://help.salesforce.com/s/articleView?id=ind.fsc_admin_business_relationship_plan_einstein_summaries.htm&amp;language=en_US&amp;type=5"><span style="font-weight: 400">Einstein Summaries for BRP</span></a></li>
<li style="font-weight: 400"><a href="https://github.com/trailheadapps"><span style="font-weight: 400">Salesforce Developers sample apps on GitHub</span></a></li>
</ul>
<h2><span style="font-weight: 400">About the author</span></h2>
<p><b>Vignesh Damodharan</b><span style="font-weight: 400"> is a Lead Member of Technical Staff with Agentforce Financial Services, where he leads Salesforce engineering teams building enterprise products on the Salesforce Platform. Follow him on </span><a href="https://www.linkedin.com/in/vigneshdamodharan/"><span style="font-weight: 400">LinkedIn</span></a><span style="font-weight: 400">.</span></p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/06/build-continuous-planning-systems-in-agentforce-financial-services">Build Continuous Planning Systems in Agentforce Financial Services</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://developer.salesforce.com/blogs/2026/06/build-continuous-planning-systems-in-agentforce-financial-services/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206583</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260624102452/Generic-C-4-e1782321903642.png?w=1000" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260624102452/Generic-C-4-e1782321903642.png?w=1000" medium="image" />
	</item>
		<item>
		<title>Master the Agentic Development Lifecycle for Agentforce</title>
		<link>https://developer.salesforce.com/blogs/2026/06/master-the-agentic-development-lifecycle-for-agentforce</link>
		<comments>https://developer.salesforce.com/blogs/2026/06/master-the-agentic-development-lifecycle-for-agentforce#respond</comments>
		<pubDate>Wed, 24 Jun 2026 15:00:04 +0000</pubDate>
		<dc:creator><![CDATA[Mohith Shrivastava]]></dc:creator>
				<category><![CDATA[Agentforce]]></category>
		<category><![CDATA[Agentforce Vibes]]></category>
		<category><![CDATA[App Development]]></category>
		<category><![CDATA[Headless 360]]></category>
		<category><![CDATA[Agent Skills]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206559</guid>
		<description><![CDATA[<p>Learn how to design, build, test, and deploy Agentforce agents using plain language, Agent Skills, and a design-first development lifecycle.</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/06/master-the-agentic-development-lifecycle-for-agentforce">Master the Agentic Development Lifecycle for Agentforce</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p><span style="font-weight: 400">Building with </span><a href="https://developer.salesforce.com/docs/ai/agentforce/guide"><span style="font-weight: 400">Agentforce</span></a><span style="font-weight: 400"> rarely involves a single task. An AI agent can span a data model, actions (flows or Apex), agent definition, and permissions. Each piece has its own setup screens, so you have to spend time clicking to wire it all together. With </span><a href="https://developer.salesforce.com/blogs/2026/05/headless-360-what-it-means-for-developers"><b>Salesforce Headless 360</b></a><span style="font-weight: 400">, the platform now exposes every one of those capabilities as an application programming interface (API), a Model Context Protocol (MCP) tool, or a command-line interface (CLI) command. Because the whole platform can be accessed by coding agents, they can take your intent and handle much of that work — which opens a new, agentic way to build.</span></p>
<p><span style="font-weight: 400">Many Salesforce Developers want a repeatable, design-first lifecycle for agent development. The Headless 360 approach pairs a coding agent like Claude Code, Codex, or </span><a href="https://developer.salesforce.com/docs/platform/einstein-for-devs/guide/einstein-overview.html"><span style="font-weight: 400">Agentforce Vibes</span></a><span style="font-weight: 400"> with </span><a href="https://agentskills.io/home"><span style="font-weight: 400">Agent Skills</span></a><span style="font-weight: 400">, so you can design, build, deploy, test, and debug from a single plain-language conversation. You stay the designer; the coding agent does the development. </span></p>
<p><span style="font-weight: 400">In this post, we&#8217;ll look at how to set up Salesforce Agent Skills, scaffold a project and connect an org, design before you build, generate your metadata, validate and test, and debug with traces. Everything we’ll discuss here works today through the open-source </span><a href="https://github.com/forcedotcom/sf-skills"><span style="font-weight: 400">Salesforce Skills Library</span></a><span style="font-weight: 400"> and the </span><a href="https://developer.salesforce.com/tools/salesforcecli"><span style="font-weight: 400">Salesforce CLI</span></a><span style="font-weight: 400">. </span></p>
<h2><strong>Teach your coding agent Salesforce with Agent Skills</strong></h2>
<p><span style="font-weight: 400">Agent Skills are how your coding assistant learns Salesforce. A skill is a small bundle of instructions and commands that teaches the assistant a specific task, such as building an Apex class or a Lightning web component (LWC), building a flow, or developing Agentforce agents. Without skills, the assistant guesses. With them, it runs the right steps and necessary CLI commands or MCP tools and follows conventions.</span></p>
<p><span style="font-weight: 400">You should install these skills either globally or within your project directory for any coding agents besides Agentforce Vibes, as the latter includes them by default. The Salesforce Skills Library ships dozens of skills covering Apex, LWC, Agentforce, Data 360, and metadata deployment. </span></p>
<p>Three skills drive the agent lifecycle specifically:</p>
<ul>
<li><code>developing-agentforce</code>: Design, build, deploy, debug (see <a href="https://github.com/forcedotcom/sf-skills/tree/main/skills/developing-agentforce"><u>docs</u></a>)</li>
<li><code>testing-agentforce</code>: Test specs and batch runs (see <a href="https://github.com/forcedotcom/sf-skills/tree/main/skills/testing-agentforce"><u>docs</u></a>)</li>
<li><code>observing-agentforce</code>: Inspect production traces from Data 360 (see <a href="https://github.com/forcedotcom/sf-skills/tree/main/skills/observing-agentforce"><u>docs</u></a>)</li>
</ul>
<p>Once installed, in most coding agents you should be able to type <code>‘/’</code> in your assistant to browse them. You&#8217;ll see a skill load by name as the assistant works, for example, <code>developing-agentforce</code> activates the moment you ask for an agent scaffold.</p>
<p><span style="font-weight: 400">You&#8217;ll also need a few common tools on your machine first: </span><a href="https://nodejs.org"><span style="font-weight: 400">Node.js</span></a><span style="font-weight: 400"> and the </span><a href="https://developer.salesforce.com/tools/salesforcecli"><span style="font-weight: 400">Salesforce CLI</span></a><span style="font-weight: 400">. And here&#8217;s the best part — if something is missing, use your assistant to get help. And if the assistant has permissions, it can also install these for you.</span></p>
<p><span style="font-weight: 400">To install Salesforce Agent Skills, run the below command from your terminal or ask your assistant to run the below command.</span></p>
<pre language="sh">npx skills add forcedotcom/sf-skills
</pre>
<p><span style="font-weight: 400">After executing the command, you will navigate through a few quick configuration choices. First, you’ll pick the specific skills from the library to equip your assistant. Then, designate your preferred coding agent and decide if these instructions should be available across all your projects or just for the current local directory.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206576" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260623124718/image2-e1782244050713.png?w=1000" class="postimages" width="1000" height="618" alt="A terminal showing the Agent Skills install command asking to select list of installed skills" />
			  </span>
			</p>
<h2><strong>Scaffold the project and connect your org</strong></h2>
<p><span style="font-weight: 400">Every Salesforce project starts with a scaffold — a folder holding all your metadata as files. This is the same project structure you already pull into an integrated development environment (IDE) like VS Code. Your assistant works against those local files, then deploys them to an org.</span></p>
<p><span style="font-weight: 400">Here&#8217;s the shift that matters. You no longer memorize CLI flags or look up command syntax. You describe what you want in plain language, and the coding agent runs the right Salesforce CLI command for you. The CLI does the actual work — the agent just knows which command to call and translates your words into it.</span></p>
<p><span style="font-weight: 400">For example, scaffolding a project used to mean typing the exact command and its flags:</span></p>
<pre language="sh">sf project generate --name agent-script-demo
</pre>
<p><span style="font-weight: 400">Now, you simply describe the goal in plain language, and the agent runs that command for you:</span></p>
<blockquote><p><i><span style="font-weight: 400">&#8220;Create a Salesforce project scaffold named agent-script-demo&#8221;</span></i></p></blockquote>
<p><span style="font-weight: 400">Keep each project in its own folder, so the agent only touches what it should. From there, the same pattern repeats for every step. For example, when you ask it to set up your org, the agent checks the current default and sets your scratch org or sandbox as the default for this project using the commands below.</span></p>
<pre language="sh">sf config get target-org --json
sf config set target-org agent-build --json
</pre>
<p><span style="font-weight: 400">You can also ask the coding agent to open your default org, and the coding agent will use the command below to open it.</span></p>
<pre language="sh">sf org open
</pre>
<p><span style="font-weight: 400">A best practice is to build in scratch orgs or sandboxes and never give your agent access to the production environment. Also, never paste secrets like passwords into a prompt. A handy workflow is to run a second terminal </span><i><span style="font-weight: 400">without</span></i><span style="font-weight: 400"> the assistant. That way you can copy, edit, and run sensitive commands yourself. </span></p>
<h2><strong>Design before you build</strong></h2>
<p><span style="font-weight: 400">This is the most important habit in the whole lifecycle. If you let an agent build on its own, it may produce something you have to throw away. So, slow down and design first.</span></p>
<p><span style="font-weight: 400">Two things make this easy. First, switch your assistant into </span><b>plan mode</b><span style="font-weight: 400"> (in Claude Code, press Shift+Tab to cycle to &#8220;plan mode&#8221;). In plan mode, the assistant proposes a plan instead of changing files. Second, ask the assistant to interview you before it builds. A prompt like this works well:</span></p>
<blockquote><p><i><span style="font-weight: 400">&#8220;Before you build anything, interview me to design this agent. Ask one question </span></i><i><span style="font-weight: 400">at a time and recommend a sensible default for each. Treat the design as a </span></i><i><span style="font-weight: 400">decision tree: when my answer opens new choices, follow that branch and keep </span></i><i><span style="font-weight: 400">asking until it&#8217;s fully resolved, then move to the next branch. Cover the data </span></i><i><span style="font-weight: 400">model, actions, permissions, and agent structure. Don&#8217;t stop or start building </span></i><i><span style="font-weight: 400">until every decision needed to build the agent is made.&#8221;</span></i></p></blockquote>
<p><span style="font-weight: 400">That single instruction turns the assistant into a design partner. It walks down every branch of the decision tree — following each answer to the sub-decisions it raises — and only stops once nothing is left to decide. Nothing gets built on a guess. For our example, an employee To-Do Manager agent, it walked through real architectural choices:</span></p>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">Where should to-dos live: in a custom object, or the standard Task object?</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Which fields and status values does the agent need?</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Should the agent run as the logged-in user?</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Use one sub-agent with three flow actions, or a hub-and-spoke model with a sub-agent per task?</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Should the backing logic be Salesforce Flows or Apex?</span></li>
</ul>
<p><span style="font-weight: 400">Note that the above is an example prompt, and based on your organization’s best practices, you can </span><a href="https://developer.salesforce.com/blogs/2026/05/build-a-salesforce-agent-skill-with-claude-code"><span style="font-weight: 400">build an agent skill of your own</span></a><span style="font-weight: 400"> to help you design this, so you do not have to repeat this prompt.</span></p>
<p><span style="font-weight: 400">The Claude Code coding assistant interviews the developer one question at a time, recommending a default for each design decision.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206577" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260623124808/image3-e1782244100641.png?w=1000" class="postimages" width="1000" height="608" alt="The Claude Code assistant interviewing the developer" />
			  </span>
			</p>
<p><span style="font-weight: 400">Visualizing your agent as a graph is helpful. Each sub-agent acts as a node representing a specific domain: a single, focused job with its own dedicated instructions and actions. A router node at the top orchestrates these sub-agents based on the conversation. Designing the agent means defining these nodes and providing clear instructions and tools to ensure that the agent achieves the user&#8217;s goals.</span></p>
<p><span style="font-weight: 400">So, the rule of thumb is about domains, not difficulty. Keep a single sub-agent when the whole job lives in one domain, for example, frequently asked questions (FAQ) or a status lookup. Reach for multiple sub-agents in a hub-and-spoke shape when the work spans distinct domains that each deserve their own instructions, actions, or security gate. Most agents land at one to five domain sub-agents. You make these calls, not your coding agent. That&#8217;s the point — you end up more confident because you designed the graph.</span></p>
<p><span style="font-weight: 400">The AI-generated info graphic below conveys these ideas.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206578" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260623124842/image1-e1782244136116.png?w=1000" class="postimages" width="1000" height="546" alt="Visualizing agents on Agentforce as a graph" />
			  </span>
			</p>
<h2><b>Generate, deploy, and let the agent fix and retry</b></h2>
<p><span style="font-weight: 400">Once the plan is approved, the assistant builds everything: the custom object and fields, the flows, and the agent definition file written in Agent Script (the declarative format that specifies your agent&#8217;s sub-agents, routing logic, instructions, and action bindings). The output is an authoring bundle: the deployable package containing the agent&#8217;s complete definition as local metadata files. You can watch it happen live in VS Code as files appear.</span></p>
<p><span style="font-weight: 400">Be sure to scope the work explicitly in your plan. A common choice is &#8220;build, deploy, and validate&#8221; before you publish. You can also add reminders that the assistant might otherwise skip, for instance, &#8220;make sure the new object has the right permissions; create a permission set.&#8221; Field-level security (FLS) and create-read-update-delete (CRUD) permissions matter, so call them out.</span></p>
<p><span style="font-weight: 400">The standout behavior is an automated </span><b>fix-and-retry loop</b><span style="font-weight: 400">. When a deploy fails, the assistant reads the compiler or deploy error, traces it to the offending metadata, applies a fix, and redeploys, repeating that cycle until the deploy succeeds. It&#8217;s the same edit-compile-debug loop you&#8217;d run by hand, just driven by the agent. If you want to go faster, you can fan out the work, so parallel agents build several flows at once instead of one after another. When you go for parallel work, make sure you understand dependencies and group them, so they can execute without stepping on each other.</span></p>
<p>You drive this in plain language: <i>“Build a single sub-agent To-Do Manager using Salesforce Flows, build, deploy, and validate it, and create a permission set for the new object”</i>. Behind that prompt, the <code>developing-agentforce</code> skill runs a precise sequence. It first generates the authoring bundle (the agent scaffold), then validates that Agent Script compiles with a local check, deploys the backing flows or Apex the actions reference, and finally deploys the authoring bundle itself. Knowing the sequence helps you follow along and step in when needed.</p>
<pre language="sh">sf agent generate authoring-bundle --json --no-spec --name "To-Do Manager" --api-name To_Do_Manager
sf agent validate authoring-bundle --json --api-name To_Do_Manager
sf project deploy start --json --metadata Flow
sf project deploy start --json --metadata AiAuthoringBundle:To_Do_Manager
</pre>
<p>Notice two best practices baked into the skill. Every command leads with <code>--json</code> to make the output machine-readable, and every deploy names its metadata explicitly. A bare <code>sf project deploy start</code> ships everything that changed, and scoping each deploy keeps agent metadata from going out by accident.</p>
<h2><strong>Validate, then test in two modes</strong></h2>
<p><span style="font-weight: 400">When the build finishes, the assistant validates the agent&#8217;s behavior paths automatically, checking far more paths than you&#8217;d test by hand. Validation is required before the agent can be published, so it&#8217;s built into the flow.</span></p>
<p>Still, don&#8217;t skip your own testing. Automated validation is a safety net, not a substitute for judgment. This is where the <code>testing-agentforce</code> skill comes in. It gives you two modes: quick smoke tests while you iterate, and a saved batch suite for regression testing and continuous integration. Use the first to move fast, and the second to keep the agent honest as it grows.</p>
<h3><strong>Quick smoke tests with preview sessions</strong></h3>
<p>The quick mode is a live preview session. You start a session, send a real utterance, and end the session when you&#8217;re done — each preview sends a trace you can read afterward. Note that <code>--authoring-bundle</code> must appear on all three subcommands.</p>
<pre language="sh">sf agent preview start --json --authoring-bundle To_Do_Manager

sf agent preview send --json --authoring-bundle To_Do_Manager --session-id SESSION_ID --utterance "Create a to-do to write a blog"\

sf agent preview end --json --authoring-bundle To_Do_Manager --session-id SESSION_ID
</pre>
<h3><b>Batch regression testing with test specs</b></h3>
<p><span style="font-weight: 400">For repeatable testing, you describe the cases you care about and the skill writes a test spec. The spec is a YAML file that lists each utterance alongside what should happen. Three assertions matter per case:</span></p>
<ul>
<li><code>expectedTopic</code>: The sub-agent that the conversation should route to</li>
<li><code>expectedActions</code>: The actions that should fire</li>
<li><code>expectedOutcome</code>: A plain-language description of the right result</li>
</ul>
<p><span style="font-weight: 400">That last one is graded by a large language model (LLM) acting as a judge, so it reads the response the way a person would. It&#8217;s the most reliable assertion, so include it on every case.</span></p>
<pre language="YAML">name: To_Do_Manager_Tests
subjectType: AGENT
subjectName: To_Do_Manager
testCases:
  - utterance: "Create a to-do to write a blog"
    expectedTopic: To_Do_Management
    expectedActions:
      - Create_To_Do
    expectedOutcome: "A new to-do titled 'write a blog' is created and confirmed to the user."
</pre>
<p><span style="font-weight: 400">You then create the test definition from that spec and run it as a batch, waiting for the results.</span></p>
<pre language="sh">sf agent test create --json --spec specs/To_Do_Manager-testSpec.yaml --api-name To_Do_Manager_Tests --force-overwrite

sf agent test run --json --api-name To_Do_Manager_Tests --wait 10
</pre>
<p><span style="font-weight: 400">When a case fails, the skill diagnoses it straight from the trace — a sub agent that didn&#8217;t match, an action that never fired, or an ungrounded response. It then applies a targeted fix and retries for a few iterations before asking for your help. You can also run the live preview in the new </span><b>Agent Builder</b><span style="font-weight: 400"> for an admin-friendly view, or use the </span><b>Agentforce DX</b><span style="font-weight: 400"> panel in VS Code to start a test session.</span></p>
<p><span style="font-weight: 400">Note: We are enhancing the automated testing experience to support multi-turn conversation, injection of state variables, and verify action validations. Keep an eye on the </span><a href="https://help.salesforce.com/s/articleView?id=release-notes.rn_einstein_platform.htm&amp;release=262&amp;type=5"><span style="font-weight: 400">release notes</span></a><span style="font-weight: 400">.</span></p>
<h2><strong>Publish and activate your agent</strong></h2>
<p><span style="font-weight: 400">When it works, publish and activate the agent. Publishing turns the deployed bundle into a runnable agent version as </span><i><span style="font-weight: 400">Inactive</span></i><span style="font-weight: 400">; activating turns it on so users and tests can reach it. You can publish now and activate later if you prefer. Below are commands that the agent runs for publish and activation.</span></p>
<pre language="sh">sf agent publish authoring-bundle --json --api-name To_Do_Manager
sf agent activate --json --api-name To_Do_Manager
</pre>
<p><span style="font-weight: 400">And if you forgot a piece of metadata, just ask the agent to build it for you. The whole point is that you describe the gap and the assistant fills it. Maintain a repeatable history by committing your Agent Script and associated metadata to a source control system like </span><a href="https://git-scm.com/"><span style="font-weight: 400">Git</span></a><span style="font-weight: 400">. This practice ensures you can revert to a known functional version whenever necessary, keeping your development environment stable and secure.</span></p>
<h2><strong>Debug with traces, not guesswork</strong></h2>
<p><span style="font-weight: 400">The agent trace is the primary debugging signal for Agentforce agents. It’s a JSON file generated after each conversation turn that shows which sub-agent handled the request, what the LLM received, and which actions fired. Agents rarely come out perfect on the first try, so you&#8217;ll keep tweaking them. You&#8217;ll work with traces in two places, and they look slightly different in each.</span></p>
<h3><strong>Local traces during development</strong></h3>
<p>While you build, the traces are local. After each <code>preview send</code>, the runtime writes one JSON file per conversation turn. Each trace shows the full execution path: which sub-agent handled the turn, what variables were set, what the LLM saw, and which actions it called. You&#8217;ll find these files in your project.</p>
<pre language="sh">.sfdx/agents/To_Do_Manager/sessions//traces/.json
</pre>
<p><span style="font-weight: 400">These local traces are instant and complete, but they only cover your own preview sessions. The fix loop is simple: open the trace, paste it back into your assistant, and explain what you expected versus what happened. In the Agent DX panel, you can grab the same trace with one click. The trace is detailed enough that the assistant usually pinpoints and fixes the issue — you can even ask it to &#8220;self-test using the trace and fix it.&#8221; This resolves the large majority of problems before the agent ever ships.</span></p>
<h3>Production traces with the <code>observing-agentforce</code> skill</h3>
<p>Once real users are on the agent, you need a different lens. That&#8217;s the job of the <code>observing-agentforce</code> skill. Instead of one local file, it queries the <a href="https://help.salesforce.com/s/articleView?id=ai.generative_ai_session_trace_data_model.htm&amp;type=5"><u>Session Trace Data Model (STDM) </u></a>— the production session data that Agentforce stores in Data 360 — so you can see how the agent behaves across real conversations at volume.</p>
<p><span style="font-weight: 400">The skill follows a three-step loop: </span><b>observe, reproduce, improve</b><span style="font-weight: 400">. It queries production sessions to surface the failures that matter — sub-agent misroutes, action errors, low adherence, slow actions, and abandoned sessions. It then reproduces a suspect case in a local preview to confirm the root cause, and only then edits the agent to fix it. You ask in plain language, </span><i><span style="font-weight: 400">&#8220;find the worst-performing sessions from the last day and tell me why&#8221;</span></i><span style="font-weight: 400">, and the skill runs the queries and reads the results for you.</span></p>
<p><span style="font-weight: 400">For either kind of trace, a visualizer helps when the routing itself is hard to follow. The agent is a graph: a router hands each conversation to a sub-agent, which builds variables and prompts, sends them to the LLM, and calls tools until it has an answer. A tool like </span><a href="https://developer.salesforce.com/blogs/2026/05/agentlens-debug-agentforce-with-interactive-visualizations"><span style="font-weight: 400">AgentLens</span></a><span style="font-weight: 400"> lets you walk that graph step by step, seeing each sub-agent handoff, the tools sent to the LLM, and the response that ends the flow.</span></p>
<p><span style="font-weight: 400">Note: for agent observability at scale for production agents, it is recommended to set up dashboards and metrics using </span><a href="https://help.salesforce.com/s/articleView?id=005226932&amp;type=1"><span style="font-weight: 400">Agent Observability </span></a></p>
<h2><b>Extend the lifecycle with custom agent skills</b></h2>
<p><span style="font-weight: 400">Adopt this lifecycle and your day-to-day changes. You stop clicking through Salesforce setup for routine work and start describing outcomes instead. When something isn&#8217;t right, the fix almost always lives in one of four places: your prompt, your context, the tools you built, or the skills you installed.</span></p>
<p><span style="font-weight: 400">That last one is the real unlock. When a skill produces metadata you don&#8217;t like, improve the skill and contribute it back. Your fixes compound for everyone, and the assistant gets better at Salesforce over time. Pairing that with a design-first interview keeps you in control — you slow down just enough to learn and to own the design.</span></p>
<h2><b>The agentic development lifecycle: Recap</b></h2>
<p><span style="font-weight: 400">The agentic development lifecycle gives you a faster, more reliable way to build Agentforce agents. Install Agent Skills from the Salesforce Skills Library so your assistant knows Salesforce, scaffold and connect your project, then design before you build with plan mode and a design-first interview. Let the assistant generate the metadata and fix-and-retry failed deployments, validate and test the result, and debug with traces when something&#8217;s off. You move quicker and stay the designer the entire time.</span></p>
<p><span style="font-weight: 400">Want to go deeper or share what you&#8217;ve built? Join the conversation in the </span><a href="https://trailhead.salesforce.com/trailblazer-community/groups/0F93A000000DJbJSAW?tab=discussion&amp;sort=LAST_MODIFIED_DATE_DESC"><span style="font-weight: 400">Salesforce Developers Trailblazer Community</span></a><span style="font-weight: 400">.</span></p>
<h2><b>Resources</b></h2>
<ul>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/developer-centers/agentforce"><span style="font-weight: 400">Agentforce Developer Center</span></a></li>
<li style="font-weight: 400"><a href="https://github.com/forcedotcom/sf-skills"><span style="font-weight: 400">Salesforce Skills Library on GitHub (forcedotcom/sf-skills)</span></a></li>
<li style="font-weight: 400"><a href="https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-agents"><span style="font-weight: 400">Agentforce DX Visual Studio Code extension</span></a></li>
</ul>
<h2><b>About the author</b></h2>
<p><b>Mohith Shrivastava</b><span style="font-weight: 400"> is a Principal Developer Advocate at Salesforce with 15 years of experience building enterprise-scale products on the Agentforce 360 Platform. Mohith is currently among the lead contributors on Salesforce Stack Exchange, a developer forum where Salesforce Developers can ask questions and share knowledge. You can follow him on </span><a href="https://www.linkedin.com/in/mohith-shrivastava-9a36464a/"><span style="font-weight: 400">LinkedIn</span></a><span style="font-weight: 400">.</span></p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/06/master-the-agentic-development-lifecycle-for-agentforce">Master the Agentic Development Lifecycle for Agentforce</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://developer.salesforce.com/blogs/2026/06/master-the-agentic-development-lifecycle-for-agentforce/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206559</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260618092236/SingleHeadshot-5-e1781799775222.png?w=1000" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260618092236/SingleHeadshot-5-e1781799775222.png?w=1000" medium="image" />
	</item>
		<item>
		<title>Analyze and Consolidate Apex Triggers via Agentforce Vibes</title>
		<link>https://developer.salesforce.com/blogs/2026/06/analyze-and-consolidate-apex-triggers-via-agentforce-vibes</link>
		<comments>https://developer.salesforce.com/blogs/2026/06/analyze-and-consolidate-apex-triggers-via-agentforce-vibes#respond</comments>
		<pubDate>Tue, 23 Jun 2026 15:00:56 +0000</pubDate>
		<dc:creator><![CDATA[Lakshmi Anusha Myneni]]></dc:creator>
				<category><![CDATA[Agentforce]]></category>
		<category><![CDATA[Agentforce Vibes]]></category>
		<category><![CDATA[Apex]]></category>
		<category><![CDATA[Developer Tooling]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Apex Best Practices]]></category>
		<category><![CDATA[Apex triggers]]></category>
		<category><![CDATA[Code Refactoring]]></category>
		<category><![CDATA[Developer Tools]]></category>
		<category><![CDATA[Salesforce CLI]]></category>
		<category><![CDATA[salesforce dx]]></category>
		<category><![CDATA[technical debt]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206556</guid>
		<description><![CDATA[<p>Learn how to use Agentforce Vibes to automatically audit, risk-scan, and safely consolidate multiple Apex triggers into a single, clean, and maintainable framework.</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/06/analyze-and-consolidate-apex-triggers-via-agentforce-vibes">Analyze and Consolidate Apex Triggers via Agentforce Vibes</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p><span style="font-weight: 400">Every org has a story, and it usually begins the same way: one Apex trigger here, another there, each solving a problem in the moment. But over time, orgs quietly accumulate multiple Apex triggers on the same object, written by different developers with no unified strategy. Before long, you&#8217;re staring down unpredictable execution orders, governor limit landmines, logic conflicts, and recursion nightmares. Sound familiar?</span></p>
<p><span style="font-weight: 400">Of course, managed package triggers are a black box. We don&#8217;t own them, and we can&#8217;t touch them. But our custom triggers? That&#8217;s our house, and we get to set the rules. The answer isn&#8217;t more triggers. It&#8217;s one, done right.</span></p>
<p><span style="font-weight: 400">That&#8217;s where </span><a href="https://www.salesforce.com/agentforce/developers/vibe-coding/"><span style="font-weight: 400">Agentforce Vibes</span></a><span style="font-weight: 400"> becomes your best pair programmer. It reads through your triggers, tells you exactly what each one is doing, spots the landmines, and helps you consolidate everything into a clean, scalable pattern iejggcbhdbklunjvfhejciflcuchnvrn the way it should have been built from the start. What would typically take days of manual code review and architectural planning gets done in a fraction of the time, so your team can focus on what actually matters building great solutions.</span></p>
<p><span style="font-weight: 400">In my org, I had multiple triggers firing on the Opportunity object, each one written at a different point in time, by different developers, for different reasons. In this post, I’ll walk you through the approach I used to bring all of that chaos under one roof, into a single, clean trigger while intentionally leaving any managed package triggers untouched.</span></p>
<p><span style="font-weight: 400">The workflows, skills, prompts, and steps you&#8217;ll see throughout this post are based on my own org, and your org will certainly look different. Your trigger count, logic complexity, and dependency map are uniquely yours. That&#8217;s completely normal, and honestly, that&#8217;s the point.</span></p>
<h2><span style="font-weight: 400">From concept to practice: Skills and workflows</span></h2>
<p><span style="font-weight: 400">What makes this approach powerful is that you can turn it into a reusable</span><a href="https://developer.salesforce.com/docs/platform/einstein-for-devs/guide/skills.html"> <span style="font-weight: 400">skill</span></a><span style="font-weight: 400"> or</span><a href="https://developer.salesforce.com/docs/platform/einstein-for-devs/guide/devagent-workflows.html"> <span style="font-weight: 400">workflow</span></a><span style="font-weight: 400"> — a framework that you can run on any object, share across your team, or plug into other agents. The principles are universal; the execution is yours to shape.</span></p>
<h3><span style="font-weight: 400">Skills: Your on-demand code analyst</span></h3>
<p><span style="font-weight: 400">Think of a skill as a specialist you can call on instantly. Point it at your triggers and it surfaces what actually matters: recursion traps, SOQL inside loops, conflicting field assignments, or gaps in test coverage. Analysis that used to take hours of careful reading? It now takes minutes.</span></p>
<h3><span style="font-weight: 400">Workflows: Safe, repeatable refactoring at scale</span></h3>
<p><span style="font-weight: 400">A workflow takes that analysis and turns it into a structured, sequenced process: audit first, then refactor what needs fixing, then generate the consolidated trigger, handler, and tests in the right order. No steps skipped, no code merged before it&#8217;s ready. Just a clean, predictable path from messy to maintainable.</span></p>
<h2><span style="font-weight: 400">From chaos to a single, clean trigger</span></h2>
<p><span style="font-weight: 400">Below is the a generic workflow that I implemented to take multiple Apex triggers on a single object and consolidate them into one clean, maintainable handler.</span></p>
<table>
<tbody>
<tr>
<td><b>Step</b></td>
<td><b>Description</b></td>
</tr>
<tr>
<td><span style="font-weight: 400">1. Workflow start</span></td>
<td>You run the <code>/trigger-consolidation</code> command to start the trigger consolidation workflow.</td>
</tr>
<tr>
<td><span style="font-weight: 400">2. Metadata retrieval</span></td>
<td><span style="font-weight: 400">The trigger consolidation workflow uses the Salesforce CLI to query the org’s metadata and pull all trigger and class sources.</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">3. Trigger analysis</span></td>
<td><span style="font-weight: 400">The workflow runs the 15-dimension risk assessment on your code thanks to the two trigger analysis skills.</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">4. Plan creation</span></td>
<td>The workflow writes the audit plan to <code>docs/trigger-audit-plan.md</code>.</td>
</tr>
<tr>
<td><span style="font-weight: 400">5. Plan review</span></td>
<td><span style="font-weight: 400">You read, edit, adjust, and approve the plan.</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">6. Plan execution</span></td>
<td><span style="font-weight: 400">The workflow reads your plan, and generates files that implement the trigger consolidation.</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">7. Manual review</span></td>
<td>You review generated files and resolve the <code>// CONFLICT</code> and <code>// ASYNC REQUIRED</code> comments.</td>
</tr>
</tbody>
</table>
<p><span style="font-weight: 400">This workflow works on any standard or custom object as it contains no hardcoded object names. You can run it multiple times on different objects. You’ll get the same process and the same quality of analysis without the need for reconfiguration.</span></p>
<p><span style="font-weight: 400">Let’s take a look at the workflow steps in more detail.</span></p>
<h3><span style="font-weight: 400">Step 0: Project setup</span></h3>
<p><span style="font-weight: 400">Before you get started, there are a few things you&#8217;ll need in place.</span></p>
<p><span style="font-weight: 400">This walkthrough assumes that you&#8217;re working in VS Code with the</span><a href="https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode"> <b>Salesforce Extension Pack</b></a><span style="font-weight: 400"> installed, your org is authenticated via the</span><a href="https://developer.salesforce.com/tools/salesforcecli"> <b>Salesforce CLI</b></a><span style="font-weight: 400">, and the</span><a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_mcp_server.htm"> <b>Salesforce DX MCP Server</b></a><span style="font-weight: 400"> is enabled in Agentforce Vibes. If you&#8217;re already set up, feel free to skip ahead. Otherwise, each link above will get you there quickly.</span></p>
<p><span style="font-weight: 400">I&#8217;ve published a base version of the skills and workflows for trigger consolidation on</span><a href="https://github.com/anushamyneni1/apexTriggerConsolidation"> <b>GitHub</b></a><span style="font-weight: 400">. Think of it as your ready-to-run starting point: fork it, adapt it to your org&#8217;s objects and conventions, and make it your own.</span></p>
<p>Now, let&#8217;s install the skills and workflows. Head over to this<a href="https://github.com/anushamyneni1/apexTriggerConsolidation#setup"> <b><u>README</u></b></a> for setup instructions, it walks you through copying the <code>.a4drules/</code> directory into your Salesforce DX project root.</p>
<p>This copies three files into your project: <code>apex-trigger-risk-scan.md</code>,<code> </code><code>pex-trigger-consolidation-analysis.md</code>, and <code>trigger-consolidation.md</code>.</p>
<pre>your-sfdx-project/
├─ .a4drules/
│   ├─ skills/
│   │   └─ apex-trigger-risk-scan.md                  ← single trigger analysis skill
│   │      └─ apex-trigger-consolidation-analysis.md  ← cross trigger analysis skill
│   └─ workflows/
│       └─ trigger-consolidation.md    ← trigger consolidation workflow
</pre>
<p><span style="font-weight: 400">That&#8217;s the entire install — no restart or configuration required. Agentforce Vibes picks up the new skills and workflow immediately.</span></p>
<h3><span style="font-weight: 400">Step 1: Workflow start</span></h3>
<ol>
<li style="font-weight: 400"><span style="font-weight: 400">Click the </span><b>Agentforce Vibes</b><span style="font-weight: 400"> icon in the VS Code Activity Bar to open the chat panel.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400"><span style="font-weight: 400">Type the following command to start the trigger consolidation workflow.</span></span>
<pre>/trigger-consolidation
</pre>
</li>
<li style="font-weight: 400"><span style="font-weight: 400"><span style="font-weight: 400">The workflow kicks off by asking which object to work on.</span></span>
<pre>Which Salesforce object do you want to consolidate triggers for?
(e.g. Opportunity, Case, Account, Invoice__c)
</pre>
<p><span style="font-weight: 400"></span></li>
<li>Type an object name like <code>Opportunity</code> and press Enter.</li>
</ol>
<h3><span style="font-weight: 400">Step 2: Metadata retrieval</span></h3>
<p><span style="font-weight: 400">The workflow uses the Salesforce CLI to query your org’s metadata to retrieve Apex triggers and the related helper classes.</span></p>
<p><span style="font-weight: 400">You can watch it work in the chat panel with an output similar to this:</span></p>
<pre>Running: sf data query --query "SELECT Name, ... FROM ApexTrigger
WHERE TableEnumOrId = 'Opportunity' AND Status = 'Active'"

## Summary of what was retrieved:
**Triggers (9 total, 5 readable):**
1. **OpportunityBefore** (x2) - Body hidden (managed package / org-installed, unreadable)
2. **OpportunityAfter** - Body hidden (unreadable)
3. **OpportunityTrigger** - Body hidden (unreadable)
4. **OppDeleteTrigger** - before delete — readable
5. **OppCreateTrigger** - before insert, after insert — readable
6. **OpportunityNotifyTrigger** - after insert, after update — readable
7. **OppStageTrigger** - before update — readable
8. **OpportunityUpdateTrigger** - before update, after update — readable
The dependent classes are all accessible: OpportunityUtils, OpportunityHelper, and NotificationService. No test classes exist for this trigger suite. Let me load the apex-trigger-analysis skill to conduct the risk assessment.
</pre>
<h3><span style="font-weight: 400">Step 3: Trigger analysis</span></h3>
<p><span style="font-weight: 400">With the source in hand, the workflow loads the two trigger analysis skills and runs every trigger through all risk dimensions.</span></p>
<h4><span>Per-trigger scan: </span><code>apex-trigger-risk-scan</code><span> skill (seven dimensions)</span></h4>
<table>
<tbody>
<tr>
<td><b>Dimension</b></td>
<td><b>What It Catches</b></td>
</tr>
<tr>
<td><b>Execution order risk</b></td>
<td><span style="font-weight: 400">Flags assumptions that the trigger makes about running before or after another specific trigger, e.g., comments or field reads that depend on values another trigger should set first.</span></td>
</tr>
<tr>
<td><b>Recursion traps</b></td>
<td><span style="font-weight: 400">Flags absence of a static Boolean recursion guard when DML is present — CRITICAL if no guard and DML exists, and HIGH if no guard only.</span></td>
</tr>
<tr>
<td><b>Governor limit exposure</b></td>
<td><span style="font-weight: 400">Scans for SOQL inside loops (CRITICAL), DML inside loops (CRITICAL), synchronous HTTP callouts in trigger context (HIGH), and aggregate queries without LIMIT (MEDIUM).</span></td>
</tr>
<tr>
<td><b>Before/after context boundary</b></td>
<td><span style="font-weight: 400">Maps which contexts that the trigger fires in and flags misplaced logic, e.g., field assignments in after context (silently lost) or DML on triggering record in before context (causes recursion).</span></td>
</tr>
<tr>
<td><b>Bypass mechanism</b></td>
<td><span style="font-weight: 400">Looks for kill-switch patterns, such as custom setting/metadata checks, permission-based skips, or static Boolean flags set externally, and notes absence as well as presence.</span></td>
</tr>
<tr>
<td><b>Static variable inventory</b></td>
<td><span style="font-weight: 400">Lists every static variable in handler/helper classes and flags generic names (isRunning, processed) that collide with the same name in another trigger&#8217;s class after consolidation.</span></td>
</tr>
</tbody>
</table>
<h4><span>Cross-trigger analysis: </span><code>apex-trigger-consolidation-analysis</code><span> skills (eight dimensions)</span></h4>
<table>
<tbody>
<tr>
<td><b>Dimension</b></td>
<td><b>What It Checks</b></td>
</tr>
<tr>
<td><b>Logic overlap</b></td>
<td><span style="font-weight: 400">Compares all triggers and flags the same field assigned in multiple triggers, identical validation logic, and the same helper method called from multiple triggers.</span></td>
</tr>
<tr>
<td><b>Conflicting logic</b></td>
<td><span style="font-weight: 400">Flags contradictions across triggers on the same event, such as opposing field values, one trigger nulling a field another reads, mutually exclusive conditionals, or read-after-write dependencies.</span></td>
</tr>
<tr>
<td><b>Helper class coupling</b></td>
<td><span style="font-weight: 400">Maps helper/utility classes to dependent triggers, i.e., any class used by more than two triggers is a consolidation risk since modifying it can break all callers.</span></td>
</tr>
<tr>
<td><b>Test coverage gaps</b></td>
<td><span style="font-weight: 400">Determines per trigger whether or not a test class exists, coverage is below 85%, or there’s an absence of a bulk test with 200+ records.</span></td>
</tr>
<tr>
<td><b>Static variable collision</b></td>
<td><span style="font-weight: 400">Cross-references static variable inventories from all per-trigger scans and identifies name collisions, such as two classes with the same static variable name, corrupting recursion guards.</span></td>
</tr>
<tr>
<td><b>Bypass consolidation strategy</b></td>
<td><span style="font-weight: 400">Assesses whether bypass mechanisms can be unified: compatible bypasses merge into one; inconsistent bypasses require per-method flags; or triggers with no bypass that inherit a unified bypass unintentionally are flagged.</span></td>
</tr>
<tr>
<td><b>Automation re-entry risk</b></td>
<td>Identifies flows, process builders, or workflow field updates that can commit DML re-firing Apex triggers mid-transaction, and flags <code>@future/Queueable/Platform Event</code> calls that could loop back.</td>
</tr>
<tr>
<td><b>Cumulative governor limit budget</b></td>
<td><span style="font-weight: 400">Sums SOQL, DML, and heap consumption across all triggers to surface compound risk invisible per-trigger, and flags when the combined estimate approaches Salesforce limits even if no single trigger is problematic alone.</span></td>
</tr>
</tbody>
</table>
<p><span style="font-weight: 400">You’ll see findings stream into the panel in real time.</span></p>
<pre>Score Meaning
1–3      Low — safe to consolidate with minimal prep
4–6      Medium — refactor required before merge
7–9      High — urgent action recommended
10       Critical — production incident likely without immediate action
Overall risk score: 7/10
</pre>
<h3><span style="font-weight: 400">Step 4: Plan creation</span></h3>
<p>Here&#8217;s the part that matters: <b>the workflow does not generate a single line of code yet.</b><br />
Instead, it writes a detailed plan file to <code>docs/trigger-audit-plan.md</code> and pauses.</p>
<pre>Audit complete. I've written the full plan to docs/trigger-audit-plan.md.
Overall risk score: 7/10
Please review the findings and edit anything before I generate
the consolidated scaffold.
When you're ready, reply YES to proceed. Reply NO to stop here.
</pre>
<h3><span style="font-weight: 400">Step 5: Plan review</span></h3>
<p><span style="font-weight: 400">Open the plan file in VS Code. It contains:</span></p>
<ul>
<li style="font-weight: 400"><b>Trigger inventory</b><span style="font-weight: 400">: Every trigger, its events, line count, risk score, and top finding</span></li>
<li style="font-weight: 400"><b>Risk register</b><span style="font-weight: 400">: Every finding with severity, plain-English description, and recommendation</span></li>
<li style="font-weight: 400"><b>Dependency graph</b><span style="font-weight: 400">: Which triggers share which helper classes, as a plain-text diagram</span></li>
<li style="font-weight: 400"><b>Logic merge map</b><span style="font-weight: 400">: Exactly which logic from which trigger goes into each consolidated context, with conflicts flagged explicitly</span></li>
<li style="font-weight: 400"><b>Best practices compliance:</b><span style="font-weight: 400"> Where current triggers violate Apex standards and what the consolidated code will fix</span></li>
</ul>
<p><b>This file is yours to edit.</b><span style="font-weight: 400"> You can change the instructions, add team notes, remove a trigger from the plan, etc. When you’re ready to proceed, the workflow reads your edited version before it writes any code. What you see in the plan is what gets built.</span></p>
<p><span style="font-weight: 400">When the plan looks right, go back to the Agentforce Vibes chat panel and type:</span></p>
<pre>YES
</pre>
<h3><span style="font-weight: 400">Step 6: Plan execution</span></h3>
<p><span style="font-weight: 400">The workflow reads your (possibly edited) plan and generates consolidated files directly into your Salesforce DX project.</span></p>
<p><span style="font-weight: 400">For instance, this is what you could see when consolidating an opportunity trigger:</span></p>
<pre>✓ force-app/main/default/triggers/OpportunityTrigger.trigger        (28 lines)
✓ force-app/main/default/classes/OpportunityTriggerHandler.cls      (74 lines)
✓ force-app/main/default/classes/OpportunityTriggerHelper.cls       (32 lines)
✓ force-app/main/default/classes/OpportunityTriggerTest.cls         (58 lines)

Consolidation complete. Search for // CONFLICT and // ASYNC REQUIRED
comments — these are the only places that need manual review.
</pre>
<p><span style="font-weight: 400">In this example, these four files are generated:</span></p>
<ul>
<li><b><code>OpportunityTrigger.trigger</code></b>: This is a single trigger covering only the events that existed across the originals. No business logic in the body, everything delegates to the handler.</li>
<li><b><code>OpportunityTriggerHandler.cls</code></b>: One method per trigger context has a static Boolean recursion guard at the top, and every method is annotated with its consolidated source triggers. Logic is merged in the correct sequence per the Logic Merge Map you reviewed.</li>
<li><b><code>OpportunityTriggerHelper.cls</code></b>: This is the actual business logic, fully ported from the original triggers. All SOQL is bulkified outside loops, and duplicate logic from multiple triggers appears exactly once.</li>
<li><b><code>OpportunityTriggerTest.cls</code></b>: Test methods for single insert, bulk insert (200 records), update, bulk update, and delete are each traceable back to the source trigger.</li>
</ul>
<h3><span style="font-weight: 400">Step 7: Manual review</span></h3>
<p><span style="font-weight: 400">Once the workflow terminates, the last manual task is to review the comments that were left during the execution. There are two types of comments that you should address:</span></p>
<ul>
<li><code>// CONFLICT</code>: Where two triggers set the same field to different values. You decide which wins</li>
<li><code>// ASYNC REQUIRED</code>: Where a sync callout needs to move to <code>@future</code> or <code>Queueable</code> before deploying</li>
</ul>
<p><span style="font-weight: 400">Finally, the trigger jungle is a solved problem. Once a trigger is optimized, you can leverage prompts to deactivate the old trigger and, once tested and validated, promote the new implementation to a higher environment.</span></p>
<h2><span style="font-weight: 400">Considerations</span></h2>
<ul>
<li><b><span>Before you adapt this framework, make it yours.</span></b><span> The workflow and skill are starting points, not scripts. Your org&#8217;s complexity, naming conventions, and business logic are unique to everything generated here, so edit the audit plan before you commit to it.</span></li>
<li><b><span>Spend real time in plan mode before generating any code.</span></b><span> Open </span><code><span>docs/trigger-audit-plan.md</span></code><span>, work through the phases, flag the conflicts you already know about, and align the merge order with your team&#8217;s plan. The more thinking you do upfront, the cleaner the output.</span></li>
<li><b><span>Treat generated code as a recommendation, not a final answer.</span></b><span> Always review and validate before you deploy. These are smart suggestions, not certified production-ready commits.</span></li>
<li><b><span>Fix High severity issues before you consolidate anything.</span></b><span> If the audit surfaces recursion risks, SOQL or DML in loops, or field conflicts, stop and resolve those first. Merging broken logic into a single trigger doesn&#8217;t fix it and just makes it harder to debug later.</span></li>
<li><b><span>Version control everything.</span></b><span> This includes triggers, handler classes, service classes, audit files, test classes — all of it. If it gets generated or modified, it belongs in source control.</span></li>
<li><b><span>Always test in a sandbox first and never run directly against production.</span></b><span> The workflow connects to whichever org you&#8217;re authenticated to, so before running </span><code><span>/trigger-consolidation</span></code><span>, verify that </span><code><span>sf org list</span></code><span> shows a sandbox or scratch org as your default. Consolidating triggers in production without testing is how outages happen.</span></li>
<li><b><span>Run one object at a time, but think about the whole org.</span></b><span> This isn&#8217;t a one-and-done fix. Once Opportunity is clean, move to Case, then Account, then your custom objects. The phased approach is intentional: each consolidation builds confidence for the next.</span></li>
</ul>
<h2><span style="font-weight: 400">Conclusion</span></h2>
<p><span style="font-weight: 400">Trigger sprawl is common and costly, and with the right approach, it&#8217;s completely solvable.</span></p>
<p><b>Ready to clean up your org?</b><span style="font-weight: 400"> Start with your simplest triggers, follow the steps in this guide, build confidence, then tackle the high-traffic objects. Run the Agentforce Vibes analysis skill and let the audit canvas show you exactly what you&#8217;re dealing with. One trigger, one handler, zero surprises.</span></p>
<h2><span style="font-weight: 400">Resources</span></h2>
<p><b>Agentforce Vibes</b></p>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">Developer Guide: </span><a href="https://developer.salesforce.com/docs/platform/einstein-for-devs/overview"><span style="font-weight: 400">Agentforce Vibes Overview</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">Developer Guide: </span><a href="https://developer.salesforce.com/docs/platform/einstein-for-devs/guide/devagent-getstarted.html"><span style="font-weight: 400">Agentforce Vibes Quick Start</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">Install:</span> <a href="https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode"><span style="font-weight: 400">Salesforce Extension Pack for VS Code</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">Documentation:</span> <a href="https://developer.salesforce.com/docs/platform/einstein-for-devs/guide/devagent-mcp.html"><span style="font-weight: 400">Agentforce Vibes MCP Server </span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">Developer Guide: </span><a href="https://developer.salesforce.com/docs/platform/einstein-for-devs/guide/skills.html"><span style="font-weight: 400">Skills in Agentforce Vibes</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">Developer Guide: </span><a href="https://developer.salesforce.com/docs/platform/einstein-for-devs/guide/devagent-workflows.html"><span style="font-weight: 400">Workflows in Agentforce Vibes</span></a></li>
</ul>
<p><b>Salesforce CLI</b></p>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">Setup Guide: </span><a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_intro.htm"><span style="font-weight: 400">Salesforce CLI </span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">Command Reference:</span> <a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_project_retrieve_start.htm"><span style="font-weight: 400">SF Project Retrieve</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">Command Reference: </span><a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_data_query.htm"><span style="font-weight: 400">SF Data Query </span></a></li>
</ul>
<p><b>Apex Trigger Best Practices</b></p>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">Developer Guide: </span><a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers.htm"><span style="font-weight: 400">Apex Triggers </span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">Developer Guide:</span> <a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_best_practices.htm"><span style="font-weight: 400">Apex Best Practices</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">Trailhead:</span> <a href="https://trailhead.salesforce.com/content/learn/modules/apex_triggers/apex_triggers_intro"><span style="font-weight: 400">Apex Trigger Badge</span></a></li>
</ul>
<p><b>Metadata &amp; Deployment</b></p>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">Developer Guide: </span><a href="https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_intro.htm"><span style="font-weight: 400">Metadata API </span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">Reference:</span> <a href="https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/manifest_samples.htm"><span style="font-weight: 400">Package.xml Manifest</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">Developer Guide:</span> <a href="https://help.salesforce.com/s/articleView?id=platform.custommetadatatypes_overview.htm&amp;type=5"><span style="font-weight: 400">Custom Metadata Types </span></a></li>
</ul>
<h2><span style="font-weight: 400">About the author</span></h2>
<p><b>Lakshmi Anusha Myneni</b><span style="font-weight: 400"> is a Principal Technical Architect at Salesforce with 15 years of experience in the financial services industry. She partners closely with customers during the most critical stages of their journey, translating complex business challenges into compelling, technically sound Salesforce solutions. </span></p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/06/analyze-and-consolidate-apex-triggers-via-agentforce-vibes">Analyze and Consolidate Apex Triggers via Agentforce Vibes</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://developer.salesforce.com/blogs/2026/06/analyze-and-consolidate-apex-triggers-via-agentforce-vibes/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206556</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260622144837/Generic-B-2-e1782164932989.png?w=1000" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260622144837/Generic-B-2-e1782164932989.png?w=1000" medium="image" />
	</item>
	</channel>
</rss>
