<?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>Tue, 25 Aug 2026 13:51:09 +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>Shift Left Natively: Testing and Quality Gates in DevOps Center</title>
		<link>https://developer.salesforce.com/blogs/2026/08/shift-left-natively-testing-and-quality-gates-in-devops-center</link>
		<comments>https://developer.salesforce.com/blogs/2026/08/shift-left-natively-testing-and-quality-gates-in-devops-center#respond</comments>
		<pubDate>Tue, 25 Aug 2026 15:00:43 +0000</pubDate>
		<dc:creator><![CDATA[spadmannagari]]></dc:creator>
				<category><![CDATA[App Development]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Flow]]></category>
		<category><![CDATA[Agentforce]]></category>
		<category><![CDATA[Apex Testing]]></category>
		<category><![CDATA[Automated Testing]]></category>
		<category><![CDATA[Code Analyzer]]></category>
		<category><![CDATA[Flow Testing]]></category>
		<category><![CDATA[Quality Gates]]></category>
		<category><![CDATA[Salesforce DevOps Center]]></category>
		<category><![CDATA[Shift-Left Testing]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206887</guid>
		<description><![CDATA[<p>Learn how generally available testing in DevOps Center helps you catch issues earlier and ship with confidence by automating tests and enforcing quality gates before changes reach production.</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/08/shift-left-natively-testing-and-quality-gates-in-devops-center">Shift Left Natively: Testing and Quality Gates in DevOps Center</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p><a href="https://help.salesforce.com/s/articleView?id=platform.devops_center_testing_setup.htm&amp;type=5"><span style="font-weight: 400">DevOps Center Testing</span></a><span style="font-weight: 400"> is now generally available, natively on the platform within DevOps Center. For today’s enterprises, speed means nothing without stability. Yet, the release cycle still hits a familiar bottleneck at the very end: manual or disconnected testing. When a test fails late in the cycle, code gets sent all the way back to the developer, resulting in broken feedback loops and delayed releases. By embedding automated testing directly into the Headless 360 platform, your team can now catch regressions and enforce compliance long before code ever gets near production. In this post, we’ll look at the cost of late-stage testing, how automated quality gates work, the native test providers you can use, and how to scale this with API tools.</span></p>
<h2><b>What is DevOps Center Testing?</b></h2>
<p><span style="font-weight: 400">Testing in DevOps Center brings together Salesforce tools like </span><a href="https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/overview"><span style="font-weight: 400">Code Analyzer</span></a><span style="font-weight: 400">, Apex unit tests, and flow tests (with other Salesforce tools and partner tools from ACCELQ, Copado, Panaya, Provar, Quality Clouds, and Tricentis coming soon). You can run everything from static code analysis to full regression tests within a single workflow.</span></p>
<p><span style="font-weight: 400">DevOps Center Testing is the single source of truth for test definitions and test results, where you can define your test strategy across multiple tools, run tests automatically, and enforce quality gates to keep only high-quality changes moving forward.</span></p>
<p><span style="font-weight: 400">This means that your teams are empowered to find issues earlier in the development process and fix them well before any bugs make their way to production, where they are expensive to fix. You’ll be able to comprehensively test Apex and flow actions thanks to Code Analyzer v5 and integration with Apex unit tests and flow tests.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206889" >
			    <img fetchpriority="high" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260824135928/image2_ce3802-e1787605177517.png?w=1000" class="postimages" width="1000" height="492" alt="A DevOps Center interface displaying a multi-stage testing pipeline." />
			  </span>
			</p>
<h2><b>The cost of the late-stage testing bottleneck</b></h2>
<p><span style="font-weight: 400">&#8220;Shifting left&#8221; is the practice of moving testing, quality checks, and compliance validation as early in the development lifecycle as possible. Catching a bug in a developer sandbox takes minutes to fix. Catching that same bug in production can cost days of downtime and thousands of dollars in remediation.</span></p>
<p><span style="font-weight: 400">Achieving a true shift-left workflow on Salesforce historically required complex CI/CD orchestration, external script maintenance, and heavy third-party syncing tools. DevOps Center eliminates this operational overhead by bringing automated quality frameworks natively on the platform where your metadata and code already live.</span></p>
<h2><b>Quality gates: automated pipeline governance</b></h2>
<p><span style="font-weight: 400">Running tests automatically is only half the battle; the real magic happens when you use those tests to enforce governance.</span> <span style="font-weight: 400">A</span> <i><span style="font-weight: 400">quality gate</span></i><span style="font-weight: 400"> is an automated checkpoint in a CI/CD pipeline that evaluates code against predefined criteria, blocking substandard software from advancing or deploying until it meets the required thresholds. </span><a href="https://help.salesforce.com/s/articleView?id=platform.devops_testing_ensure_high_quality_work_items_with_quality_gate_rules.htm&amp;type=5"><span style="font-weight: 400">Automated quality gates</span></a><span style="font-weight: 400"> are now directly part of the pipeline workflow in DevOps Center. Instead of relying on manual checklists or human oversight to approve a pipeline promotion, you can define strict criteria for specific pipeline stages, such as on pull request creation or pre-promotion.</span></p>
<p><span style="font-weight: 400">Imagine a developer attempting to promote a work item. Behind the scenes, DevOps Center automatically triggers the assigned Apex, Flow, and Code Analyzer test suites. If an Apex test fails, code coverage drops below your organization&#8217;s threshold, or Code Analyzer flags a critical security vulnerability, the pipeline automatically halts. The promotion is blocked, and the developer receives immediate, line-level feedback right inside their work item. The bug is isolated and fixed instantly, keeping the main release branch completely clean.</span></p>
<h2><b>Test providers in native platform automation</b></h2>
<p><span style="font-weight: 400">DevOps Center Testing unifies execution and reporting for your most critical internal test providers right out of the box. From a single centralized hub, you can easily orchestrate a comprehensive testing matrix across programmatic and declarative elements.</span></p>
<ul>
<li style="font-weight: 400"><b>Apex tests:</b><span style="font-weight: 400"> Automatically execute unit tests and track code coverage percentages to ensure backend programmatic logic is thoroughly vetted early.</span></li>
<li style="font-weight: 400"><b>Flow tests:</b><span style="font-weight: 400"> Natively execute declarative flow test cases to verify that your automated business logic behaves precisely as intended before promotion.</span></li>
<li style="font-weight: 400"><b>Salesforce Code Analyzer:</b><span style="font-weight: 400"> Catch security vulnerabilities, detect anti-patterns, and evaluate technical debt before code review even begins by running multi-engine static code analysis including PMD, ESLint, and </span><a href="https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/guide/engine-flow.html"><span style="font-weight: 400">Flow Scanner</span></a><span style="font-weight: 400">.</span></li>
</ul>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206890" >
			    <img decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260824135959/image1_77b037-e1787605210118.png?w=1000" class="postimages" width="1000" height="725" alt="A Configure Test Provider interface showing options for Code Analyzer, Flow Tests, and Apex Unit Tests." />
			  </span>
			</p>
<h2><b>Agentic era: skills for DevOps Center Testing</b></h2>
<p><span style="font-weight: 400">While manual and programmatic gate configuration offers incredible safety, managing a matrix of dozens of test suites, mapping coverage gaps, and diagnosing complex failures can become a full-time task. To simplify this complexity, we have also released </span><b>Skills for Testing</b><span style="font-weight: 400"> within Agentforce Vibes.</span></p>
<p><span style="font-weight: 400">Four new Agentforce skills bring AI-assisted test management directly into your DevOps Center workflow, from configuring providers and quality gates to running suites, analyzing failures, and tracking fixes.</span></p>
<p><span style="font-weight: 400">These skills combine to act as an autonomous copilot for your release operations, allowing DevOps Center Testing managers to control the lifecycle through natural language interaction:</span></p>
<ul>
<li><code><span>dx-devops-test-pipeline-configure</span></code><br />
<b><span>What it does:</span></b><span> Configures test providers, syncs new suites into a pipeline, and assigns quality gates with pass-rate, severity, and essential-test rules to test suites on a pipeline stage. Instead of manually mapping criteria across complex tables, managers can instruct the agent to align the gate logic automatically.</span></li>
<li><code><span>dx-devops-test-suite-assignments-configure</span></code><br />
<b><span>What it does:</span></b><span> Recommends and manages DevOps Center test suite assignments for pipeline stages. Use this skill to recommend suites for a commit, assign or map suites to stages, or add/remove tests in a suite.</span></li>
<li><code><span>dx-devops-test-suite-run</span></code><br />
<b><span>What it does:</span></b><span> Triggers test suite execution on a specific pipeline stage, polls for results, and can automatically re-run a quality gate check after a developer resolves their code coverage gaps. This keeps the deployment train moving efficiently with automated validation loopbacks.</span></li>
<li><code><span>dx-devops-test-failures-analyze</span></code><br />
<b><span>What it does:</span></b><span> Analyzes DevOps Center test failures and Code Analyzer violations in plain language, failure category, offending file/class/method/line, rule violated, fix direction, and prioritized improvement suggestions (test-code vs production-code), then optionally creates a tracked fix WorkItem on explicit request.</span></li>
</ul>
<h2><b>How to get started</b></h2>
<p><span style="font-weight: 400">You can bring automated quality to your release management workflow in a few quick steps:</span></p>
<ol>
<li style="font-weight: 400"><span style="font-weight: 400">Locate the Tests tab: The automated testing feature is available within the DevOps Center application. Admins can open their DevOps Center pipeline to find the new native Tests management interface.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Add test providers: Configure one or more of the available test providers: Apex, Flow, and Code Analyzer.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Configure your quality gates: Define your testing thresholds. Decide which pipeline stages require mandatory Apex test passes, flow validations, or Code Analyzer scans.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Automate and scale: Review the developer</span><a href="https://help.salesforce.com/s/articleView?id=platform.devops_center_testing_setup.htm&amp;language=en_US&amp;type=5"><span style="font-weight: 400"> reference documentation</span></a><span style="font-weight: 400"> to connect your CLI scripts, repository webhooks, or Agentforce toolsets to the Headless 360 API.</span></li>
</ol>
<p><span style="font-weight: 400">By automating your testing lifecycle natively within DevOps Center and pairing it with Agentforce, you eliminate release anxiety, secure your digital supply chain, and empower your teams to ship high-quality features faster and smarter than ever before.</span></p>
<h2><b>Conclusion</b></h2>
<p><span style="font-weight: 400">DevOps Center Testing now enforces Apex, Flow, and Code Analyzer checks at each pipeline stage, and you can trigger the same gates from your existing CI tools via the CLI or REST API.</span></p>
<h2><b>Resources</b></h2>
<ul>
<li style="font-weight: 400"><a href="https://help.salesforce.com/s/articleView?id=platform.devops_center_testing_setup.htm&amp;type=5"><span style="font-weight: 400">Testing User Guide</span></a></li>
<li style="font-weight: 400"><a href="https://help.salesforce.com/s/articleView?id=release-notes.rn_deployment_devops_center_testing.htm&amp;release=262&amp;type=5"><span style="font-weight: 400">Release Notes</span></a></li>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_list.htm#:~:text=67.0%20and%20later.-,DevopsQualityGateRule,-Defines%20the%20criteria"><span style="font-weight: 400">Object References</span></a></li>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/guide/ci-cd.html#accelerate-your-github-cicd-integration"><span style="font-weight: 400">Code Analyzer</span></a><span style="font-weight: 400"> </span></li>
<li style="font-weight: 400"><a href="https://www.google.com/search?q=https://trailhead.salesforce.com/trailblazer-community/groups/0F94V000000HeS0SAK"><span style="font-weight: 400">DevOps Center Trailblazer Group</span></a></li>
<li style="font-weight: 400"><a href="https://help.salesforce.com/s/articleView?id=platform.devops_center_dx_inspector.htm&amp;language=en_US&amp;type=5"><span style="font-weight: 400">DX Inspector Documentation</span></a></li>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/docs/platform/salesforce-cli-reference/guide/cli_reference.html"><span style="font-weight: 400">Salesforce CLI Reference</span></a></li>
<li style="font-weight: 400"><a href="https://help.salesforce.com/s/articleView?id=platform.next_generation_devops_center.htm&amp;type=5"><span style="font-weight: 400">Next Generation DevOps Center documentation</span></a></li>
</ul>
<h2><b>About the Author</b></h2>
<p><b>Srikrishna Padmannagari</b><span style="font-weight: 400"> is a Senior Product Manager at Salesforce, where he builds tools that simplify ALM for the global developer community. He leads product for </span><b>Salesforce DX Inspector</b><span style="font-weight: 400">, </span><b>Testing</b><span style="font-weight: 400">, Code Analyzer focusing on making the Salesforce DX ecosystem more efficient, reliable, and developer-friendly. Follow Srikrishna on </span><a href="https://www.linkedin.com/in/srikrishnapadmannagari/"><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/08/shift-left-natively-testing-and-quality-gates-in-devops-center">Shift Left Natively: Testing and Quality Gates in DevOps 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/08/shift-left-natively-testing-and-quality-gates-in-devops-center/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206887</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260824140820/Generic-C-6-e1787605714286.png?w=1000" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260824140820/Generic-C-6-e1787605714286.png?w=1000" medium="image" />
	</item>
		<item>
		<title>新しいAgentforceメタデータと開発ライフサイクル</title>
		<link>https://developer.salesforce.com/blogs/2026/08/new-agentforce-metadata-and-development-lifecycle-jp</link>
		<comments>https://developer.salesforce.com/blogs/2026/08/new-agentforce-metadata-and-development-lifecycle-jp#respond</comments>
		<pubDate>Tue, 25 Aug 2026 12:03:40 +0000</pubDate>
		<dc:creator><![CDATA[Alba Rivas]]></dc:creator>
				<category><![CDATA[Agentforce]]></category>
		<category><![CDATA[App Development]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Developer Tooling]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Salesforce Releases]]></category>
		<category><![CDATA[Agent Script]]></category>
		<category><![CDATA[alm]]></category>
		<category><![CDATA[CI/CD]]></category>
		<category><![CDATA[GenAiPlannerBundle]]></category>
		<category><![CDATA[Metadata API]]></category>
		<category><![CDATA[salesforce developers]]></category>
		<category><![CDATA[Spring '26]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206904</guid>
		<description><![CDATA[<p>&#26032;&#12375;&#12356;&#12496;&#12540;&#12472;&#12519;&#12531;&#31649;&#29702;&#20184;&#12365;&#12513;&#12479;&#12487;&#12540;&#12479;&#12514;&#12487;&#12523;&#12392;&#12289;&#20154;&#38291;&#12364;&#35501;&#12415;&#12420;&#12377;&#12356;Agent Script&#12434;&#27963;&#29992;&#12375;&#12390;&#12289;CI/CD&#12497;&#12452;&#12503;&#12521;&#12452;&#12531;&#12434;&#21177;&#29575;&#21270;&#12375;&#12414;&#12375;&#12423;&#12358;&#12290;&#12496;&#12531;&#12489;&#12523;&#21270;&#12373;&#12428;&#12383;&#12450;&#12475;&#12483;&#12488;&#12364;&#12300;&#12464;&#12525;&#12540;&#12496;&#12523;&#12394;&#27874;&#21450;&#21177;&#26524;&#12301;&#12434;&#25490;&#38500;&#12375;&#12289;&#12500;&#12450;&#12524;&#12499;&#12517;&#12540;&#12434;&#31777;&#32032;&#21270;&#12377;&#12427;&#12371;&#12392;&#12391;&#12289;&#12424;&#12426;&#20449;&#38972;&#24615;&#12398;&#39640;&#12356;&#12456;&#12540;&#12472;&#12455;&#12531;&#12488;&#12398;&#12487;&#12503;&#12525;&#12452;&#12434;&#23455;&#29694;&#12377;&#12427;&#26041;&#27861;&#12434;&#23398;&#12403;&#12414;&#12375;&#12423;&#12358;&#12290;</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/08/new-agentforce-metadata-and-development-lifecycle-jp">新しいAgentforceメタデータと開発ライフサイクル</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<blockquote><p>※本記事は2026年5月14日に米国で公開された <a href="https://developer.salesforce.com/blogs/2026/05/new-agentforce-metadata-and-development-lifecycle">The New Agentforce Metadata and Development Lifecycle</a>の抄訳です。本記事の正式言語は英語であり、その内容および解釈については英語が優先されます。</p></blockquote>
<p><span style="font-weight: 400"></span><a href="https://help.salesforce.com/s/articleView?id=ai.agent_builder_intro.htm&amp;type=5"><span style="font-weight: 400">新しいAgentforce Builder</span></a><span style="font-weight: 400">（Spring ’26正式リリース）では、AIエージェントの作成とテストのエクスペリエンスが刷新されます。スピーディで「失敗しても安全」な環境が提供され、試行錯誤しながら複雑なロジックを改良できます。本番環境で稼働しているAIエージェントへの影響を心配する必要はありません。</span></p>
<p><span style="font-weight: 400">Salesforce開発者の皆さんなら、構築エクスペリエンスが新しくなると、たいていは内部の仕組みも変わることをご存じでしょう。今回、このスピード感がある、安全な作業環境をサポートするために、基盤となるメタデータも進化させる必要がありました。この記事では、新しい開発者ワークフロー、メタデータが変更された理由、デプロイ用にパッケージを構成する方法について、順を追って説明します。</span></p>
<h2><b>新しい開発ワークフロー – スクリプトからメタデータへ</b></h2>
<p><span style="font-weight: 400">メタデータの変更については、AIエージェント構築の新しい考え方を理解しておくとわかりやすくなるでしょう。新しいAgentforce Builderでは、開発者の「意図」（AIエージェントに実行させたいこと）と、エンジンの「実行」（有効なメタデータ）が明確に分離されます。</span></p>
<p><span style="font-weight: 400">AIエージェントの作成から公開までは、次のような流れで進みます。</span></p>
<ol>
<li><b><span>記述と構築</span></b><span> – Agentforce BuilderのUIを使用するか、</span><b><span>Agent Script</span></b><span>を使って、AIエージェントを作成します。人間が読んで理解できるこのスクリプトは、AIエージェントの設定を示す単一の</span><code><span>.agent</span></code><span>ファイルとして、新しい</span><code><span>AiAuthoringBundle</span></code><span>メタデータ型内に保存されます。この段階では、作業内容はドラフトの状態です。</span></li>
<li><b><span>改良とプレビュー</span></b><span> – プレビューモード（テストを組織のデータから安全に分離するシミュレーションモードなど）を使用して、ドラフトをテストします。</span></li>
<li><b><span>公開</span></b><span> – ドラフトの内容で問題ないと判断したら、そのバージョンをコミットします。</span><b><span>ここが非常に重要なポイントです。</span></b><span>コミットの段階で初めて、プラットフォームは</span><code>.agent</code><span>スクリプトを、AIエージェントの実行に実際に使われる有効な</span><code>Bot</code><span>メタデータと</span><code>GenAiPlannerBundle</code><span>メタデータに変換します。</span><i><span></span></i><span></span></li>
</ol>
<h2><b>メタデータ変更の理由 – ローカルアセットのバンドル化</b></h2>
<p>新しいビルダーで<a href="https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_genaiplannerbundle.htm"><u><code>GenAiPlannerBundle</code><span>メタデータ</span></u></a><span>の構成を変更したのはなぜかというと、分離を確保し、デプロイの信頼性を高める必要があったからです。</span><br />
<span></span></p>
<p><span>これまで、Agentforceアセットはグローバルでした。あるAIエージェントのために共有サブエージェントを変更すると、それが全体に波及し、そのサブエージェントを使用しているすべてのエージェントに即座に影響していました。これを解決するために導入したのが</span><b><span>ローカルアセット</span></b><span>（ローカルサブエージェントとローカルアクションを含む）です。ローカルアセットは、グローバルアセットを複製して作成され、特定のエージェントバージョンにひも付けられます。アセットがローカルになることで、他に影響を与えず安全に編集できます。</span><br />
<span></span></p>
<p><span>ローカルアセットは以前から利用可能でしたが、CI/CDパイプラインで完全にサポートするには、</span><code>GenAiPlannerBundle</code>メタデータを更新する必要がありました。これまで、エージェントメタデータは複数のメタデータ型に分散していました。新しい<code>GenAiPlannerBundle</code>で最も大きな変更は、「バンドル化」です。特定のバージョンに関連し、依存関係にあるすべてのエージェントアセットを、1つのフォルダー構造でデプロイして利用できるように、メタデータを再構成しました。これにより、デプロイエラーを防げるともに、エージェントがプレビュー時とまったく同じように動作するために必要なものを、すべて揃えられます。<i></i><b></b><i></i></p>
<h2><b>内部の仕組み – 新しいメタデータ構造</b></h2>
<p><span style="font-weight: 400">従来のようにファイルが分散することなく、各エージェントバージョンに固有のすべての要素が、ディレクトリ構造の中にすっきりとまとめられています。</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206308" >
			    <img decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260513105223/image3_7fea0a.png?w=594" class="postimages" width="594" height="1000" alt="plannerファイル、localActionsサブフォルダー、入力および出力用のschema.jsonファイルを含む、GenAiPlannerBundleのディレクトリ構造を示す図" />
			  </span>
			</p>
<p><code>AiAuthoringBundle</code><span>は、AIエージェントの設計時のアーティファクトをすべて含むディレクトリです。このバンドルでは、</span><code>AgentName_1</code><span>や</span><code>AgentName_2</code><span>のように複数のバージョン付きサブディレクトリを使用でき、それぞれが独自の</span><code>.agent</code><span>ファイルと</span><code>.bundle-meta.xml</code><span>記述子を持ちます。</span><span>これらのサブディレクトリは、AIエージェントのドラフトやコミット済みバージョンなど、異なるライフサイクル状態に対応します。各バージョンには、次のファイルが含まれます。</span></p>
<ul>
<li><span></span><code>.agent</code><span>ファイルには、Agent Scriptで記述されたAIエージェントの設定が保持されます。これには、名前、ラベル、説明、システム指示、サブエージェント定義、推論指示、変数、条件分岐、ツール/アクション参照が含まれます。</span></li>
<li><span>メタデータ記述子（</span><code>.bundle-meta.xml</code><span>）は、bundleType（例：AGENT）と、その記述子が参照するエージェントバージョンを宣言します。</span></li>
</ul>
<p><code><span>Bot</span></code><span>には、AIエージェントの種類や、プライベートデータをログに記録するかどうかといった設定など、AIエージェントのすべてのバージョンに共通する情報が含まれます。また、Botはエージェントレベルのコンテキスト変数も保持します。これは、各</span><code><span>BotVersion</span></code><span>内に存在する会話変数とは異なります。</span><code><span>BotVersion</span></code><span>の詳細には、会話変数、ウェルカムメッセージ、会話転送時のメッセージが含まれます。</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206310" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260513105333/image1_7095ac.png?w=958" class="postimages" width="958" height="626" alt="plannerバンドルのディレクトリ構造と、plannerActionディレクトリの内容を示す図" />
			  </span>
			</p>
<p><code></code><code>GenAiPlannerBundle</code>は、AIエージェントの公開済みバージョンごとに関連するデータをすべて保持します。各バージョンには、次の要素が含まれます。</p>
<ul>
<li><code>.genAiPlannerBundle</code>は、AIエージェントの実行時設定（サブエージェント、指示、アクション、オーケストレーションロジック）を含む、中核となるメタデータファイルです。</li>
<li><code>agentGraph</code>は、サブエージェント間のすべての遷移と条件を記述した<code>.json</code>ファイルです。</li>
<li><code>agentScript</code>は、そのバージョンのAgent Scriptをエンコードしたコピーです。これは同期検出を目的として保持されるスナップショットです。このスナップショットにより、スクリプトが公開済みまたはコミット済みメタデータと同期していない場合に、Agentforce Builderがユーザーに通知できます。</li>
<li><code>plannerActions</code><span style="color: #4a4a4a;font-family: &apos;Salesforce Sans&apos;, Arial, sans-serif">は、特定のサブエージェントにひも付かない、エージェントレベルのアクションです。</span></li>
<li><code>localActions</code>は、サブエージェント単位でスコープが限定されたアクションで、それぞれのサブエージェントフォルダーの下にネストされます。<code>input/schema.json</code>ファイルと<code>output/schema.json</code>ファイルが、各アクションの型付きパラメーターを定義します。</li>
</ul>
<p>注 – <code>GenAiPlannerBundle</code>のバージョンはコミットされた順に自動で番号が付けられるため、<code>AiAuthoringBundle</code>のバージョン番号と一致するとは限りません。</p>
<p>バージョンをコミットすると、<code>Bot</code>メタデータと<code>GenAiPlannerBundle</code>メタデータはどちらも自動的に作成されます。また、<code>AiAuthoringBundle</code>、<code>agentScript</code><span></span><span>、</span><code>agentGraph</code>は、新しいAgentforce Builderで作成されたAIエージェントのメタデータにのみ含まれます。</p>
<h3><b></b><b><code>GenAiPlannerBundle</code></b><b> XMLの例</b></h3>
<p><span style="font-weight: 400">ローカル化されたサブエージェントとアクションをXMLの例で見てみましょう。</span></p>
<pre class="wp-block-code language-xml">&lt;GenAiPlannerBundle&gt;
   &lt;description&gt;新しいAIエージェントの説明&lt;/description&gt;
   &lt;localTopicLinks&gt;
       &lt;genAiPluginName&gt;Retrieve_data_from_the_Knowledge_Base_16jxx0000001234&lt;/genAiPluginName&gt;
   &lt;/localTopicLinks&gt;
   &lt;localTopics&gt;
       &lt;fullName&gt;Retrieve_data_from_the_Knowledge_Base_16jxx0000001234&lt;/fullName&gt;
       &lt;description&gt;リトリーバーアクションを使用する&lt;/description&gt;
       &lt;pluginType&gt;Topic&lt;/pluginType&gt;
       &lt;masterLabel&gt;ナレッジベースからデータを取得&lt;/masterLabel&gt;
       &lt;genAiPluginInstructions&gt;
           &lt;description&gt;あなたはAIエージェントです。&lt;/description&gt;
           &lt;sortOrder&gt;1&lt;/sortOrder&gt;
       &lt;/genAiPluginInstructions&gt;
       &lt;localActionLinks&gt;
            &lt;functionName&gt;File_test_retriever_179xx0000001234&lt;/functionName&gt;
       &lt;/localActionLinks&gt;
       &lt;localActions&gt;
           &lt;fullName&gt;File_test_retriever_179xx0000001234&lt;/fullName&gt;
           &lt;invocationTarget&gt;File_test_retriever_1234&lt;/invocationTarget&gt;
           &lt;invocationTargetType&gt;apex:testRetriever&lt;/invocationTargetType&gt;
           &lt;source&gt;File_test_retriever&lt;/source&gt;
       &lt;/localActions&gt;
   &lt;/localTopics&gt;
   &lt;plannerType&gt;AiCopilot__ReAct&lt;/plannerType&gt;
&lt;/GenAiPlannerBundle&gt;</pre>
<p><code>&lt;localTopics&gt;</code>ブロックでは、サブエージェントのすべての設定を定義します。一意のAPI名、説明、プラグイン型、決定的な順序で並べられた指示、そのサブエージェントで利用可能なすべてのローカルアクションなどです。また、元のサブエージェントへのリファレンスが含まれる場合もあります。</p>
<p><code>&lt;localActions&gt;</code>ブロックでは、アクション名、マスターラベル、呼び出し先とその種別を定義します。さらに、必要に応じて、クローン元のグローバルアクションへの<code>source</code>リファレンスを含める場合もあります。確認時の動作や読み込み中テキストの設定など、UX関連の追加設定が含まれる場合もあります。</p>
<h3><b>新しいメタデータモデルに対応したpackage.xmlの例</b></h3>
<p>新しいAgentforce Builderで構築したAIエージェントを正常に取得し、デプロイするには、<code>package.xml</code>に新しいバンドル型を含める必要があります。以下は、Spring ’26のメタデータ構造を前提として作成されたマニフェストの例です。</p>
<pre class="wp-block-code language-xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;Package xmlns="http://soap.sforce.com/2006/04/metadata"&gt;
    &lt;types&gt;
        &lt;members&gt;*&lt;/members&gt;
        &lt;name&gt;GenAiFunction&lt;/name&gt;
    &lt;/types&gt;
    &lt;types&gt;
        &lt;members&gt;*&lt;/members&gt;
        &lt;name&gt;Bot&lt;/name&gt;
    &lt;/types&gt;
    &lt;types&gt;
        &lt;members&gt;*&lt;/members&gt;
        &lt;name&gt;GenAiPlannerBundle&lt;/name&gt;
    &lt;/types&gt;
    &lt;types&gt;
        &lt;members&gt;*&lt;/members&gt;
        &lt;name&gt;GenAiPlugin&lt;/name&gt;
    &lt;/types&gt;
    &lt;types&gt;
        &lt;members&gt;*&lt;/members&gt;
        &lt;name&gt;AiAuthoringBundle&lt;/name&gt;
    &lt;/types&gt;
    &lt;version&gt;66.0&lt;/version&gt;
&lt;/Package&gt;</pre>
<p><span style="font-weight: 400">注 – このマニフェストではAPIバージョン66.0を使用しています。この例のGenAiPlannerBundleと新しいエージェントメタデータ型をサポートするには、このバージョンが必要です。</span></p>
<h3><b>新しいAgentforce Builderで開発するためのヒント</b></h3>
<p><span style="font-weight: 400">この新しいアーキテクチャーによって改善された開発ライフサイクルを活用する方法を、2つ紹介します。</span></p>
<ul>
<li><b>人間が読めるスクリプトファイルを使って、コードレビューを効率化する。</b>従来のAgentforce Builderでは、AIエージェントの変更をレビューするには、プルリクエスト内に分散した複雑なXMLファイルを見比べる必要がありました。新しいアーキテクチャーでは、人が読んで理解できる<code>.agent</code>スクリプトファイルを比較できます。これにより、ピアレビューが大幅にスピードアップし、内容も理解しやすくなります。</li>
<li><b></b><code>AiAuthoringBundle</code><span></span><b><span></span></b><span></span><b><span>を使用して、CI/CDをシンプルにする。</span></b><span>ほとんどのパイプラインでは、ソース管理に</span><code>AiAuthoringBundle</code><span></span><span><span><span>を保持するだけで済みます。新しい組織でそのAIエージェントが必要になったら、デプロイし、バージョンをコミットして実行時メタデータを生成し、最後に有効化します。これは、次のコマンドを使用して自動的に実行できます。</span></span></span><br />
<code>sf project deploy start --metadata AiAuthoringBundle --target-org my-org</code><br />
<code>sf agent publish authoring-bundle --api-name MyAuthoringBundle --target-org my-org<br />
</code><code><br />
sf agent activate --api-name MyAuthoringBundle --version 2 --target-org my-org</code><br />
手動のステップを必要としない、完全に自動のパイプラインを構築したい場合は、<code>AiAuthoringBundle</code>と<code>GenAiPlannerBundle</code><span>の両方をソース管理に保持し、同時にデプロイすることで、コミット済みの状態にできます。</span>システムは、デプロイされるスクリプトと事前に生成されたメタデータをあわせて認識します。手動のコミット手順がすべてにスキップされ、エージェントはデプロイ直後に稼働状態になります。<br />
<code>sf project deploy start --metadata AiAuthoringBundle,GenAiPlannerBundle --target-org my-org</code></li>
</ul>
<h2><b>まとめ</b></h2>
<p><span style="font-weight: 400">新しいAgentforce Builderでは、メタデータ構造がバンドル化されたことで、影響範囲を分離し、バージョンを安全に維持しながらAIエージェントを作成できるようになりました。この構造により、メタデータが整理され、コードレビューが簡単になり、デプロイの信頼性も向上します。 </span></p>
<p><span style="font-weight: 400">さっそく、Agent Scriptと新しいAgentforce Builderを使ってみましょう。</span><a href="https://trailhead.salesforce.com/content/learn/projects/create-an-agent-using-pro-code-tools/create-an-agent-from-your-dx-project"><span style="font-weight: 400">こちらのTrailheadモジュール</span></a><span style="font-weight: 400">では、Agent Scriptを使用したエージェントの作成について学習できます。また、Agent Scriptの基本を解説した</span><a href="https://developer.salesforce.com/blogs/2026/02/agent-script-decoded-intro-to-agent-script-language-fundamentals"><span style="font-weight: 400">ブログ</span></a><span style="font-weight: 400">や、</span><a href="https://www.youtube.com/playlist?list=PLgIMQe2PKPSJNLEQTPkr06gKhjnHgI1Jb"><span style="font-weight: 400">YouTubeのAgent Script Decodedシリーズ</span></a><span style="font-weight: 400">（英語）もご覧ください。</span><a href="https://developer.salesforce.com/events#upcomingevents"><span style="font-weight: 400">Agentforce Builderのワークショップ</span></a><span style="font-weight: 400">（英語）も随時開催していますので、ぜひ参加してみてください。</span></p>
<h2><b>関連情報</b></h2>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">リリースノート</span>
<ul>
<li style="font-weight: 400"><a href="https://help.salesforce.com/s/articleView?id=ai.agent_versions_lifecycle.htm&amp;type=5"><span style="font-weight: 400">エージェントのバージョン管理と編集</span></a></li>
<li style="font-weight: 400"><a href="https://help.salesforce.com/s/articleView?id=release-notes.rn_einstein_agentforce_versioning_improvements.htm&amp;release=256&amp;type=5"><span style="font-weight: 400">改良されたエージェントバージョン機能を使用したエージェントのテストとカスタマイズ（英語）</span></a></li>
</ul>
</li>
<li style="font-weight: 400"><span style="font-weight: 400">ヘルプドキュメント</span>
<ul>
<li style="font-weight: 400"><a href="https://help.salesforce.com/s/articleView?id=ai.copilot_actions_edit_reference.htm&amp;type=5"><span style="font-weight: 400">標準エージェントアクションの参照アクションの編集 </span></a></li>
</ul>
</li>
<li style="font-weight: 400"><span style="font-weight: 400">パッケージ</span>
<ul>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/docs/atlas.en-us.pkg2_dev.meta/pkg2_dev/dev2gp_packageable_agentforce_md.htm"><span style="font-weight: 400">Agentforceメタデータコンポーネントのパッケージ化（英語）</span></a></li>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/docs/atlas.en-us.pkg2_dev.meta/pkg2_dev/dev2gp_package_agent_templates.htm"><span style="font-weight: 400">スクラッチ組織を使用したAIエージェントテンプレートの開発とパッケージ化（英語） </span></a></li>
</ul>
</li>
<li style="font-weight: 400"><span style="font-weight: 400">メタデータの更新</span>
<ul>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_genaiplannerbundle.htm"><span style="font-weight: 400">GenAiPlannerBundle</span></a></li>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_genaifunction.htm"><span style="font-weight: 400">GenAiFunction</span></a></li>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_genaiplugin.htm"><span style="font-weight: 400">GenAiPlugin</span></a></li>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_genaiplugininstructiondef.htm"><span style="font-weight: 400">GenAiPluginInstructionDef</span></a></li>
</ul>
</li>
</ul>
<p><b>Shreyas</b><span style="font-weight: 400">は、サンフランシスコのSalesforce AIでリードソフトウェアエンジニアを務めており、Institute of Analyticsのフェロー（FIoA）でもあります。Agentforce Core Platformチームの中心メンバーとして、AgentforceにエンタープライズレベルのALMを導入するため、Agentforceのバージョン管理システムとローカルアセット構成の変更を共同で設計し、主導しました。</span><span style="font-weight: 400">LinkedInのプロフィールは</span><a href="https://www.linkedin.com/in/rshreyas2/"><span style="font-weight: 400">こちら</span></a><span style="font-weight: 400">。</span></p>
<p><b>Alba Rivas</b><span style="font-weight: 400">は、Salesforceのプリンシパルデベロッパーアドボケイトです。LinkedInのプロフィールは</span><a href="https://www.linkedin.com/in/alba-rivas/"><span style="font-weight: 400">こちら</span></a><span style="font-weight: 400">。</span></p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/08/new-agentforce-metadata-and-development-lifecycle-jp">新しい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/08/new-agentforce-metadata-and-development-lifecycle-jp/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206904</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260514111122/DoubleHeadshot-4-1-e1778782304152.png?w=1000" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260514111122/DoubleHeadshot-4-1-e1778782304152.png?w=1000" medium="image" />
	</item>
		<item>
		<title>Claude CodeでSalesforceエージェントスキルを構築する</title>
		<link>https://developer.salesforce.com/blogs/2026/08/build-a-salesforce-agent-skill-with-claude-code-jp</link>
		<comments>https://developer.salesforce.com/blogs/2026/08/build-a-salesforce-agent-skill-with-claude-code-jp#respond</comments>
		<pubDate>Tue, 25 Aug 2026 10:16:09 +0000</pubDate>
		<dc:creator><![CDATA[Dave Norris]]></dc:creator>
				<category><![CDATA[Agentforce]]></category>
		<category><![CDATA[Agentforce Vibes]]></category>
		<category><![CDATA[App Development]]></category>
		<category><![CDATA[Developer Tooling]]></category>
		<category><![CDATA[ai]]></category>
		<category><![CDATA[Apex]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[Claude Code]]></category>
		<category><![CDATA[developer tooling]]></category>
		<category><![CDATA[LLMs]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206896</guid>
		<description><![CDATA[<p>&#27083;&#36896;&#21270;&#12373;&#12428;&#12383;&#12527;&#12540;&#12463;&#12501;&#12525;&#12540;&#12289;&#12467;&#12540;&#12489;&#12486;&#12531;&#12503;&#12524;&#12540;&#12488;&#12289;&#33258;&#21205;&#26908;&#35388;&#12484;&#12540;&#12523;&#12434;&#27963;&#29992;&#12375;&#12289;Salesforce&#12456;&#12467;&#12471;&#12473;&#12486;&#12512;&#20840;&#20307;&#12391;&#19968;&#36011;&#12375;&#12390;&#39640;&#21697;&#36074;&#12394;&#12467;&#12540;&#12489;&#12434;&#20316;&#25104;&#12377;&#12427;&#12383;&#12417;&#12398;&#12467;&#12540;&#12487;&#12451;&#12531;&#12464;&#12473;&#12461;&#12523;&#12434;&#36523;&#12395;&#12388;&#12369;&#12427;&#26041;&#27861;&#12434;&#23398;&#12403;&#12414;&#12375;&#12423;&#12358;&#12290;</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/08/build-a-salesforce-agent-skill-with-claude-code-jp">Claude CodeでSalesforceエージェントスキルを構築する</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<blockquote><p>※本記事は2026年5月29日に米国で公開された <a href="https://developer.salesforce.com/blogs/2026/05/build-a-salesforce-agent-skill-with-claude-code">Build a Salesforce Agent Skill with Claude Code</a>の抄訳です。本記事の正式言語は英語であり、その内容および解釈については英語が優先されます。</p></blockquote>
<p><span style="font-weight: 400">AIにコードを書かせるのは簡単です。とはいえ、セキュリティレビューに合格し、ガバナ制限を守り、指定したフレームワークに従い、静的解析でも高い評価を得られるコードを安定して生成させるとなると、そう簡単にはいきません。</span><a href="https://agentskills.io/home"><span style="font-weight: 400">エージェントスキル</span></a><span style="font-weight: 400">（英語）を使えば、この問題を解決できます。エージェントスキルとは、開発チームが定義する「本番品質」を、エージェントが従い、検証ツールが強制できる形に落とし込んだ、構造化されたプロンプトパッケージです。LLMの出力には確率的なばらつきがあるため、どうしても例外的な結果が生じます。それを想定して検出するのが、このアーキテクチャーです。</span></p>
<p><span style="font-weight: 400">この記事では、Apexを例に、Salesforceエージェントスキルの構造を詳しく見ていきます。わかりやすいように、Claude Codeを使って具体的な例を紹介しますが、ここで取り上げる原則はどのAIエージェントにも適用できます。エージェントスキルとは何か、プロジェクトの構造、最初のスキルの作成方法について、順を追って説明していきます。</span></p>
<h2><span style="font-weight: 400">エージェントスキルとは</span></h2>
<p><span style="font-weight: 400">エージェントスキルとは、Claudeを汎用的なアシスタントではなく、スペシャリストとして使えるようにするために構造化されたプロンプトパッケージです。スキルでは、モデルの学習データだけに頼るのではなく、明確に定義されたワークフロー、リファレンス、コードテンプレート、自動検証ツールを用意します。スキルが有効化されると、これらがコンテキストに読み込まれます。</span></p>
<p><span style="font-weight: 400">Claudeの基盤である大規模言語モデル（LLM）は、Apex、LWC、SOQLといったSalesforceエコシステムのプログラミング言語をすでに習得しています。しかし、プログラミング言語を理解しているからといって、必ずしもベストプラクティスに沿った高品質なコードを安定して生成できるわけではありません。スキルは、これを可能にします。</span></p>
<p><span style="font-weight: 400">各スキルは、次のような一定の構造を持つフォルダー内に配置されます。</span></p>
<pre>skills/authoring-apex/
├── SKILL.md              # 実行ルール
├── references/           # デシジョンツリー、パターン、ガードレール
├── assets/               # サンプルコード
└── hooks/scripts/        # Python検証ツール
</pre>
<p><span>最低限必要なのは、</span><code>SKILL.md</code><span>です。これは、スキルの有効化時にClaudeが最初に参照するファイルです。その他の要素は、スキルの成長に応じて追加する足場となります。まずは</span><a href="http://skill.md"><u><code>SKILL.md</code></u></a><span>と参照ドキュメントを1つずつ用意し、指示だけではなく、仕組みによってルールを徹底したい段階でフックを追加するとよいでしょう。</span></p>
<p><span>スキルは、フロントマターにもとづいて有効化されます。フロントマターは、Markdownファイルの先頭で区切り記号「</span><code>---</code><span>」の間に記述されるYAML形式のメタデータブロックです。フロントマターはコンテンツとして表示されず、機械が読み取れる設定情報として使用されます。フロントマターは、どのような場合にそのスキルを有効にするかをエージェントに示します。nameフィールドでスキルを識別し、descriptionフィールドには、現在のタスクにこのスキルが適しているかどうかを判断するためのトリガールールを記述します。 </span></p>
<p><span>以下の例では、descriptionで</span><code>TRIGGER when</code><span> / </span><code>DO NOT TRIGGER when</code><span>という構造を使用して、スキルを有効にする条件と有効にしない条件の両方をエージェントに示しています。有効化の条件だけをモデルに伝えると、「このSOQLはApexコードの作成作業としてApexスキルで扱うのか、それともSOQLスキルで扱うのか」といったあいまいさが生じ、誤ったスキルが有効化されることがあります。この形式を使えば、そうしたあいまいさを排除できます。</span></p>
<pre language="yaml">---
name: authoring-apex
description: &gt;
  TRIGGER when: ユーザーがSalesforce Apexコードを作成、編集、またはレビューする場合 — 
  対象は、サービスクラス、セレクタークラス、
  トリガーハンドラー、テストクラス、バッチジョブ、Queueableクラス、
  呼び出し可能メソッド、Apex RESTエンドポイントを含む.clsファイルまたは.triggerファイル。
  DO NOT TRIGGER when: ユーザーがLWC JavaScript、Flow XML、
  単独のSOQLクエリーを扱う場合、または既存のテストを実行する場合。
---
</pre>
<p>この例は簡略化されたもので、実際には、descriptionにはもっと包括的な情報を記述します。すべてのクラス種別（<code>Schedulable</code>、<code>AuraEnabled</code>、<code>HttpCalloutMock</code>）を列挙し、除外するケースごとに、どのスキルが処理するかを明記します（LWC JavaScriptには「authoring-lwcを使用」など）。境界を具体的に定義するほど、誤ったスキルの有効化を減らせます。</p>
<p>条件に一致するタスクが検出されると、Claudeは<code>SKILL.md</code>を読み込み、ワークフローに従います。プロンプトで<code>/skill-name</code>を指定して、スキルを手動で有効化することもできます。どちらの場合も、ワークフロー、リファレンス、テンプレートを含むスキルのコンテキスト全体が自動的に組み込まれます。<code>SKILL.md</code>の内容を会話に貼り付ける必要はありません。</p>
<p><span>スキルの形式自体（フロントマターを含む</span><span></span><code>SKILL.md</code><span>、リファレンス、アセット）は、AnthropicがApache 2.0の下で管理している</span><a href="https://agentskills.io/home"><u>オープン仕様</u></a><span>（英語）で、コミュニティも開発に参加できます。作成した</span><span></span><code>SKILL.md</code><span>、リファレンス、テンプレートは、別の環境でも利用できます。フックの仕組み（PostToolUseライフサイクルイベントを含むhooks.yaml）はClaude Code固有のものです。別のエージェントランタイムを使用する場合は、検証を別の方法で組み込むことになりますが、スキルの内容はそのまま移行できます。そのため、スキルは特定の実行環境に依存しない、いわばヘッドレスなものになります。Agentforce Vibes、Claude Code、Cursor、Visual Studio Code、Gemini CLI、OpenAI Codex、Windsurf、Roo Code、Gooseのほか、このオープン仕様をサポートする30以上のエージェントで使用できます。</span></p>
<h2><span style="font-weight: 400">エージェントスキルの構造</span></h2>
<h3><span style="font-weight: 400">SKILL.md – 実行ルール</span></h3>
<p><span style="font-weight: 400">スキルを使用する際に従う重要なワークフローです。手順は変更できず、各フェーズには厳格な終了条件が設定されています。以下に、その構造を示す簡略化した例を紹介します。実際の</span><a href="http://skill.md"><span style="font-weight: 400">SKILL.md</span></a><span style="font-weight: 400">（英語）では各フェーズをさらに詳しく記述しますが、終了条件を伴うフェーズを順番に並べるという構造は同じです。</span></p>
<pre language="markdown">このワークフローを順番どおりに実行してください。ステップの省略、結合、順序変更は禁止します。
行き詰まった場合は停止し、不足しているコンテキストを確認してください。該当なしの場合は、
レポートで「N/A」と記載し、その理由を1行で示してください。

## 必須の入力

作成に入る前に、以下を収集または推測する：

- クラス種別（サービス、セレクター、バッチ、Queueable、Invocable、トリガーハンドラー）
- 対象となるオブジェクトとビジネス目標
- デフォルトの共有設定（理由がある場合を除き`with sharing`）
- すでに使用中のトリガーフレームワーク（または明示的に選択されたもの）

フェーズの構成:

### フェーズ1 — 作成
1. **プロジェクト規約を確認する** — 既存のパターン、トリガー
     フレームワーク、命名スタイルを調べる
2. **要件を満たす最小のパターンを選択する**:

  | 要件                  | パターン                              |
  | ------------------ | -------------------------------------- |
  | ビジネスロジック       | サービスクラス                          |
  | データアクセス         | セレクタークラス                        |
  | トリガーロジック        | トリガーハンドラー（フレームワークが必要）　|
  | Flowとの連携        | @InvocableMethod                       |
  | 一括処理             | Batch Apex                            |
  | 非同期処理          | Queueable                               |

3. 作成に入る前に、`assets/`内の**対応するテンプレートを確認する**
4. **ガードレールに従って作成する** — 以下の「ルール」セクションにあるすべてのルールを適用する
5. **テストクラスを生成する** — テストスキルに委任する

### フェーズ2 — 検証

6. **Code Analyzerを実行する** — すべてのブロッキング違反を修正し、クリーンになるまで再実行する
7. **テストを実行する** — 合否とコードカバー率を記録する

### フェーズ3 — レポート

8. **報告する** — ファイル、設計上の判断、アナライザー出力、テスト結果、デプロイメモ

</pre>
<p><span style="font-weight: 400">フェーズが適用されない場合、ClaudeはそのフェーズをN/Aとして記録し、理由を記す必要があります。これは、「順序や完全性が重要な場合は、番号付きリストを使って、指示を連続したステップとして示す」というAnthropicのベストプラクティスに対応しています。</span></p>
<h3><span style="font-weight: 400">references/: ナレッジライブラリ</span></h3>
<p><span style="font-weight: 400">referencesは、一般的な学習では一貫した対処ができない、特定の失敗モードに対処するための参照ドキュメントです。つい情報を詰め込んでしまいがちなので、以下にAnthropicの</span><a href="https://platform.claude.com/docs/en/docs/build-with-claude/prompt-engineering/claude-prompting-best-practices"><span style="font-weight: 400">ベストプラクティス</span></a><span style="font-weight: 400">をいくつか示します。</span></p>
<table>
<tbody>
<tr>
<td><b>ベストプラクティス</b></td>
<td><b>理由</b></td>
<td><b>Apexの例</b></td>
</tr>
<tr>
<td><span style="font-weight: 400">ファイルサイズ</span></td>
<td><span style="font-weight: 400">ドキュメントが大きくなるほど、Claudeが重視するポイントに偏りが生じます。短く、目的が明確なファイルのほうが、安定して注意を向けられます。</span></td>
<td><span style="font-weight: 400">関心ごとに分けます。コアパターン（Factory、Strategy、セレクター、サービス）は1つのファイルにまとめ、高度なパターン（Unit of Work、ドメインモデル、Facade）は別のファイルに分けます。</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">階層構造</span></td>
<td><span style="font-weight: 400">目次と見出しがあると、Claudeがすべてを読まなくても関連するセクションを見つけられます。 </span></td>
<td><span style="font-weight: 400">SKILL.mdで「作成前にbest-practices.mdを読む」と指示しておくと、Claudeはファイル全体を確認することなく、必要な見出しに移動できます。</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">1セクションにつき1つのルール</span></td>
<td><span style="font-weight: 400">各セクションのポイントを1つに絞ると、適用されるルールからあいまいさを排除できます。</span></td>
<td><span style="font-weight: 400">「SOQL in Loops」という見出しのセクションなら、ループ内のSOQLだけを扱い、DMLや共有設定、null安全性は扱いません。</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">短いセクションを数多く</span></td>
<td><span style="font-weight: 400">各セクションを自己完結させる（約20～40行）ことで、Claudeはドキュメント全体を読み込まずに1つのルールを適用できます。</span></td>
<td><span style="font-weight: 400">アンチパターンであれば、1項目ごとに、見出し、「失敗する理由」の説明、BAD（悪い例）コードブロック、修正方法、GOOD（良い例）コードブロックを1つずつ用意します。</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">抽象的ではなく具体的に</span></td>
<td><span style="font-weight: 400">BAD/GOODのペアは、実質的にfew-shotの例として機能します。Anthropicは、例は「出力を方向付ける最も信頼できる方法の1つ」だと述べています。抽象的なルール（「ガバナ制限を避ける」）だと解釈に幅が出ますが、具体的なペアであれば振る舞いが安定します。</span></td>
<td><span style="font-weight: 400">// BAD: 1回の反復につきSOQLを1回実行。レコード101件目で100件のクエリー制限を超過する。</span></p>
<p><span style="font-weight: 400"></span></p>
<p><span style="font-weight: 400">// GOOD: SOQLの実行は全体で1回。</span></p>
<p><span style="font-weight: 400"></span></td>
</tr>
<tr>
<td><span style="font-weight: 400">命令よりも理由と結果を示す</span></td>
<td><span style="font-weight: 400">「Xは禁止」と伝えるより、「XはYという理由で失敗する」と示すほうが効果的です。Anthropicは、「理由を説明することで、Claudeが未知のケースにも応用できるようになる」と述べています。Claudeは理由がわかれば、例とは異なって見えるパターンにも同じルールを適用します。</span></td>
<td><span style="font-weight: 400">「Salesforceでは、1トランザクションにつきDMLステートメントは150件までしか許可されません。200件のレコードに対するトリガーでループ内にDMLを書くと、151件目のレコードで150件の上限を超過し、バッチ全体がロールバックされます」</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">肯定形で表現する</span></td>
<td><span style="font-weight: 400">「Xをしてはいけない」という表現では、何をすべきかをClaudeが推測しなければなりません。期待する動作を直接示すことで、Claudeが目指すべき目標を1つに絞れます。</span></td>
<td><span style="font-weight: 400">すべてのクラスでsharingを明示的に宣言し、ユーザー向けロジックにはwith sharingを、両方のコンテキストから呼び出されるユーティリティクラスにはinherited sharingを使用します。</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">さまざまな例</span></td>
<td><span style="font-weight: 400">Claudeが特定の形だけに引きずられないよう、エッジケースも扱います。Anthropicは、限定的なパターンマッチングを避けるために、3～5個の多様な例を示すことを推奨しています。</span></td>
<td><code>selector.cls</code><span>では、</span><code>getByIds</code><span>（一括取得）、</span><code>getByName</code><span>（サニタイズを伴うLIKE）、</span><code>getWithContacts</code><span>（親-子サブクエリー）、</span><code>getContactsWithAccount</code><span>（子-親クエリー）の4つのメソッドを示せます。同じパターンを4つの形で示せます。これにより、Claudeは「1つのクエリーメソッド」ではなく、「セレクター」という概念を学びます。</span></td>
</tr>
</tbody>
</table>
<p><code>authoring-apex</code>スキルでは、どのような参照ファイルを含めるとよいかを見てみましょう。</p>
<table>
<tbody>
<tr>
<td><b>リファレンス</b></td>
<td><b>ドキュメントの内容</b></td>
<td><b>この情報がない場合に起こる問題</b></td>
</tr>
<tr>
<td><code>best-practices.md</code></td>
<td><span style="font-weight: 400">コーディング規約（4スペースインデント、120文字以内の行）、命名規則、ApexDoc要件、APIバージョン管理、一般的なガイダンス</span></td>
<td><span style="font-weight: 400">プロジェクト規約とのずれ — Claudeは正しく動くコードを生成しますが、チームの既存のスタイルには合っていません。</span><i><span style="font-weight: 400"></span></i><span style="font-weight: 400"></span></td>
</tr>
<tr>
<td><code>design-patterns.md</code></td>
<td><span style="font-weight: 400">Factory、Strategy、セレクター、サービス、バッチ、Queueable、Unit of Work、ドメインモデルなど、各パターンを選ぶためのデシジョンツリー。各パターンに「使用する場面」の表を用意して、Claudeが最も一般的なパターンをデフォルトで選ばないようにします。</span></td>
<td><span style="font-weight: 400">この情報がないと、セレクターやStrategyのほうが適している場面でも、Claudeはすべてをサービスクラスとして作成する傾向があります。</span></td>
</tr>
<tr>
<td><code>anti-patterns.md</code></td>
<td><span style="font-weight: 400">Apexでよくあるミスをまとめます。各項目には、BAD/GOODのコードペアと、スケール時に失敗する理由を説明します。</span><i><span style="font-weight: 400"></span></i><span style="font-weight: 400"></span></td>
<td><span style="font-weight: 400">Claudeが人間の開発者よりも起こしやすい、一般的なミスを扱います（例：</span><span style="font-weight: 400">AccessLevel</span><span style="font-weight: 400">の指定なしに</span><span style="font-weight: 400">database.query()</span><span style="font-weight: 400">を生成する。</span><span style="font-weight: 400">Assert.areEqual</span><span style="font-weight: 400">ではなく従来の</span><span style="font-weight: 400">System.assertEquals</span><span style="font-weight: 400">を使用するなど）。</span></td>
</tr>
<tr>
<td><code>security-guide.md</code></td>
<td><span style="font-weight: 400"></span><span style="font-weight: 400">USER_MODE</span><span style="font-weight: 400">（API 56以降）を使用したCRUD/FLSの適用、下位互換性のための</span><span style="font-weight: 400">Security.stripInaccessible()</span><span style="font-weight: 400">、SOQLインジェクション対策、XSS対策パターン。</span></td>
<td><span style="font-weight: 400">この情報がないと、Claudeは管理者プロファイルのユーザーでは動作しても、標準ユーザーでは</span><span style="font-weight: 400">INSUFFICIENT_ACCESS</span><span style="font-weight: 400">が発生するコードを生成することがあります。</span></td>
</tr>
<tr>
<td><code>transaction-security-policy.md</code></td>
<td><span style="font-weight: 400">特殊なケース向けのリファレンス。この例では、</span><span style="font-weight: 400">TxnSecurity.EventCondition</span><span style="font-weight: 400">の実装（拡張トランザクションセキュリティ）を扱います。これらのクラスは</span><span style="font-weight: 400">global</span><span style="font-weight: 400">であり、システムコンテキストで実行され、監視イベントを評価します。</span></td>
<td><span style="font-weight: 400">これらは特殊なケースです。共有設定や可視性についての一般的なルールは、これらのクラスには当てはまりません。このリファレンスがないと、Claudeが</span><span style="font-weight: 400">with sharing</span><span style="font-weight: 400">を適用してしまい、こうした種類のクラスが機能しなくなります。</span></td>
</tr>
</tbody>
</table>
<p><span style="font-weight: 400">このようなリファレンスの構成は、Anthropicが言う「指示の背景にある文脈と動機を提供する」という方法を活用したものです。単に「何をすべきか」だけを示すのではなく、「なぜそうするのか」も説明することで、Claudeが機械的にパターンマッチングするのではなく、未知の状況にも正しく応用できるようにします。</span><i><span style="font-weight: 400"></span></i><span style="font-weight: 400"></span><i><span style="font-weight: 400"></span></i><span style="font-weight: 400"></span></p>
<p><span style="font-weight: 400"><a href="http://anti-patterns.md"><u><code>anti-patterns.md</code></u></a><span></span></span><span style="font-weight: 400">の例を見てみましょう。この構造は、繰り返し問題が起きやすいプラクティスを対象に設計されています。すべてのセクションで同じBAD/GOOD形式を使用しています。Claudeが個別のミスを認識し、回避できるようにするためです。アンチパターンの詳細については、</span><a href="https://architect.salesforce.com/docs/architect/well-architected-tools/guide/anti-patterns.html"><span style="font-weight: 400">こちらのドキュメント</span></a><span style="font-weight: 400">をご覧ください。</span></p>
<pre language="markdown"># Apexのアンチパターン

## 目次

- [ループ内SOQL](#soql-in-loops)
- 

---

## ループ内SOQL
**アンチパターン:** `for`ループまたは`while`ループ内でSOQLクエリーを実行すること。

**失敗する理由:** Salesforceには、1つの同期トランザクションで実行できるSOQLクエリーは
100件までという厳格な制限があります。トリガーは最大200件のレコードをまとめて処理するため、
ループ内でSOQLを1回実行すると、100件を処理しただけで上限に達します。

```apex
// BAD: 1回の反復につきSOQLを1回実行。レコード101件目で100クエリー制限を超過する。
for (Account acc : accounts) {
    List contacts = [SELECT Id FROM Contact WHERE AccountId = :acc.Id];
}

修正方法: クエリーは一括で1回だけ実行し、取得した結果を反復処理します。

// GOOD: SOQLの実行は全体で1回。
Map contactsByAccount = new Map();
for (Contact c : [SELECT Id, AccountId FROM Contact WHERE AccountId IN :accountIds]) {
    ...
}
// Salesforce Well-Architectedのアンチパターンに合わせて、他の項目を追加します。
</pre>
<p><span style="font-weight: 400">トランザクションセキュリティポリシーのような特殊なケースでは、この構造に沿ってMarkdownを作成し、通常のルールがどれも当てはまらない特定のApex機能を1つ扱うことができます。このMarkdownでは、通常のルールが当てはまらないのはどのような場合か、代わりに何をすべきか、なぜそうするのかをClaudeに教える必要があります。BAD/GOODのペアはありません。この文脈では、「悪い」コード（例：global without sharing）が実際には正しいコードだからです。この例では、assetsフォルダーにある実例を参照していることに注意してください。</span></p>
<pre language="markdown"># トランザクションセキュリティポリシー（Apex条件）

## 目次

- [概要](#overview)
- [クラスの形式](#class-shape)
- [共有設定](#sharing)
- [ガードレール](#guardrails)
- [例](#example)

---

## 概要

条件ビルダーでは不十分な場合、拡張トランザクションセキュリティポリシーはApexを呼び出します。
`TxnSecurity.EventCondition`を実装し、単一の
`evaluate(SObject event)`メソッドを定義します。

## クラスの形式

- クラスは**`global`**として宣言する（［設定］で選択できるようにするために必須）
- `TxnSecurity.EventCondition`を実装する
- シグネチャ: `global Boolean evaluate(SObject event)`

## 共有設定

これらのクラスは、ユーザー向けのコントローラーでは**ありません**。`without sharing`を使用します。
`with sharing`をデフォルトとする通常のルールはここでは適用されません。
適用すると、エラーが明示されないまま、ポリシーが正しく機能しなくなります。

## ガードレール

- 一括SOQLクエリーは最大1つとする（ループ内でSOQLは実行しない。ガバナ制限は引き続き適用される）
- トランザクションをブロックする場合は`true`、許可する場合は`false`を返す

## 例

`assets/transaction-security-policy.cls`を参照してください。

</pre>
<h3><span style="font-weight: 400">assets/：具体例によるfew-shot</span></h3>
<p><span style="font-weight: 400">Anthropicは、Claudeの出力形式、トーン、構造を方向づける最も信頼性の高い方法の1つに、few-shotとして機能する例の使用を挙げています。</span><span style="font-weight: 400">few-shotとは、テンプレートとして使える良い例をいくつか提示するといった意味です。各テンプレートには、必須要件として、ApexDocコメント、バルク対応のロジック、明示的なsharing宣言、CRUD/FLSの適用、テストを容易にするための依存性の注入が組み込まれています。Claudeはテンプレートをもとにコードを作成する際に、テンプレートの構造からこれらの要件を引き継ぎます。学習済みの知識から引き出す必要はありません。</span></p>
<p><span style="font-weight: 400">Apexには幅広い可能性がありますが、ここでは有効なユースケースをいくつか掘り下げてみましょう。</span></p>
<table>
<tbody>
<tr>
<td><b>アセット</b></td>
<td><b>ドキュメントの内容</b></td>
<td><b>この情報がない場合に起こる問題</b></td>
</tr>
<tr>
<td><code>service.cls</code></td>
<td><span style="font-weight: 400">ビジネスロジックを取りまとめる役割。クエリーを委譲し、DML 操作をまとめ、エラーを処理します。</span></td>
<td><span style="font-weight: 400">Claudeが関心の分離を考慮することなく、クエリーロジック、DML、オーケストレーションを1つの巨大なメソッドに入れてしまいます。</span></td>
</tr>
<tr>
<td><code>selector.cls</code></td>
<td><span style="font-weight: 400">SOQLアクセスを一元化します。sObjectごとに1つのセレクターを使用します。</span></td>
<td><span style="font-weight: 400">Claudeが場当たり的にクエリーを書いて、serviceコードやtriggerコードに分散させてしまいます。その結果、コードレビューでセキュリティやパフォーマンスの観点からSOQLを監査しにくくなります。</span></td>
</tr>
<tr>
<td><code>batch.cls</code></td>
<td>大量データの非同期処理（1万件以上のレコード）。<code>Database.Batchable</code>と<code>Database.Stateful</code>。</td>
<td><span style="font-weight: 400">Claudeが、エラーが発生しても適切に報告せず、そのまま処理してしまうバッチジョブを書いたり、失敗を報告する手段がないステートレスなバッチを使用したりしてしまいます。</span></td>
</tr>
<tr>
<td><code>queueable.cls</code></td>
<td><span style="font-weight: 400">オブジェクトを渡し、ジョブをチェーニングする非同期処理。</span></td>
<td><span style="font-weight: 400">Claudeが深さを制限せずにジョブをチェーニングして無限再帰を招いたり、partial DMLを使わないためにエラーを見落としたりしてしまいます。</span></td>
</tr>
<tr>
<td><code>transaction-security-policy.cls</code></td>
<td>拡張トランザクションセキュリティの<code>EventCondition</code>実装。</td>
<td>Claudeは、通常のルール（with sharing、<code>USER_MODE</code>）が当てはまらないクラスに、通常のルールを適用してしまいます。トランザクションセキュリティポリシー（TSP）クラスは、プラットフォームの要件により、global without sharingである必要があります。<i></i></td>
</tr>
</tbody>
</table>
<p><span style="font-weight: 400">各テンプレートは、単に「特定のクラスをどう書くか」を示すものではありません。必須要件を構造に組み込んだ、事前に用意されたfew-shot例です。</span></p>
<h3><span style="font-weight: 400">hooks.yamlと検証スクリプト：セーフティネット</span></h3>
<p>フックは、ライフサイクルの特定のタイミングでClaude Codeが自動実行するシェルコマンドです。フックは<code>hooks.yaml</code>で設定します。スクリプトは、そのコマンドが実行するものです。一般的には、ツールの入出力を検査して構造化されたフィードバックを返す、Pythonの検証スクリプトです。</p>
<p><span style="font-weight: 400">フックによって、人が介入しなくてもフィードバックループが完結します。Claudeがコードなどを生成すると、フックがすぐにそれを評価し、その結果をClaudeが同じ会話ターンの中で受け取ります。Claudeが問題全体を把握している状態のまま、その文脈内で修正が行われます。</span></p>
<p><span style="font-weight: 400">hooksファイルは、検証スクリプトが適切なタイミングで実行されるように設定します。たとえば、ユーザーがプロンプトを送信したタイミングで、事前チェックが実行されます。</span></p>
<pre language="json">{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "python3 ${CLAUDE_SKILL_DIR}/hooks/scripts/preflight-apex-check.py",
            "timeout": 10000
          }
        ]
      }
    ]
  }
}
</pre>
<p>また、ファイルの書き込みまたは編集が行われるたびに、<code>PostToolUse</code>フックが実行されます。</p>
<pre language="yaml">---
name: authoring-apex
description: ...
hooks:
  PostToolUse:
    - matcher: "Write|Edit"
      hooks:
        - type: command
          command: "python3 ${CLAUDE_SKILL_DIR}/hooks/scripts/preflight-apex-check.py"
          timeout: 90000
---
</pre>
<p>Claude Codeは、フックのコンテキストをJSON形式で標準入力（stdin）に渡します。ペイロードの構造はライフサイクルイベントによって異なります。<code>PostToolUse</code>にはツール名、入力パラメーター、出力が含まれ、<code>UserPromptSubmit</code>にはユーザーのプロンプトテキストが含まれます。</p>
<p>開発チーム向けの事前チェックを例に考えてみましょう。<code>SKILL.md</code>のワークフローでは、検証フェーズで「Code Analyzerを実行する」と指示しています。しかし、Code Analyzerがインストールされていなかったり、バージョンが誤っていたりすると、どうなるでしょうか。フックがない場合、Claudeはワークフローの途中でコマンドを実行しようとしてエラーを受け取ります。開発者はエラーの原因がプラグインの不足にあることを突き止めなければなりません。フックを設定しておけば、Apex関連の作業が始まった時点でチェックが実行されます。</p>
<pre language="python">import json, subprocess, sys

MINIMUM_VERSION = "5.5.0"

def parse_version(v):
    """バージョン文字列を比較可能なタプルに変換します。"""
    return tuple(int(x) for x in v.split(".")[:3])

def main():
    hook_input = json.load(sys.stdin)
    prompt = hook_input.get("prompt", "").lower()

    # Apex関連の作業である可能性が高い場合のみチェックする
    apex_keywords = ["apex", ".cls", "class", "trigger", "service", "selector", "batch"]
    if not any(kw in prompt for kw in apex_keywords):
        sys.exit(0)

    try:
        result = subprocess.run(
            ["sf", "plugins", "--json"],
            capture_output=True, text=True, timeout=15
        )
        if result.returncode == 0:
            plugins = json.loads(result.stdout)
            for plugin in plugins:
                if plugin.get("name") == "@salesforce/plugin-code-analyzer":
                    version = plugin.get("version", "0.0.0")
                    if parse_version(version) &gt;= parse_version(MINIMUM_VERSION):
                        sys.exit(0)
                    else:
                        print("=== 事前チェック ===")
                        print(f"  [警告] Code Analyzer {version} は、最低対応バージョンである {MINIMUM_VERSION} を満たしていません。")
                        print(f"  インストール: sf plugins install @salesforce/plugin-code-analyzer@latest")
                        sys.exit(0)
    except (FileNotFoundError, subprocess.TimeoutExpired, json.JSONDecodeError):
        pass

    print("=== 事前チェック ===")
    print("  [警告] Salesforce Code Analyzerがインストールされていません。")
    print("  authoring-apex skillでは、検証のためにSalesforce Code Analyzerが必要です。")
    print("  インストール: sf plugins install @salesforce/plugin-code-analyzer")
    sys.exit(0)

if __name__ == "__main__":
    main()

</pre>
<p><span style="font-weight: 400">開発者は、ツールチェーンに不足があることを事前に発見できるので、ワークフローの途中で検証フェーズが失敗してから気づくという事態を避けられます。 </span></p>
<p><span style="font-weight: 400">指示とフックの違いはここにあります。</span><span style="font-weight: 400"><code>SKILL.md</code></span><span style="font-weight: 400">には、「検証フェーズでCode Analyzerを実行する」と書かれています。フックは、ワークフローが始まる前にCode Analyzerを実行できることを確認します。指示は望ましい動作を示すものであり、フックは機械的に実行されるものです。この両方が必要です。</span></p>
<h2><span style="font-weight: 400">エージェントスキルには、なぜ人間と機械の両方による検証が必要になるのか</span></h2>
<p><span style="font-weight: 400">スキルはすべてを解決する切り札ではありません。スキルによってClaudeの出力のばらつきはかなり小さくできますが、それでもClaudeは本質的に非決定論的なシステムです。ここで問題になるのは、次の2点です。</span></p>
<p><b>動作を完全に指定することはできない。</b><span style="font-weight: 400"></span><span style="font-weight: 400"><code>SKILL.md</code></span><span style="font-weight: 400">がどれほど正確であっても、実際の要件にはテンプレートやリファレンスではカバーしきれない、新しい組み合わせが含まれます。それでもClaudeは判断を下さなければなりません。新しいモデルほどプロンプトを文字どおりに解釈するため、記述が少し足りないだけでも結果にばらつきが出ます。</span><span style="font-weight: 400"><code>SKILL.md</code></span><span style="font-weight: 400">でパターンを指定せずに「エラー処理を追加する」とだけ書くと、毎回異なるアプローチが使われることになります。</span></p>
<p><b>出力は確率に左右される。</b><span style="font-weight: 400">プロンプトを構造化し、役割を割り当て、例を提示し、検証フックを使っても、結局は正答率を最適化しているにすぎません。正答率が60%から95%に向上すれば、もちろん大きな改善ではありますが、残りの5%に対応するために検証ツールが必要です。このアーキテクチャーには、予防的対策（構造化されたプロンプト、リファレンス、テンプレート）と検出的対策（自動検証ツール、採点ルーブリック、エラー時のブロック）の両方が含まれます。このスキルは、Claudeが間違えることもあるという前提に立っています。完全な出力が可能であるかのように見なすのではなく、修正プロセスをワークフローに組み込んでいるのです。</span></p>
<h2><span style="font-weight: 400">さっそく始めてみましょう</span></h2>
<p><span style="font-weight: 400">Anthropicは、プロンプトの作成についてこう述べています。「背景情報をほとんど知らない同僚にプロンプトを見せて、それに沿って作業してもらってみてください。その同僚が戸惑うようなら、Claudeも戸惑います」。適切に作成されたエージェントスキルには、人間にとってもモデルにとっても、あいまいな点がありません。</span></p>
<p><span style="font-weight: 400">スキルをゼロから構築する必要はありません。Anthropicが提供する</span><span style="font-weight: 400"><code>skill-creator</code></span><a href="https://github.com/anthropics/skills/blob/main/skills/skill-creator/SKILL.md"><span style="font-weight: 400">スキル</span></a><span style="font-weight: 400">（英語）を使うと、意図の整理、<code>SKILL.md</code></span><span style="font-weight: 400">の記述、テストケースの作成、evalの実行、そして出力が求める基準に達するまで反復するという一連のプロセスを進められます。skill-creatorスキルをインストールし、作成したいスキルをClaudeに伝えてみてください。skill-creatorスキルが土台を作成し、エッジケースについて聞き取り、実際に動作し、調整可能なドラフトを生成してくれます。</span></p>
<p><span style="font-weight: 400">Salesforceに特化したサンプルを使って始めてみたい場合は、</span><a href="https://github.com/forcedotcom/afv-library"><span style="font-weight: 400">Agentforce Vibesスキルライブラリ</span></a><span style="font-weight: 400">（英語）で、Apex、LWC、Flowなどの本番品質のスキルを利用できます。こうしたスキルをインストールして使い、どのように構成されているかを確認してみてください。この記事で説明したものと同様のパターンに従っています。Agentforce Vibesスキルライブラリでは、ルールと理由を</span><span style="font-weight: 400"><code>SKILL.md</code></span><span style="font-weight: 400">にインラインで記述し、Markdown形式の参照ドキュメントの代わりに、完全なApexソースファイルをテンプレートとして使っています。これにより、少ないファイル数でスキルを自己完結させることができますが、モジュール性は損なわれます。1つのルールを更新するには、メインのワークフローファイルを編集する必要があります。 </span></p>
<p><span style="font-weight: 400">スキルは、ニーズに合わせて成長していきます。まずは</span><span style="font-weight: 400"><code>skill-creator</code></span><span style="font-weight: 400">または既存のスキルから始めてみましょう。プロジェクトに合わない部分をカスタマイズし、既存のスキルでは埋められないギャップが出てきたら、新しいスキルを構築してみるとよいでしょう。</span></p>
<h2><span style="font-weight: 400">関連情報</span></h2>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">GitHub：</span><a href="https://github.com/forcedotcom/afv-library"><span style="font-weight: 400">Salesforceのエージェントスキル集（英語）</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">Trailhead：</span><a href="https://trailhead.salesforce.com/content/learn/modules/prompt-fundamentals"><span style="font-weight: 400">プロンプトの基本事項</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">Trailhead：</span><a href="https://trailhead.salesforce.com/content/learn/modules/prompt-engineering-techniques"><span style="font-weight: 400">プロンプトエンジニアリングのテクニック</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">GitHub：</span><a href="https://github.com/anthropics/skills/blob/main/skills/skill-creator/SKILL.md"><span style="font-weight: 400">Anthropic Skill Creator（英語）</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">ドキュメント：</span><a href="https://docs.anthropic.com/en/docs/claude-code/skills"><span style="font-weight: 400">Claude Code</span></a><span style="font-weight: 400"> </span></li>
</ul>
<h2><span style="font-weight: 400">執筆者について</span></h2>
<p><b>Dave Norris</b><span style="font-weight: 400">は、Salesforceのデベロッパーアドボケイトです。技術的なテーマを、多様な読者に広くわかりやすく説明することに情熱を注いでいます。Salesforceで10年以上勤務し、現在、SalesforceとMuleSoftの認定資格を40以上保有。2013年に、Salesforce認定テクニカルアーキテクトの資格を取得しています。</span></p>
<p>&nbsp;</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/08/build-a-salesforce-agent-skill-with-claude-code-jp">Claude CodeでSalesforceエージェントスキルを構築する</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/08/build-a-salesforce-agent-skill-with-claude-code-jp/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206896</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260528154202/SingleHeadshot-2-e1780008137933.png?w=1000" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260528154202/SingleHeadshot-2-e1780008137933.png?w=1000" medium="image" />
	</item>
		<item>
		<title>Headless Experience Layer によるカスタムウィジェット：MCP 経由で取引先の商談サマリーを AI エージェントアプリに表示する</title>
		<link>https://developer.salesforce.com/blogs/2026/08/headless-experience-layer-custom-ui-widget-jp</link>
		<comments>https://developer.salesforce.com/blogs/2026/08/headless-experience-layer-custom-ui-widget-jp#respond</comments>
		<pubDate>Mon, 24 Aug 2026 16:10:41 +0000</pubDate>
		<dc:creator><![CDATA[Hiroyuki Inaba]]></dc:creator>
				<category><![CDATA[Agentforce Vibes]]></category>
		<category><![CDATA[App Development]]></category>
		<category><![CDATA[Headless 360]]></category>
		<category><![CDATA[hxl]]></category>
		<category><![CDATA[MCP Server]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206871</guid>
		<description><![CDATA[<p>Salesforce &#12398;&#21830;&#35527;&#12487;&#12540;&#12479;&#12434;&#12289;Claude &#12420; ChatGPT &#12395;&#38745;&#30340;&#12469;&#12531;&#12503;&#12523;&#12391;&#12399;&#12394;&#12367;&#23455;&#12487;&#12540;&#12479;&#12398;&#12522;&#12483;&#12481;&#12394; UI &#12459;&#12540;&#12489;&#12391;&#34920;&#31034;&#12290;HXL&#65288;Headless Experience Layer&#65289;&#12392; MCP &#12434;&#32068;&#12415;&#21512;&#12431;&#12379;&#12383; 7 &#12473;&#12486;&#12483;&#12503;&#12398;&#12495;&#12531;&#12474;&#12458;&#12531;&#12434;&#12289;Salesforce &#38283;&#30330;&#32773;&#21521;&#12369;&#12395;&#26085;&#26412;&#35486;&#12391;&#35299;&#35500;&#12375;&#12414;&#12377;&#12290;</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/08/headless-experience-layer-custom-ui-widget-jp">Headless Experience Layer によるカスタムウィジェット：MCP 経由で取引先の商談サマリーを AI エージェントアプリに表示する</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>みなさん、こんにちは！</p>
<p>TDX 2026 で発表された <strong>HXL（Headless Experience Layer）</strong> ですが、2026年8月後半よりベータ公開となりました。Salesforce のデータを Slackbot、ChatGPT や Claude といった外部の AI エージェントアプリに、リッチなカスタム UI（ウィジェット）として表示できます。しかも表示するのは静的なサンプルではなく、<strong>組織の実データ</strong>です。</p>
<p>本記事では、その HXL ウィジェットを <strong>MCP（Model Context Protocol）サーバー経由</strong>で公開し、AI エージェントアプリに「取引先の商談サマリ」を表示するまでをの流れを解説します。完成すると、AI エージェントアプリで「株式会社アストロエンタープライズの商談状況サマリを教えて」などと話しかけるだけで、次のようなカードが返ってくるようになります。</p>
<figure>
 
			  <span class="postimagessection_specify alignnone size-medium wp-image-206879" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260824092858/00-hero-card.png?w=1024" class="postimages" width="1024" height="590" alt="" />
			  </span>
			<br />
</figure>
<p>HXL の仕様や API の詳細は、公式の <a href="https://developer.salesforce.com/docs/platform/hxl/overview">Headless Experience Layer Developer Guide (Beta)</a> に詳しくまとまっています。ただし内容は英語で、サンプルもオブジェクトのデータにはアクセスしないものでした。そこで本記事では、<strong>実際に Salesforce 組織のデータを扱いながら、日本語で一連の流れを解説する</strong>ことを目的に作成しました。公式ガイドとあわせて読むことで、より理解が深まるはずです。</p>
<p>対象読者は <strong>Salesforce 開発の経験がある方</strong>です。Apex、メタデータ、VS Code + Salesforce&amp;Agentforce 関連の拡張機能、<code>sf</code> コマンドの基礎は前提とし、HXL・MCP まわりの新しい概念を重点的に解説します。</p>
<blockquote>
<p><strong>※注意</strong></p>
<ul>
<li>この記事は <strong>2026 年 8 月時点</strong>の情報で作成しています。HXL / MCP まわりは進化が速いため、最新の仕様は公式ドキュメントもあわせてご確認ください。</li>
<li>本番組織ではなく <strong>Sandbox / Developer Editio/ Scratch Org</strong> での検証をおすすめします。</li>
<li>本記事の内容を試すには、組織のインスタンスが <strong>Summer &#8217;26 Patch 14.4 以降</strong>である必要があります。パッチバージョンは <a href="https://status.salesforce.com/">Salesforce Status</a> で自組織のインスタンスを検索すると確認できます。</li>
<li>本手順は Developer Edition での動作を確認しています。</li>
</ul>
</blockquote>
<hr />
<h2>全体の流れ</h2>
<p>作るファイルはやや多いですが、役割ごとに整理すると次の 7 ステップになります。</p>
<ol>
<li><strong>Apex クラス</strong>で取引先の商談サマリーを取得する（データ取得ロジック）</li>
<li><strong>LightningType</strong> で戻り値の型とレンダラー（描画マッピング）を定義する</li>
<li><strong>UiWidgetBundle</strong> でウィジェットの見た目（UI）を作る</li>
<li><strong>GenAiFunction（Agent Action）</strong> で Apex を API カタログに登録する</li>
<li><strong>McpServerDefinition</strong> で MCP サーバーとして公開する</li>
<li><strong>デプロイ</strong>する</li>
<li><strong>MCP サーバーを有効化</strong>し、AI エージェントアプリから接続して動作確認する</li>
</ol>
<p>登場人物を図にすると、データの流れは次のようになります。</p>
<figure>

			  <span class="postimagessection_specify alignnone size-medium wp-image-206880" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260824093007/06-hxl-architecture-diagram.png?w=1242" class="postimages" width="1242" height="1000" alt="" />
			  </span>
			<br />
</figure>
<p>ポイントは、<strong>「データを取得する経路（tools）」と「見た目を定義する経路（resources）」が別々</strong>で、それを McpServerDefinition が束ねているところです。ここを押さえると、以降のファイル構成がすっきり理解できます。</p>
<hr />
<h2>事前準備</h2>
<ul>
<li>Salesforce 組織（検証には Developer Edition または Sandbox を推奨）</li>
<li>Salesforce CLI（<code>sf</code>）&amp; VS Code + Salesforce &amp; Agentforce の拡張機能</li>
</ul>
<p>本記事では API バージョン <code>67.0</code> を前提にしています。</p>
<h3>HXL を有効化する</h3>
<p>まず、組織で HXL の機能を有効化しておきます。<strong>設定</strong> のクイック検索で「<strong>ヘッドレスエクスペリエンスレイヤー</strong>」を検索し、設定ページを開いて有効化スイッチをオンにします。</p>
<figure>

			  <span class="postimagessection_specify alignnone size-medium wp-image-206878" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260824092856/01-enable-hxl.png?w=1024" class="postimages" width="1024" height="590" alt="" />
			  </span>
			<br />
</figure>
<blockquote>
<p><strong>※</strong> この設定が表示されない場合は、組織のインスタンスが <strong>Summer &#8217;26 Patch 14.4 以降</strong>になっているかを確認してください（パッチバージョンの確認方法は冒頭の注意を参照）。</p>
</blockquote>
<hr />
<blockquote>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4e6.png" alt="📦" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 本記事で作成するコード一式は、GitHub リポジトリ <a href="https://github.com/hinabasfdc/hxl-mcp-widget-sample">hinabasfdc/hxl-mcp-widget-sample</a> に公開しています。手を動かしながら読む場合は、あわせて参照してください。</p>
</blockquote>
<h2>ステップ 1：Apex で商談サマリーを取得する</h2>
<p>まずはデータ取得の心臓部となる Apex クラスです。取引先名を受け取り、次の 3 つを返します。</p>
<ul>
<li>商談の総数</li>
<li>フェーズ（<code>StageName</code>）別の商談件数</li>
<li>未クローズ（<code>IsClosed = false</code>）商談の合計金額</li>
</ul>
<p>MCP のツールとして呼び出せるように、<code>@InvocableMethod</code> / <code>@InvocableVariable</code> で入出力を定義するのがポイントです。クラス全体は次のとおりです。</p>
<pre><code class="language-apex">global without sharing class AccountOpportunitySummary {

    @InvocableMethod(label='取引先の商談サマリーを取得' description='取引先名から、商談件数・フェーズ別件数・未クローズ商談の合計金額を取得します。')
    global static List&lt;SummaryResponse&gt; getAccountOpportunitySummary(List&lt;SummaryRequest&gt; requests) {
        List&lt;SummaryResponse&gt; responses = new List&lt;SummaryResponse&gt;();

        for (SummaryRequest req : requests) {
            SummaryResponse res = new SummaryResponse();
            res.summary = buildSummary(req.accountName);
            responses.add(res);
        }

        return responses;
    }

    private static Summary buildSummary(String accountName) {
        Summary summary = new Summary();
        summary.accountName = accountName;
        summary.accountInitials = toInitials(accountName);
        summary.totalOpportunityCount = 0;
        summary.stageSummaryText = '';
        summary.openOpportunityAmount = 0;

        List&lt;Account&gt; accounts = [
            SELECT Id, Name
            FROM Account
            WHERE Name LIKE :('%' + accountName + '%')
            ORDER BY Name
            LIMIT 1
        ];

        if (accounts.isEmpty()) {
            return summary;
        }

        Account acc = accounts[0];
        summary.accountName = acc.Name;
        summary.accountInitials = toInitials(acc.Name);

        List&lt;String&gt; stageSummaryParts = new List&lt;String&gt;();
        for (AggregateResult ar : [
            SELECT StageName, COUNT(Id) opportunityCount
            FROM Opportunity
            WHERE AccountId = :acc.Id
            GROUP BY StageName
            ORDER BY StageName
        ]) {
            String stageName = (String) ar.get('StageName');
            Integer count = (Integer) ar.get('opportunityCount');

            summary.totalOpportunityCount += count;
            stageSummaryParts.add(stageName + ': ' + count + '件');
        }
        summary.stageSummaryText = String.join(stageSummaryParts, ' / ');

        AggregateResult openTotal = [
            SELECT SUM(Amount) totalAmount
            FROM Opportunity
            WHERE AccountId = :acc.Id AND IsClosed = false
        ];
        Decimal openAmount = (Decimal) openTotal.get('totalAmount');
        summary.openOpportunityAmount = (openAmount != null) ? openAmount : 0;

        summary.totalOpportunityCountText = summary.totalOpportunityCount + '件';
        summary.openOpportunityAmountFormatted = formatCurrency(summary.openOpportunityAmount);

        return summary;
    }

    // ウィジェット表示用に3桁区切りの「¥」表記へ整形する(Decimal.format()はロケール依存のため使わない)
    private static String formatCurrency(Decimal amount) {
        Long rounded = amount.round();
        String sign = (rounded &lt; 0) ? '-' : '';
        String digits = String.valueOf(Math.abs(rounded));

        List&lt;String&gt; groups = new List&lt;String&gt;();
        Integer len = digits.length();
        Integer head = Math.mod(len, 3);
        if (head &gt; 0) {
            groups.add(digits.substring(0, head));
        }
        for (Integer i = head; i &lt; len; i += 3) {
            groups.add(digits.substring(i, i + 3));
        }

        return sign + '¥' + String.join(groups, ',');
    }

    // アバター表示用に、法人格の接頭辞を除いた先頭1文字を取り出す
    private static String toInitials(String name) {
        if (String.isBlank(name)) {
            return '?';
        }
        String bareName = name.replace('株式会社', '').replace('有限会社', '').trim();
        return String.isBlank(bareName) ? name.substring(0, 1) : bareName.substring(0, 1);
    }

    global class SummaryRequest {
        @InvocableVariable(label='取引先名' description='検索対象の取引先名(部分一致)' required=true)
        public String accountName;
    }

    global class SummaryResponse {
        @InvocableVariable(label='商談サマリー')
        public Summary summary;
    }

    global class Summary {
        @InvocableVariable public String accountName;
        @InvocableVariable public String accountInitials;
        @InvocableVariable public Integer totalOpportunityCount;
        @InvocableVariable public String stageSummaryText;
        @InvocableVariable public Decimal openOpportunityAmount;
        @InvocableVariable public String totalOpportunityCountText;
        @InvocableVariable public String openOpportunityAmountFormatted;
    }
}</code></pre>
<hr />
<h2>ステップ 2：LightningType で型とレンダラーを定義する</h2>
<p>ここが HXL の肝です。Apex の戻り値を、そのままウィジェットに流し込めるわけではありません。<strong>LightningType</strong> が「どの Apex 型を、どのウィジェットの、どの属性にマッピングするか」を仲介します。</p>
<p>MCP のレスポンスは 3 層の入れ子（エンベロープ）になっています。</p>
<pre><code>accountOpportunitySummaryResult        ← 一番外側（actionName / isSuccess / outputValues）
  └─ accountOpportunitySummaryOutputValues  ← 中間（summary を保持）
       └─ AccountOpportunitySummary$Summary  ← Apex の Summary クラス（実データ）</code></pre>
<p>この 3 層に対応する LightningType をそれぞれ用意します。</p>
<h3>2-1. 一番内側：Apex 型のラッパー</h3>
<p><code>lightningTypes/accountOpportunitySummary/schema.json</code> は、Apex の <code>Summary</code> クラスを LightningType として参照するだけのシンプルなものです。</p>
<pre><code class="language-json">{
  "title": "Account Opportunity Summary",
  "description": "Apex から返される取引先の商談サマリー情報",
  "lightning:type": "@apexClassType/c__AccountOpportunitySummary$Summary"
}</code></pre>
<p><code>@apexClassType/c__&lt;クラス名&gt;$&lt;内部クラス名&gt;</code> という記法で、Apex の内部クラスを直接参照できます。</p>
<h3>2-2. 中間層：OutputValues</h3>
<p><code>lightningTypes/accountOpportunitySummaryOutputValues/schema.json</code> は、Apex アクションのレスポンス payload（<code>summary</code> を持つ）を表します。<code>lightning:tags</code> に <code>mcp</code> を付けるのがポイントです。</p>
<pre><code class="language-json">{
  "title": "Account Opportunity Summary Output Values",
  "type": "object",
  "lightning:type": "lightning__objectType",
  "unevaluatedProperties": false,
  "lightning:tags": [ "mcp" ],
  "properties": {
    "summary": {
      "title": "Summary",
      "lightning:type": "@apexClassType/c__AccountOpportunitySummary$Summary"
    }
  }
}</code></pre>
<h3>2-3. 一番外側：Result エンベロープ</h3>
<p><code>lightningTypes/accountOpportunitySummaryResult/schema.json</code> が MCP に公開される最上位の型です。<code>actionName</code> / <code>isSuccess</code> / <code>outputValues</code> を持ちます。</p>
<pre><code class="language-json">{
  "title": "Account Opportunity Summary Result",
  "type": "object",
  "lightning:type": "lightning__objectType",
  "unevaluatedProperties": false,
  "lightning:tags": [ "mcp" ],
  "properties": {
    "actionName": { "title": "Action Name", "lightning:type": "lightning__textType" },
    "isSuccess":  { "title": "Is Success",  "lightning:type": "lightning__booleanType" },
    "outputValues": {
      "title": "Output Values",
      "lightning:type": "c__accountOpportunitySummaryOutputValues"
    }
  }
}</code></pre>
<h3>2-4. レンダラー：属性のマッピング</h3>
<p>そして最も重要なのが <code>renderer.json</code> です。これが <strong>「入れ子になったデータのどこを、ウィジェットのどの属性に流し込むか」</strong> を定義します。Result 型のレンダラーは、3 層をたどって値を取り出します。</p>
<pre><code class="language-json">{
  "renderer": {
    "componentOverrides": {
      "$": {
        "definition": "@widget/c/accountSummaryCard",
        "attributes": {
          "accountName": "{!$attrs.outputValues.summary.accountName}",
          "accountInitials": "{!$attrs.outputValues.summary.accountInitials}",
          "totalOpportunityCountText": "{!$attrs.outputValues.summary.totalOpportunityCountText}",
          "stageSummaryText": "{!$attrs.outputValues.summary.stageSummaryText}",
          "openOpportunityAmountFormatted": "{!$attrs.outputValues.summary.openOpportunityAmountFormatted}"
        }
      }
    }
  }
}</code></pre>
<ul>
<li><code>"definition": "@widget/c/accountSummaryCard"</code> で、次のステップで作るウィジェットを指定します。</li>
<li><code>{!$attrs.outputValues.summary.xxx}</code> という式で、エンベロープの奥にある実データを取り出してウィジェットの属性に渡します。<strong>この階層（<code>outputValues.summary.</code>）を間違えると値が表示されない</strong>ので注意してください。</li>
</ul>
<hr />
<h2>ステップ 3：UiWidgetBundle でウィジェットの UI を作る</h2>
<p>いよいよ見た目です。HXL のウィジェットは <code>tile/*</code> というコンポーネントを JSON でツリー状に組み合わせて作ります。</p>
<h3>3-1. スキーマ（受け取る属性の宣言）</h3>
<p><code>uiWidgets/accountSummaryCard/schema.json</code> で、ウィジェットが受け取る属性を宣言します。</p>
<pre><code class="language-json">{
  "title": "Account Opportunity Summary Widget",
  "type": "object",
  "properties": {
    "attributes": {
      "lightning:type": "lightning__objectType",
      "properties": {
        "accountName":                     { "title": "取引先名", "lightning:type": "lightning__textType" },
        "accountInitials":                 { "title": "取引先名イニシャル", "lightning:type": "lightning__textType" },
        "stageSummaryText":                { "title": "フェーズ別商談数", "lightning:type": "lightning__textType" },
        "totalOpportunityCountText":       { "title": "商談数(表示用)", "lightning:type": "lightning__textType" },
        "openOpportunityAmountFormatted":  { "title": "未クローズ商談合計金額(表示用)", "lightning:type": "lightning__textType" }
      }
    }
  }
}</code></pre>
<blockquote>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> フェーズ別件数は、Apex 側で <code>フェーズA: 3件 / フェーズB: 2件</code> のような <strong>1 本のテキスト（<code>stageSummaryText</code>）に整形</strong>して渡しています。</p>
</blockquote>
<h3>3-2. ウィジェット本体（tile ツリー）</h3>
<p><code>uiWidgets/accountSummaryCard/accountSummaryCard.json</code> がレイアウト定義です。全体は長いので、構造を先に示します。</p>
<pre><code>tile/widget
└─ tile/container
   └─ tile/column (gap: lg)
      ├─ [ヘッダー行] tile/row (justify: between)
      │   ├─ tile/row → tile/avatar（イニシャル） + tile/column（取引先名 + キャプション）
      │   └─ tile/badge（商談数）
      ├─ [統計行] tile/row (align: stretch, isWrapped)
      │   ├─ tile/container → icon(briefcase) + 「商談数」 + 大きな数値
      │   └─ tile/container → icon(dollar-sign) + 「未クローズ商談合計金額」 + 大きな金額
      ├─ tile/separator
      └─ [フェーズ別] tile/column → 見出し + stageSummaryText</code></pre>
<p>ヘッダー部分（アバター＋取引先名＋商談数バッジ）の JSON は次のようになります。</p>
<pre><code class="language-json">{
  "definition": "tile/row",
  "attributes": { "gap": "md", "align": "center", "justify": "between", "isWrapped": true },
  "children": [
    {
      "definition": "tile/row",
      "attributes": { "gap": "sm", "align": "center" },
      "children": [
        {
          "definition": "tile/avatar",
          "attributes": {
            "initials": "{!$attrs.accountInitials}",
            "alt": "{!$attrs.accountName}",
            "size": "md",
            "shape": "circle"
          }
        },
        {
          "definition": "tile/column",
          "attributes": { "gap": "xs" },
          "children": [
            { "definition": "tile/text", "attributes": { "text": "{!$attrs.accountName}", "variant": "h3", "weight": "semibold" } },
            { "definition": "tile/text", "attributes": { "text": "取引先の商談サマリー", "variant": "caption", "color": "muted" } }
          ]
        }
      ]
    },
    {
      "definition": "tile/badge",
      "attributes": { "label": "{!$attrs.totalOpportunityCountText}", "variant": "primary" }
    }
  ]
}</code></pre>
<p>未クローズ商談合計金額を強調して表示する統計カード部分はこうです。アイコンと大きな数値を組み合わせます。</p>
<pre><code class="language-json">{
  "definition": "tile/container",
  "children": [
    {
      "definition": "tile/column",
      "attributes": { "gap": "xs" },
      "children": [
        {
          "definition": "tile/row",
          "attributes": { "gap": "sm", "align": "center" },
          "children": [
            { "definition": "tile/icon", "attributes": { "name": "dollar-sign", "size": "sm", "color": "success" } },
            { "definition": "tile/text", "attributes": { "text": "未クローズ商談合計金額", "variant": "caption", "color": "muted" } }
          ]
        },
        {
          "definition": "tile/text",
          "attributes": { "text": "{!$attrs.openOpportunityAmountFormatted}", "variant": "h2", "weight": "bold", "color": "success" }
        }
      ]
    }
  ]
}</code></pre>
<blockquote>
<p><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;" /> <strong>現時点でのハマりどころ：<code>tile/icon</code> の <code>name</code> は実在する値のみ</strong><br />
  <code>tile/icon</code> の <code>name</code> に存在しないアイコン名（例：<code>currency</code>）を指定すると、ウィジェット全体が <code>NullPointerException</code> でクラッシュします。エラーメッセージが「An unexpected error occurred」としか出ないため、原因の特定に時間がかかりました。<code>briefcase</code> や <code>dollar-sign</code> など、<strong>実在するアイコン名</strong>を使ってください。</p>
</blockquote>
<p><code>UiWidgetBundle</code> のメタデータ（<code>accountSummaryCard.uiwidget-meta.xml</code>）は <code>widgetType</code> を <code>JSON</code> にしておきます。</p>
<pre><code class="language-xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;UiWidgetBundle xmlns="http://soap.sforce.com/2006/04/metadata"&gt;
    &lt;masterLabel&gt;Account Summary Card&lt;/masterLabel&gt;
    &lt;description&gt;取引先名、商談数、フェーズ別商談数、未クローズ商談の合計金額を表示します。&lt;/description&gt;
    &lt;widgetType&gt;JSON&lt;/widgetType&gt;
&lt;/UiWidgetBundle&gt;</code></pre>
<hr />
<h2>ステップ 4：GenAiFunction（Agent Action）で Apex を登録する</h2>
<p>ここは見落としがちですが<strong>必須</strong>です。Apex クラスを MCP サーバーから呼び出せるようにするために、Agent アクションとして登録する必要があります。</p>
<p><code>genAiFunctions/Get_Account_Opportunity_Summary/Get_Account_Opportunity_Summary.genAiFunction-meta.xml</code>:</p>
<pre><code class="language-xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;GenAiFunction xmlns="http://soap.sforce.com/2006/04/metadata"&gt;
    &lt;description&gt;取引先名から、商談件数・フェーズ別件数・未クローズ商談の合計金額を取得します。&lt;/description&gt;
    &lt;developerName&gt;Get_Account_Opportunity_Summary&lt;/developerName&gt;
    &lt;invocationTarget&gt;AccountOpportunitySummary&lt;/invocationTarget&gt;
    &lt;invocationTargetType&gt;apex&lt;/invocationTargetType&gt;
    &lt;isConfirmationRequired&gt;false&lt;/isConfirmationRequired&gt;
    &lt;masterLabel&gt;取引先の商談サマリーを取得&lt;/masterLabel&gt;
&lt;/GenAiFunction&gt;</code></pre>
<p>入力スキーマ（<code>input/schema.json</code>）では、<code>accountName</code> をユーザー入力として受け取ることを宣言します。</p>
<pre><code class="language-json">{
  "required": [ "accountName" ],
  "properties": {
    "accountName": {
      "title": "取引先名",
      "lightning:type": "lightning__textType",
      "copilotAction:isUserInput": true
    }
  },
  "lightning:type": "lightning__objectType"
}</code></pre>
<p>出力スキーマ（<code>output/schema.json</code>）では、<code>summary</code> を <strong>表示可能（<code>isDisplayable</code>）</strong> として宣言します。これがウィジェット表示につながる重要なフラグです。</p>
<pre><code class="language-json">{
  "properties": {
    "summary": {
      "title": "商談サマリー",
      "lightning:type": "@apexClassType/c__AccountOpportunitySummary$Summary",
      "copilotAction:isDisplayable": true,
      "copilotAction:isUsedByPlanner": true
    }
  },
  "lightning:type": "lightning__objectType"
}</code></pre>
<hr />
<h2>ステップ 5：McpServerDefinition で MCP サーバーとして公開する</h2>
<p>最後に、これまでの部品を束ねる <code>McpServerDefinition</code> です。ここが「データ取得（<code>tools</code>）」と「見た目（<code>resources</code>）」を接続する結節点になります。</p>
<pre><code class="language-xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;McpServerDefinition xmlns="http://soap.sforce.com/2006/04/metadata"&gt;
    &lt;description&gt;取引先の商談サマリー(商談数、フェーズ別件数、未クローズ商談合計金額)を検索して返します。&lt;/description&gt;
    &lt;masterLabel&gt;account-opportunity-summary-server&lt;/masterLabel&gt;
    &lt;tools&gt;
        &lt;apiDefinition&gt;
            &lt;apiIdentifier&gt;aa:apex-AccountOpportunitySummary&lt;/apiIdentifier&gt;
            &lt;apiSource&gt;API_CATALOG&lt;/apiSource&gt;
            &lt;operation&gt;AccountOpportunitySummary&lt;/operation&gt;
        &lt;/apiDefinition&gt;
        &lt;descriptionOverride&gt;取引先名から、商談件数・フェーズ別件数・未クローズ商談の合計金額を取得します。&lt;/descriptionOverride&gt;
        &lt;destructive&gt;false&lt;/destructive&gt;
        &lt;idempotent&gt;true&lt;/idempotent&gt;
        &lt;openWorld&gt;false&lt;/openWorld&gt;
        &lt;readOnly&gt;true&lt;/readOnly&gt;
        &lt;returnDirect&gt;false&lt;/returnDirect&gt;
        &lt;toolName&gt;AccountOpportunitySummaryapex_AccountOpportunitySummary&lt;/toolName&gt;
        &lt;toolTitle&gt;AccountOpportunitySummary&lt;/toolTitle&gt;
        &lt;uiResource&gt;accountSummary&lt;/uiResource&gt;
    &lt;/tools&gt;
    &lt;resources&gt;
        &lt;resourceName&gt;accountSummary&lt;/resourceName&gt;
        &lt;resourceUri&gt;ui://widget/lightningType/c__accountOpportunitySummaryResult&lt;/resourceUri&gt;
        &lt;resourceTitle&gt;Account Opportunity Summary&lt;/resourceTitle&gt;
        &lt;description&gt;取引先名、商談数、フェーズ別商談数、未クローズ商談合計金額を表示するウィジェット。&lt;/description&gt;
    &lt;/resources&gt;
&lt;/McpServerDefinition&gt;</code></pre>
<h3>読み解きのポイント</h3>
<ul>
<li><code>&lt;tools&gt;</code> は <strong>データ取得の経路</strong>です。<code>apiIdentifier</code> の <code>aa:apex-&lt;クラス名&gt;</code> と <code>apiSource</code> の <code>API_CATALOG</code> が、ステップ 4 で登録した Agent Action を指しています。</li>
<li><code>&lt;resources&gt;</code> は <strong>見た目の経路</strong>です。<code>resourceUri</code> は <code>ui://widget/lightningType/c__&lt;LightningTypeBundleのAPI名&gt;</code> という形式で、ステップ 2 で作った Result 型を指します。</li>
<li><code>&lt;uiResource&gt;</code> と <code>&lt;resourceName&gt;</code> の値（<code>accountSummary</code>）を一致させることで、ツールとリソース（＝データと見た目）が紐づきます。</li>
</ul>
<blockquote>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 現時点の仕様: CSP（<code>connectDomains</code> など）や <code>_meta.ui.domain</code> といった MCP プロトコルの内部設定は、<strong>Salesforce プラットフォームが自動生成</strong>します。開発者がメタデータで設定する項目ではありません。</p>
</blockquote>
<hr />
<h2>ステップ 6：デプロイする</h2>
<p>ソースを組織にデプロイします。依存関係の順（Apex → LightningType &amp; UiWidget → GenAiFunction → McpServerDefinition）を意識するとエラーが減りますが、まとめてデプロイしても解決してくれることが多いです。</p>
<pre><code class="language-bash">sf project deploy start \
  --source-dir force-app/main/default \
  --target-org &lt;your-org-alias&gt; \
  --wait 15 --json</code></pre>
<blockquote>
<p>現時点の仕様: <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;" /> <strong>UiWidgetBundle のスキーマは「プロパティ削除」で失敗する</strong><br />
  一度デプロイしたウィジェットの <code>schema.json</code> から既存プロパティを削除すると、<code>Schema update contains breaking changes: ... プロパティは削除できません</code> というエラーになります。属性を作り直したいときは、<strong>古いプロパティを残したまま新しいものを追加</strong>するのが安全です。</p>
</blockquote>
<hr />
<h2>ステップ 7：MCP サーバーを有効化し、AI エージェントアプリから接続する</h2>
<p>デプロイが終わったら、<strong>MCP サーバーを有効化</strong>します。これは現状 <strong>設定画面からの手動操作のみ</strong>です。</p>
<figure>

			  <span class="postimagessection_specify alignnone size-medium wp-image-206877" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260824092854/02-enable-mcp-server.png?w=1024" class="postimages" width="1024" height="590" alt="" />
			  </span>
			<br />
</figure>
<p>有効化したら、外部クライアントアプリケーションを作成し、AI エージェントアプリ側でコネクタ（プラグイン）として登録します。この OAuth まわりの手順は、別記事「<a href="https://developer.salesforce.com/jpblogs/2026/04/salesforce-hosted-mcp-server-jp">Salesforce Hosted MCP Server 使い始め</a>」で詳しく解説されているので、そちらもあわせてご覧ください。</p>
<h3>ChatGPT と Claude で試してみる</h3>
<p>公開した MCP サーバーは、MCP に対応した AI エージェントアプリから接続できます。コネクタとして登録したうえで「SalesforceDev で United Oil の商談サマリを見せて」と話しかけると、<code>AccountOpportunitySummary</code> ツールが呼び出され、次のように同じカードが表示されます。</p>
<p><strong>Claude の場合</strong></p>
<figure>

			  <span class="postimagessection_specify alignnone size-medium wp-image-206876" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260824092852/03-claude.png?w=1024" class="postimages" width="1024" height="590" alt="" />
			  </span>
			<br />
</figure>
<p><strong>ChatGPT の場合</strong></p>
<figure>

			  <span class="postimagessection_specify alignnone size-medium wp-image-206875" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260824092850/04-chatgpt.png?w=1024" class="postimages" width="1024" height="590" alt="" />
			  </span>
			<br />
</figure>
<p><code>SUM(Amount)</code> も <code>GROUP BY StageName</code> も、すべて組織の実データが反映されています。フィールドレベルセキュリティ（FLS）や共有ルールも尊重されるため、安心して社内データを扱えます。同じ MCP サーバーを Claude と ChatGPT のどちらから呼び出しても、<strong>同一のウィジェットが同じ見た目で表示される</strong>点にも注目してください。</p>
<hr />
<h2>要考慮事項：ウィジェットの変更が反映されない</h2>
<p>ところで、ウィジェットの定義を更新後、デプロイは成功しているのに、AI エージェントアプリ側では<strong>古いレイアウトのまま</strong>という現象に悩まされました。組織側のメタデータを取得して確認しても、ローカルと内容は一致しています。それでも新しい見た目にならないのです。</p>
<p>原因は、<strong>AI エージェントアプリ（クライアント）側が、ウィジェットのテンプレートを <code>resourceUri</code> の文字列をキーにキャッシュしている</strong>からのようです。AI エージェントアプリの内部仕様で詳細は不明ですが<code>resourceUri</code> が同じままだと、中身をいくら変えても古いテンプレートが使われ続けるように見えました。</p>
<p>実際、クライアント側のコネクタ設定を見ると、<code>ui://widget/lightningType/c__accountOpportunitySummary...</code> という <code>resourceUri</code> をキーに、ウィジェットのテンプレート内容が保持されているのが確認できます。</p>
<figure>

			  <span class="postimagessection_specify alignnone size-medium wp-image-206874" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260824092846/05-ui-widget-url.png?w=1024" class="postimages" width="1024" height="590" alt="" />
			  </span>
			<br />
</figure>
<p><strong>ひとまずの対策は <code>resourceUri</code> のバージョニング</strong>です。</p>
<ol>
<li>LightningTypeBundle を新しい API 名でコピーする（例：<code>accountOpportunitySummaryResult</code> → <code>accountOpportunitySummaryResultV2</code>）</li>
<li><code>McpServerDefinition</code> の <code>&lt;resourceUri&gt;</code> と <code>&lt;uiResource&gt;</code> を新しいものに更新する</li>
<li>デプロイ後、AI エージェントアプリ側でコネクタ／プラグインを更新（再登録）する</li>
</ol>
<pre><code class="language-xml">&lt;!-- 変更前 --&gt;
&lt;resourceUri&gt;ui://widget/lightningType/c__accountOpportunitySummaryResult&lt;/resourceUri&gt;

&lt;!-- 変更後（V2 に）--&gt;
&lt;resourceUri&gt;ui://widget/lightningType/c__accountOpportunitySummaryResultV2&lt;/resourceUri&gt;</code></pre>
<p>なお、<strong>バージョニングが必要なのは <code>resourceUri</code> が指す LightningTypeBundle と McpServerDefinition だけ</strong>です。UiWidgetBundle は同じ名前のまま上書きデプロイで問題ありません（クライアントは URI をキーにキャッシュしているため、URI が変われば中身も取り直されます）。Apex や GenAiFunction も影響を受けません。</p>
<p>ただし、この対策はあまり美しいものとは言えません。今後の AI エージェントアプリ側でのキャッシュクリアなどよりスマートな解決策が出てくることを願っています。</p>
<hr />
<h2>おわりに</h2>
<p>本記事では、Apex・LightningType・UiWidgetBundle・GenAiFunction・McpServerDefinition を組み合わせて、<strong>組織の実データ（取引先の商談サマリー）を AI エージェントアプリにリッチなカードとして表示する</strong> HXL カスタムウィジェットを作りました。</p>
<p>従来、AI エージェントアプリに返せるのはテキストや静的なサンプルが中心でした。HXL と MCP を使うことで、<strong>Salesforce の実データを、意味のある UI として、外部の AI 体験に直接埋め込める</strong>ようになります。FLS や共有ルールも尊重されるため、セキュリティ面でも安心です。</p>
<p>一度この 7 ステップの型を押さえてしまえば、Apex のクエリとウィジェットの <code>tile</code> ツリーを差し替えるだけで、ケース一覧・在庫状況・売上ダッシュボードなど、さまざまなカスタムウィジェットに応用できます。ぜひ Developer Edition で試してみてください。</p>
<h2>参考資料</h2>
<ul>
<li><a href="https://developer.salesforce.com/docs/platform/hxl/overview">Headless Experience Layer Developer Guide (Beta)</a></li>
<li><a href="https://developer.salesforce.com/jpblogs/2026/04/salesforce-hosted-mcp-server-jp">Salesforce Hosted MCP Server 使い始め</a>（OAuth 接続手順）</li>
<li><a href="https://status.salesforce.com/">Salesforce Status</a>（インスタンスのパッチバージョン確認）</li>
<li><a href="https://github.com/hinabasfdc/hxl-mcp-widget-sample">本記事のサンプルコード一式（GitHub: hinabasfdc/hxl-mcp-widget-sample）</a></li>
</ul>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/08/headless-experience-layer-custom-ui-widget-jp">Headless Experience Layer によるカスタムウィジェット：MCP 経由で取引先の商談サマリーを AI エージェントアプリに表示する</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/08/headless-experience-layer-custom-ui-widget-jp/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206871</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260824092515/headless-experience-layer-custom-ui-widget-jp.png?w=1200" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260824092515/headless-experience-layer-custom-ui-widget-jp.png?w=1200" medium="image" />
	</item>
		<item>
		<title>Data and Communication Anti-Patterns in Lightning Web Components</title>
		<link>https://developer.salesforce.com/blogs/2026/08/data-and-communication-anti-patterns-in-lightning-web-components</link>
		<comments>https://developer.salesforce.com/blogs/2026/08/data-and-communication-anti-patterns-in-lightning-web-components#respond</comments>
		<pubDate>Thu, 20 Aug 2026 15:00:51 +0000</pubDate>
		<dc:creator><![CDATA[Tim Dionne]]></dc:creator>
				<category><![CDATA[App Development]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Developer Community]]></category>
		<category><![CDATA[Lightning Web Components]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[@wire Service]]></category>
		<category><![CDATA[Component Communication]]></category>
		<category><![CDATA[Event Handling]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[lightning data service]]></category>
		<category><![CDATA[lwc]]></category>
		<category><![CDATA[LWC Anti-Patterns]]></category>
		<category><![CDATA[Salesforce Architecture]]></category>
		<category><![CDATA[Salesforce Developer]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206863</guid>
		<description><![CDATA[<p>Learn how the wire service, public properties, and events move data through Lightning web components, and how to avoid reactivity and communication mistakes that cause stale UI, lost events, and hard-to-reproduce state bugs.</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/08/data-and-communication-anti-patterns-in-lightning-web-components">Data and Communication Anti-Patterns in Lightning Web Components</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">Most Lightning web component bugs fall into one of two categories: the component fetches the wrong data, or two components can&#8217;t talk to each other correctly. These problems are frustrating because the code looks right — the types are correct, there are no console errors — but the UI shows stale values, events disappear, or changes never propagate.</span></p>
<p>This is the second post in our series on LWC anti-patterns. The <a href="https://developer.salesforce.com/blogs/2026/06/security-anti-patterns-in-lightning-web-components"><u>first post</u></a> covered security and platform compatibility — how to write components that work within Lightning Web Security. In this post, you&#8217;ll learn the most common mistakes in three areas: the <a href="https://developer.salesforce.com/docs/platform/lwc/guide/data-wire-service-about.html"><u><code>@wire</code><span> service</span></u></a><span>, </span><a href="https://developer.salesforce.com/docs/platform/lwc/guide/js-props-intro.html"><u>public properties</u></a> (<code>@api</code>), and <a href="https://developer.salesforce.com/docs/platform/lwc/guide/events.html"><u>event handling</u></a>. Fixing these patterns is one of the highest-leverage things you can do to make your components more reliable.</p>
<h2><span style="font-weight: 400">Wire service anti-patterns</span></h2>
<p><span style="font-weight: 400">The wire service is how components reactively fetch Salesforce data, but its subscription model trips up developers who treat it like a one-time fetch. The patterns below cover the mistakes that lead to stale data, infinite loops, and updates that never arrive.</span></p>
<h3><span style="font-weight: 400"><code>@wire</code> is a subscription, not a fetch</span></h3>
<p><span>Before diving into specific anti-patterns, there&#8217;s one mental model shift that explains most wire service bugs: </span><b><code><span>@wire</span></code><span> is not a fetch wrapper</span></b><span>. It&#8217;s a subscription.</span></p>
<p>When you wire a property to <code>getRecord</code> (see <a href="https://developer.salesforce.com/docs/platform/lwc/guide/reference-wire-adapters-record.html"><u>docs</u></a>), you&#8217;re not making a one-time request. You&#8217;re subscribing to a stream. The adapter can emit multiple times — once from cache, again when the network responds, and again when any component on the page modifies that record. Your wire handler should be safe to call multiple times with the most recent value.</p>
<p><span style="font-weight: 400">This distinction matters for every pattern below.</span></p>
<h3><span style="font-weight: 400">Don&#8217;t mutate </span><span style="font-weight: 400"><code>@wire</code> </span><span style="font-weight: 400">results directly</span></h3>
<p><span style="font-weight: 400">Wire data is immutable. Assigning directly to a wired property, or to a nested field on that property, violates the contract with the wire service. The result is unpredictable: you may see stale data, missed reactive updates, or a render that doesn&#8217;t reflect your change.</span></p>
<pre language="javascript">@wire(getContacts)
contacts;

handleDelete(event) {
    // This won't work reliably — wire data is immutable
    this.contacts.data = this.contacts.data.filter(c =&gt; c.Id !== event.detail.id);
}
</pre>
<p><span style="font-weight: 400">Copy the data into a local property instead, and mutate that.</span></p>
<pre language="javascript">contacts = [];

@wire(getContacts)
wiredContacts({ data, error }) {
    if (data) {
        this.contacts = [...data];
    }
}

handleDelete(event) {
    this.contacts = this.contacts.filter(c =&gt; c.Id !== event.detail.id);
}
</pre>
<h3><span style="font-weight: 400">Don&#8217;t update wire config in </span><span style="font-weight: 400"><code>renderedCallback()</code></span></h3>
<p><code>renderedCallback()</code> (see <a href="https://developer.salesforce.com/docs/platform/lwc/guide/create-lifecycle-hooks-rendered.html"><u>docs</u></a>) runs after every render. If you change a reactive wire config property inside it, that change triggers a new render, which calls <code>renderedCallback()</code> again. You&#8217;ve created an infinite loop.</p>
<pre language="javascript">renderedCallback() {
    // This causes an infinite render loop
    this.recordId = this.template.querySelector('input').value;
}
</pre>
<p><span style="font-weight: 400">Update wire config properties in response to user events, not in rendering callbacks.</span></p>
<pre language="javascript">handleIdChange(event) {
    this.recordId = event.detail.value; // wire re-evaluates automatically
}
</pre>
<h3><span style="font-weight: 400">Don&#8217;t assume wire adapters fire in order</span></h3>
<p>Multiple wire adapters on the same component are independent subscriptions. The order they deliver data is not guaranteed, and neither is the number of times each fires. Code that reads from one wire result inside another wire&#8217;s handler, or reads wire data inside <code>connectedCallback()</code>, will fail silently when the <a href="https://developer.salesforce.com/docs/platform/lwc/guide/data-ui-api.html"><u>Lightning Data Service</u></a> (LDS) cache is cold.</p>
<pre language="javascript">connectedCallback() {
    // items.data is undefined on first load — this throws
    this.total = this.items.data.reduce((sum, item) =&gt; sum + item.UnitPrice__c, 0);
}
</pre>
<p><span style="font-weight: 400">Drive derived state from inside the wire handler itself, and guard against </span><span style="font-weight: 400">undefined</span><span style="font-weight: 400"> at every access.</span></p>
<pre language="javascript">@wire(getOrderItems, { orderId: '$recordId' })
wiredItems({ data }) {
    if (data) {
        this.items = data;
        this.total = data.reduce((sum, item) =&gt; sum + item.UnitPrice__c, 0);
    }
}
</pre>
<p><span style="font-weight: 400">If derived state depends on two adapters, compute it once both have delivered.</span></p>
<pre language="javascript">updateTotal() {
    if (this.order &amp;&amp; this.items.length &gt; 0) {
        this.total = this.items.reduce((sum, item) =&gt; sum + item.UnitPrice__c, 0);
    }
}

@wire(getOrder, { recordId: '$recordId' })
wiredOrder({ data }) {
    if (data) {
        this.order = data;
        this.updateTotal();
   }
}

@wire(getOrderItems, { orderId: '$recordId' })
wiredItems({ data }) {
    if (data) {
        this.items = data;
        this.updateTotal();
    }
}
</pre>
<h3><span style="font-weight: 400">Use schema imports for object and field references</span></h3>
<p><span style="font-weight: 400">Hard-coding SObject or field names as strings bypasses Salesforce&#8217;s ability to validate references, prevent accidental deletion, and cascade renames. A renamed field silently breaks the component at runtime.</span></p>
<pre language="javascript">// String literals — not validated at deploy time
@wire(getRecord, { recordId: '$recordId', fields: ['Account.Name', 'Account.Industry'] })
account;
</pre>
<p>Import field tokens from <code>@salesforce/schema</code> instead. The platform validates these at build time.</p>
<pre language="javascript">import ACCOUNT_OBJECT from '@salesforce/schema/Account';
import NAME_FIELD from '@salesforce/schema/Account.Name';
import INDUSTRY_FIELD from '@salesforce/schema/Account.Industry';

@wire(getRecord, { recordId: '$recordId', fields: [NAME_FIELD, INDUSTRY_FIELD] })
account;
</pre>
<h3><span style="font-weight: 400">Use the correct field path in</span><span style="font-weight: 400"> <code>getRecord</code></span></h3>
<p>Every field in a <code>getRecord</code> <code>fields</code> array must be reachable from the record&#8217;s own object type. Specifying a top-level field from a different object — like including <code>Account.Name</code> in a call for a Case record — produces a malformed config. The component receives incomplete data. Because Aura components share the same Lightning Data Service (LDS) cache, a malformed config can affect those Aura components too.</p>
<pre language="javascript">// Wrong — Account.Name is not a field on Case
@wire(getRecord, { recordId: '$recordId', fields: [CASE_SUBJECT, ACCOUNT_NAME] })
record;
</pre>
<p><span style="font-weight: 400">To access a related record&#8217;s field, use the full relationship path starting from the base object.</span></p>
<pre language="javascript">import CASE_ACCOUNT_NAME from '@salesforce/schema/Case.Account.Name';

// Correct — traversal expressed from Case
@wire(getRecord, { recordId: '$recordId', fields: [CASE_SUBJECT, CASE_ACCOUNT_NAME] })
record;
</pre>
<h3><span style="font-weight: 400">Don&#8217;t use </span><span style="font-weight: 400"><code>@wire</code> </span><span style="font-weight: 400">for write operations</span></h3>
<p><code>@wire</code> is for read operations only. Using it to invoke an Apex method that performs DML gives you unpredictable invocation timing and no way to handle errors in the UI.</p>
<pre language="javascript">// Don't wire a method that performs DML
@wire(saveRecord, { record: '$record' })
savedResult;
</pre>
<p><span style="font-weight: 400">Use </span><a href="https://developer.salesforce.com/docs/platform/lwc/guide/apex-call-imperative.html"><span style="font-weight: 400">imperative Apex calls</span></a><span style="font-weight: 400"> for any operation that writes data.</span></p>
<pre language="javascript">async handleSave() {
    try {
        await saveRecord({ record: this.record });
        this.dispatchEvent(new CustomEvent('saved'));
    } catch (error) {
        // show error in UI
    }
}
</pre>
<h3><span style="font-weight: 400">Don&#8217;t mix Apex and LDS for the same record</span></h3>
<p><span style="font-weight: 400">Apex and Lightning Data Service (LDS) maintain separate, independent caches. When you fetch the same record through both at the same time, the two copies can diverge — one reflecting a recent server change, the other serving a stale value. The result is inconsistent UI state that&#8217;s hard to reproduce.</span></p>
<p><span style="font-weight: 400">Pick one data source per record and use it consistently. Use LDS wire adapters when they support your use case. Use Apex only when LDS doesn&#8217;t (unsupported objects, complex queries, transactional operations).</span></p>
<h3><span style="font-weight: 400">Don&#8217;t use </span><span style="font-weight: 400"><code>refreshApex()</code> </span><span style="font-weight: 400;font-size: 16px">on LDS wire adapters</span></h3>
<p><code>refreshApex()</code>(see <a href="https://developer.salesforce.com/docs/platform/lwc/guide/apex-result-caching.html#refresh-the-cache-when-using-wire"><u>docs</u></a>) is designed for wired Apex methods only. Calling it on an LDS adapter like <code>getRecord</code> is deprecated and has no reliable effect. LDS manages its own cache automatically when records change through LDS-aware operations.</p>
<pre language="javascript">handleRefresh() {
    refreshApex(this.record); // deprecated for LDS adapters
}
</pre>
<p>To signal that a record&#8217;s cached data is stale after an out-of-band write, use <code>notifyRecordUpdateAvailable()</code> (see <a href="https://developer.salesforce.com/docs/platform/lwc/guide/reference-notify-record-update.html"><u>docs</u></a>).</p>
<pre language="javascript">import { notifyRecordUpdateAvailable } from 'lightning/uiRecordApi';

async handleRefresh() {
    await notifyRecordUpdateAvailable([{ recordId: this.recordId }]);
    // LDS now has fresh data for all subscribed adapters
}
</pre>
<p><span style="font-weight: 400">All active wire adapters subscribed to that record will automatically receive fresh data.</span></p>
<h3><span style="font-weight: 400">Call </span><span style="font-weight: 400"><code>notifyRecordUpdateAvailable()</code> </span><span style="font-weight: 400">after imperative Apex writes</span></h3>
<p><span style="font-weight: 400">When an imperative Apex method modifies a record, LDS doesn&#8217;t know about it. Every LDS wire adapter on the page — including those in sibling and parent components — continues to serve its cached, pre-mutation value. The UI shows stale data with no error.</span></p>
<pre language="javascript">async handleSave() {
    await updateAccount({ recordId: this.recordId, name: this.name });
    // LDS still has the old value — nothing updates here
}
</pre>
<p><span style="font-weight: 400">After the write completes, notify LDS that the record is stale.</span></p>
<pre language="javascript">import { notifyRecordUpdateAvailable } from 'lightning/uiRecordApi';

async handleSave() {
    await updateAccount({ recordId: this.recordId, name: this.name });
    await notifyRecordUpdateAvailable([{ recordId: this.recordId }]);
    // LDS now has fresh data
}
</pre>
<p><span style="font-weight: 400">This keeps all LDS wire adapters across the page consistent with the server state.</span></p>
<h3><span style="font-weight: 400">Use config gating for dependent data, not promise chains</span></h3>
<p>When loading data that depends on the result of another fetch — like fetching an Account after you have its ID from a Case — developers often reach for nested imperative Apex calls or <code>Promise.then()</code> (see <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise"><u>docs</u></a>) chains. This is fragile, doesn&#8217;t participate in LDS caching, and doesn&#8217;t recover automatically when upstream data changes.</p>
<p>The wire service handles this natively: a wire adapter won&#8217;t evaluate until all of its required config properties are truthy. Keep a reactive config property <code>undefined</code> until upstream data arrives, and the second adapter gates automatically.</p>
<pre language="javascript">@api recordId;   // Case record ID
accountId;       // undefined until first wire delivers

@wire(getRecord, { recordId: '$recordId', fields: [CASE_ACCOUNT_ID] })
wiredCase({ data }) {
    if (data) {
        this.accountId = data.fields.AccountId.value; // triggers second wire
    }
}

// Does not evaluate until accountId is truthy
@wire(getRecord, { recordId: '$accountId', fields: [ACCOUNT_NAME] })
accountRecord;
</pre>
<p>Both records now participate in the LDS cache. If the Case&#8217;s <code>AccountId</code> changes, the second wire re-fetches the new Account automatically.</p>
<h3><span style="font-weight: 400">Don&#8217;t swap the config object to &#8220;re-fetch&#8221;</span></h3>
<p>The <code>@wire</code> reactive system tracks individual top-level class properties, not nested object contents or the config object reference. Replacing the entire config object doesn&#8217;t trigger re-evaluation.</p>
<pre language="javascript">currentConfig = { recordId: '001000000000001', fields: [NAME_FIELD] };

@wire(getRecord, '$currentConfig')
record;

handleSelectRecord(event) {
    // Swapping the object doesn't trigger re-evaluation
    this.currentConfig = { recordId: event.detail.recordId, fields: [NAME_FIELD] };
}
</pre>
<p>Declare reactive config values as individual top-level properties and reference them with <code>$</code>.</p>
<pre language="javascript">recordId;

@wire(getRecord, { recordId: '$recordId', fields: [NAME_FIELD] })
record;

handleSelectRecord(event) {
    this.recordId = event.detail.recordId; // wire re-evaluates automatically
}
</pre>
<h3><span style="font-weight: 400">Don&#8217;t add dummy </span><span style="font-weight: 400"><code>optionalField</code> </span><span style="font-weight: 400">to bust the LDS cache</span></h3>
<p>Some developers add irrelevant fields to <code>optionalFields</code> hoping to force a cache miss. This doesn&#8217;t work. <code>optionalFields</code> are fetched opportunistically when already in the cache and silently omitted when not. They don&#8217;t invalidate cache entries for required fields.</p>
<p>Use <code>notifyRecordUpdateAvailable()</code> after any out-of-band write to signal LDS that the record is stale. See the pattern above.</p>
<h3><span style="font-weight: 400">Design wire handlers to be idempotent</span></h3>
<p>Because <code>@wire</code> is a subscription stream that can emit multiple times, wire handlers must be safe to call with a fresh value at any time. A handler that performs one-time initialization side effects will leave the component in a stale state after subsequent emissions.</p>
<pre language="javascript">@wire(getRecord, { recordId: '$recordId', fields: [NAME_FIELD] })
wiredRecord({ data }) {
    if (data) {
        this.record = data;
        this.initializeChart(data); // breaks on second emission
    }
}
</pre>
<p><span style="font-weight: 400">Derive all displayed state from the most recent emission. For side effects that genuinely run once, guard them with a flag and keep them separate from the data-update logic:</span></p>
<pre language="javascript">_chartInitialized = false;

wiredRecord({ data }) {
    if (data) {
        this.record = data;
        if (!this._chartInitialized) {
            this._chartInitialized = true;
            this.initializeChart(data);
        }
        this.updateChart(data); // idempotent update path

    }
}
</pre>
<h2><span style="font-weight: 400">Public property anti-patterns</span></h2>
<p><span style="font-weight: 400">Public properties (@api) define the contract between a component and its parent. Data flows down through them, and the patterns below cover the mistakes that break that one-way flow or leak your component&#8217;s internal state to the outside.</span></p>
<h3><span style="font-weight: 400">Don&#8217;t reassign <code>@api</code></span><span style="font-weight: 400"> properties internally</span></h3>
<p><code>@api</code> properties are owned by the parent component. They flow data downward. If you reassign an <code>@api</code> property from within your own component, you break the unidirectional data flow contract, which can cause infinite update cycles and runtime warnings from the LWC engine.</p>
<pre language="javascript">@api value = '';

handleInput(event) {
    this.value = event.target.value; // reassigning an @api property
}
</pre>
<p><span style="font-weight: 400">Store the working value in a private property and expose a getter for the public interface.</span></p>
<pre language="javascript">_value = '';

@api
get value() { return this._value; }
set value(v) { this._value = v; }

handleInput(event) {
    this._value = event.target.value;
    this.dispatchEvent(new CustomEvent('change', { detail: { value: this._value } }));
}
</pre>
<h3><span style="font-weight: 400">Don&#8217;t pass objects by reference in event </span><span style="font-weight: 400"><code>detail</code></span></h3>
<p>JavaScript passes objects by reference. When you put an object directly into a <code>CustomEvent</code> <code>detail</code> (see <a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent"><u>docs</u></a>), any listener can mutate the original. This creates hidden coupling and hard-to-debug state corruption.</p>
<pre language="javascript">handleSave() {
    this.dispatchEvent(new CustomEvent('save', { detail: this.record })); // mutable reference
}
</pre>
<p><span style="font-weight: 400">Pass a </span><a href="https://developer.mozilla.org/en-US/docs/Glossary/Shallow_copy"><span style="font-weight: 400">shallow copy</span></a><span style="font-weight: 400"> so listeners can&#8217;t affect your component&#8217;s state.</span></p>
<pre language="javascript">handleSave() {
    this.dispatchEvent(new CustomEvent('save', { detail: { ...this.record } }));
}
</pre>
<h2><span style="font-weight: 400">Event handling anti-patterns</span></h2>
<p><span style="font-weight: 400">Events carry data upward, from a component to its ancestors. The patterns below cover the mistakes that make events hard to listen for, leak mutable state between listeners, or quietly break component encapsulation.</span></p>
<h3><span style="font-weight: 400">Use</span><span style="font-weight: 400"> <code>CustomEvent</code></span><span style="font-weight: 400"></span><span style="font-weight: 400">, not</span><span style="font-weight: 400"> <code>Event</code></span></h3>
<p>Unlike <code>CustomEvent</code>, the base <a href="https://developer.mozilla.org/en-US/docs/Web/API/Event/Event"><u><code>Event</code><span> constructor</span></u></a><span> doesn&#8217;t support a </span><code>detail</code> property. Using it forces you to attach data through non-standard properties, which is fragile and inconsistent with platform conventions.</p>
<pre language="javascript">this.dispatchEvent(new Event('recordselected'));
</pre>
<pre language="javascript">this.dispatchEvent(new CustomEvent('recordselected', {
    detail: { recordId: this.selectedId }
}));
</pre>
<h3><span style="font-weight: 400">Don&#8217;t prefix event names with &#8220;on&#8221;</span></h3>
<p>HTML attribute syntax uses <code>on</code> as a prefix for event handlers. If you name your custom event <code>onstatuschange</code>, a parent component must listen for it as <code>ononstatuschange</code> — which is confusing and risks conflicts with reserved event names.</p>
<pre language="javascript">this.dispatchEvent(new CustomEvent('statuschange', { detail: { status } }));
</pre>
<pre language="html">&lt;c-child onstatuschange={handleStatusChange}&gt;&lt;/c-child&gt;
</pre>
<h3><span style="font-weight: 400">Don&#8217;t mutate</span><span style="font-weight: 400"> <code>event.detail</code></span></h3>
<p><code>event.detail</code> is a shared object reference. Mutating it inside your handler modifies the object that other listeners in the same bubbling chain will read.</p>
<pre language="javascript">handleStatusChange(event) {
    event.detail.status = 'processed'; // affects other listeners
    this.currentStatus = event.detail.status;
}
</pre>
<p>Read from <code>event.detail</code> and store the value locally — never write back to it.</p>
<pre language="javascript">handleStatusChange(event) {
    this.currentStatus = event.detail.status;
}
</pre>
<p><span style="font-weight: 400">If you need to enrich event data for upstream listeners, stop the original event and re-dispatch a new one with the updated payload. This makes the transformation explicit.</span></p>
<pre language="javascript">handleStatusChange(event) {
    event.stopPropagation();
    this.dispatchEvent(new CustomEvent('statuschange', {
        bubbles: true,
        detail: { ...event.detail, status: 'processed', processedAt: Date.now() }
    }));
}
</pre>
<h3><span style="font-weight: 400">Always remove event listeners you add imperatively</span></h3>
<p>Listeners added via <code>addEventListener</code> (see <a href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener"><u>docs</u></a>) to elements outside your component&#8217;s template — like <code>window</code> (see <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window"><u>docs</u></a>) or <code>document</code> (see <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document"><u>docs</u></a>) — will hold a reference to your component after it disconnects. This prevents garbage collection and can fire callbacks on a disconnected component.</p>
<pre language="javascript">connectedCallback() {
    window.addEventListener('resize', this.handleResize.bind(this)); // never removed
}
</pre>
<p>The cleanest fix is to declare the event handler as an arrow function class field, which is bound at class definition time and always has the same reference. Then, remove the event handler by calling <code>removeEventListener()</code> (see <a href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener"><u>docs</u></a>).</p>
<pre language="javascript">handleResize = () =&gt; {
    this.width = window.innerWidth;
};

connectedCallback() {
    window.addEventListener('resize', this.handleResize);
}

disconnectedCallback() {
    window.removeEventListener('resize', this.handleResize);
}
</pre>
<h3><span style="font-weight: 400">Don&#8217;t call </span><span style="font-weight: 400"><code>.bind()</code> </span><span style="font-weight: 400">inline with </span><span style="font-weight: 400"><code>addEventListener</code></span><span style="font-weight: 400"></span></h3>
<p><code>.bind()</code> (see <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind"><u>docs</u></a>) returns a <b>new function object</b> every time it&#8217;s called. If you pass <code>this.handler.bind(this)</code> to <code>addEventListener</code> and then pass <code>this.handler.bind(this)</code> again to <code>removeEventListener</code>, you&#8217;re passing two different functions. The listener is never removed.</p>
<pre language="javascript">connectedCallback() {
    window.addEventListener('scroll', this.handleScroll.bind(this));
}

disconnectedCallback() {
    window.removeEventListener('scroll', this.handleScroll.bind(this)); // different function — does nothing
}
</pre>
<p>Use an arrow function class field (same reference always) or store a single <code>.bind()</code> result in a property and reuse it.</p>
<pre language="javascript">// Arrow field — preferred
handleScroll = () =&gt; { this.scrollTop = window.scrollY; };

// Or stored bind reference
connectedCallback() { this._scrollHandler = this.handleScroll.bind(this); }
</pre>
<h3><span style="font-weight: 400">Don&#8217;t use </span><span style="font-weight: 400"><code>bubbles: true, composed: true</code> unneccessarily</span></h3>
<p>Setting both <code>bubbles </code><span>(see </span><a href="https://developer.mozilla.org/en-US/docs/Web/API/Event/bubbles"><u>docs</u></a><span>) </span><span>and </span><code>composed</code> (see <a href="https://developer.mozilla.org/en-US/docs/Web/API/Event/composed"><u>docs</u></a>) event properties to <code>true</code> causes the event to propagate through every shadow boundary all the way to the document root. This breaks encapsulation, creates implicit dependencies on ancestor components, and risks event name collisions higher in the tree. The LWC documentation is explicit: &#8220;Lightning web components don&#8217;t use this configuration.&#8221;</p>
<p>Use the default (<code>bubbles: false, composed: false</code>) for events handled by a direct parent. Use <code>bubbles: true, composed: false</code> only when a grandparent within the same shadow tree needs to hear the event. Reserve <code>composed: true</code> for rare cases where crossing a shadow boundary is genuinely necessary, and stop propagation at the first component that handles it.</p>
<h3><span style="font-weight: 400">Replace </span><span style="font-weight: 400"><code>pubsub</code> </span><span style="font-weight: 400">with Lightning Message Service</span></h3>
<p><span style="font-weight: 400">The community </span><a href="https://github.com/developerforce/pubsub"><span style="font-weight: 400">pubsub</span></a><span style="font-weight: 400"> module is deprecated and no longer actively maintained. It only works within a single page, can&#8217;t cross namespace boundaries, and requires manual unregistration — a step that&#8217;s easy to forget and causes memory leaks.</span></p>
<p>Use Lightning Message Service — <code>lightning/messageService</code> — (see <a href="https://developer.salesforce.com/docs/platform/lightning-component-reference/guide/lightning-message-service?type=Develop"><u>docs</u></a>) instead. It works across LWC, Aura, and Visualforce components, spans multiple pages and namespaces, and manages subscription lifecycle cleanly.</p>
<pre language="javascript">import { subscribe, unsubscribe, MessageContext } from 'lightning/messageService';
import RECORD_SELECTED_CHANNEL from '@salesforce/messageChannel/RecordSelected__c';

export default class RecordConsumer extends LightningElement {
    @wire(MessageContext) messageContext;
    _subscription;

    connectedCallback() {
        this._subscription = subscribe(
            this.messageContext,
            RECORD_SELECTED_CHANNEL,
            (message) =&gt; this.handleRecordSelected(message)
        );
    }

    disconnectedCallback() {
        unsubscribe(this._subscription);
        this._subscription = null;
    }
}
</pre>
<h3><span style="font-weight: 400">Don&#8217;t register capture-phase listeners</span></h3>
<p>LWC doesn&#8217;t support the <code>capture</code> (see <a href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#capture"><u>docs</u></a>) phase of DOM event propagation. Passing <code>{ capture: true }</code> to <code>addEventListener</code> has no effect — the listener won&#8217;t fire on the way down the tree. There&#8217;s no runtime error; the code just behaves as if the option wasn&#8217;t set.</p>
<p>Design event handling around the bubbling phase. If you need to intercept an event before child components handle it, restructure the component tree so the intercepting component is a direct parent, or use a declarative handler on the child element in the template.</p>
<h2><span style="font-weight: 400">Conclusion</span></h2>
<p><span style="font-weight: 400">The patterns in this post share a common root: misunderstanding how data flows through LWC. The wire service is a subscription stream — not a fetch call. </span><span style="font-weight: 400">@api</span><span style="font-weight: 400"> properties flow down from the parent — they&#8217;re not yours to reassign. Events carry immutable snapshots — don&#8217;t mutate their payloads or attach shared object references to them.</span></p>
<p><span style="font-weight: 400">Correcting your mental model on these three surfaces prevents the large majority of data and communication bugs in LWC development.</span></p>
<p><span style="font-weight: 400">In the next and final post in this series, we&#8217;ll cover </span><b>runtime behavior</b><span style="font-weight: 400"> — DOM access, component lifecycle, async patterns, performance, and base component usage.</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/lwc/guide/data-wire-service-about.html"><span style="font-weight: 400">Wire Service documentation</span></a></li>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.reference_wire_adapters_record"><span style="font-weight: 400">LDS — getRecord</span></a></li>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.reference_notify_record_update"><span style="font-weight: 400">notifyRecordUpdateAvailable()</span></a></li>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.use_message_channel"><span style="font-weight: 400">Lightning Message Service</span></a></li>
<li style="font-weight: 400"><a href="https://developer.salesforce.com/docs/platform/lwc/guide/events.html"><span style="font-weight: 400">LWC Events documentation</span></a></li>
<li style="font-weight: 400"><a href="https://github.com/salesforce/eslint-plugin-lwc"><span style="font-weight: 400">@lwc/eslint-plugin-lwc rules</span></a></li>
</ul>
<h2><span style="font-weight: 400">About the author</span></h2>
<p><b>Tim Dionne</b><span style="font-weight: 400"> is a Principal Member of Technical Staff (PMTS) on the Customer Centric Engineering team. He&#8217;s worked on many UI features of Salesforce over the years, starting with VisualForce, Aura Components, and Lightning Web Components with an emphasis on Lightning Web Security and Lightning Data Service.</span></p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/08/data-and-communication-anti-patterns-in-lightning-web-components">Data and Communication Anti-Patterns in Lightning Web 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/08/data-and-communication-anti-patterns-in-lightning-web-components/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206863</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260819155500/Generic-D-7.png?w=1778" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260819155500/Generic-D-7.png?w=1778" medium="image" />
	</item>
		<item>
		<title>The Salesforce Developer’s Guide to Dreamforce 2026</title>
		<link>https://developer.salesforce.com/blogs/2026/08/developers-guide-dreamforce-2026</link>
		<comments>https://developer.salesforce.com/blogs/2026/08/developers-guide-dreamforce-2026#respond</comments>
		<pubDate>Wed, 19 Aug 2026 16:00:05 +0000</pubDate>
		<dc:creator><![CDATA[Sarah Welker]]></dc:creator>
				<category><![CDATA[Agentforce]]></category>
		<category><![CDATA[Agentforce Vibes]]></category>
		<category><![CDATA[Apex]]></category>
		<category><![CDATA[APIs and Integrations]]></category>
		<category><![CDATA[App Development]]></category>
		<category><![CDATA[Data 360]]></category>
		<category><![CDATA[Developer Community]]></category>
		<category><![CDATA[Developer Tooling]]></category>
		<category><![CDATA[Headless 360]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Salesforce Events]]></category>
		<category><![CDATA[Agenda Builder]]></category>
		<category><![CDATA[Agent Script]]></category>
		<category><![CDATA[Agentic Enterprise]]></category>
		<category><![CDATA[Camp Mini Hack]]></category>
		<category><![CDATA[developer community]]></category>
		<category><![CDATA[developer keynote]]></category>
		<category><![CDATA[Dreamforce 2026]]></category>
		<category><![CDATA[MCP Servers]]></category>
		<category><![CDATA[salesforce]]></category>
		<category><![CDATA[salesforce developers]]></category>
		<category><![CDATA[salesforce mobile sdk]]></category>
		<category><![CDATA[Slack Integration]]></category>
		<category><![CDATA[Trailblazer Forest]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206837</guid>
		<description><![CDATA[<p>Build the Agentic Enterprise at Dreamforce 2026, September 15&ndash;17, in San Francisco or on Salesforce+.</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/08/developers-guide-dreamforce-2026">The Salesforce Developer’s Guide to Dreamforce 2026</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">Calling all Salesforce Developers: it’s time to build the Agentic Enterprise. Powered by you, amplified by agents. </span><a href="https://www.salesforce.com/dreamforce/"><span style="font-weight: 400">Dreamforce</span></a><span style="font-weight: 400"> delivers three days of limitless impact with 1,600+ breakout sessions, 150+ hands-on trainings and demos, 50+ keynotes, and 240+ community roundtables. Get hands-on through expert-led training, live demos, and real-world stories to build the next generation of apps and agents. Plus, get direct access to the product experts and visionaries shaping the future of AI and agentic software.</span></p>
<p><span style="font-weight: 400">Whether you’re joining us in San Francisco or tuning in on </span><a href="https://www.salesforce.com/plus/experience/dreamforce_2026?d=afx"><span style="font-weight: 400">Salesforce+</span></a><span style="font-weight: 400">, we’ve curated our top Dreamforce recommendations for developers to help you make the most of your experience. </span></p>
<p><span style="font-weight: 400">Ready to plan your perfect three days? With </span><a href="https://reg.salesforce.com/flow/plus/df26/myagenda/page/myagenda"><span style="font-weight: 400">My Agenda</span></a><span style="font-weight: 400"> now live, it’s time to start building your schedule. See the sessions you’ve added alongside personalized, AI-powered recommendations based on your interests, so you can quickly add sessions that interest you or hide them anytime. Explore the must-attend experiences for developers, from practical training and deep technical dives to hands-on agent-building sessions designed to give you the skills and confidence needed to put what you learn into production right away.</span></p>
<h2><b>Prepare for Dreamforce 2026</b></h2>
<h3><span style="font-weight: 400">Road to Dreamforce Quest</span></h3>
<p><span style="font-weight: 400">Before arriving at Dreamforce, dive into hands-on learning, must-see sessions, and curated resources to help you build your Agentic Enterprise. Complete the </span><a href="https://trailhead.salesforce.com/users/teamtrailhead/trailmixes/road-to-dreamforce-2026-quest"><span style="font-weight: 400">Road to Dreamforce Quest</span></a><span style="font-weight: 400"> by September 14, 2026, and you’ll be entered for a chance to win* 1 of 100 prize boxes. </span><i><span style="font-weight: 400">*No purchase necessary. Void where prohibited. Country of residence and other restrictions apply. See the </span></i><a href="https://trailhead.salesforce.com/quests"><i><span style="font-weight: 400">Trailblazer Quests page</span></i></a><i><span style="font-weight: 400"> for full details and restrictions.</span></i></p>
<h3><span style="font-weight: 400">Developer Trail Map</span></h3>
<p><span style="font-weight: 400">The </span><a href="https://reg.salesforce.com/flow/plus/df26/developertrailmap/page/trailmap?_ga=2.115056263.14357231.1786384291-1997898997.1775245343"><span style="font-weight: 400">Dreamforce Developer Trail Map</span></a><span style="font-weight: 400"> is your guide to Dreamforce for developers. We&#8217;ve curated the experiences, sessions, and connections most relevant to you so you can explore what to prioritize and make every moment at Dreamforce count.</span></p>
<h2><b>Dreamforce keynotes for developers</b></h2>
<p><span style="font-weight: 400">Dreamforce is jam-packed with must-see sessions for developers. If you’re attending in person, be sure to add these sessions to your agenda. Can’t join us in San Francisco? Register for the livestream on </span><a href="https://www.salesforce.com/plus/experience/dreamforce_2026?d=afx"><span style="font-weight: 400">Salesforce+</span></a><span style="font-weight: 400"> to tune in remotely.</span></p>
<h3><span style="font-weight: 400">Main Keynote</span></h3>
<p><span style="font-weight: 400">Join Salesforce Chair and CEO Marc Benioff, along with special guests, to explore what it means to become an Agentic Enterprise, where humans, agents, and platforms together promote customer success.<br />
</span><span style="font-weight: 400"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span><a href="https://reg.salesforce.com/flow/plus/df26/sessioncatalog/page/catalog/session/1776704005612001dxP3"><span style="font-weight: 400">Add to your agenda</span></a><br />
<span style="font-weight: 400"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4bb.png" alt="💻" class="wp-smiley" style="height: 1em; max-height: 1em;" /><a href="https://www.salesforce.com/plus/experience/dreamforce_2026/dreamforce-main-keynote-2026">Watch on Salesforce+</a></span></p>
<h3><span style="font-weight: 400">Developer Keynote: Build the Agentic Enterprise</span></h3>
<p><span style="font-weight: 400">Join Christophe Coenraets and Salesforce Developer Advocates for a keynote built by developers, for developers. See Headless 360 and the latest AI-powered innovations in action through live demos, and discover how AI is transforming your developer workflows.</span><span style="font-weight: 400"><br />
</span><span style="font-weight: 400"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span><a href="https://reg.salesforce.com/flow/plus/df26/sessioncatalog/page/catalog/session/1781727007867001leU5"><span style="font-weight: 400">Add to your agenda</span></a><br />
<span style="font-weight: 400"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4bb.png" alt="💻" class="wp-smiley" style="height: 1em; max-height: 1em;" /><a href="https://www.salesforce.com/plus/experience/dreamforce_2026/developer-keynote-1">Watch on Salesforce+</a></span></p>
<h3><span style="font-weight: 400">True to the Core </span></h3>
<p><span style="font-weight: 400">Join Co-Founder Parker Harris and other Salesforce product leaders as they answer your questions in this fan-favorite, unscripted keynote. This is a unique opportunity to ask your questions and get answers directly from the experts.<br />
</span><span style="font-weight: 400"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span><a href="https://reg.salesforce.com/flow/plus/df26/sessioncatalog/page/catalog/session/1781727008652001lBd7"><span style="font-weight: 400">Add to your agenda</span></a><br />
<span style="font-weight: 400"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4bb.png" alt="💻" class="wp-smiley" style="height: 1em; max-height: 1em;" /><a href="https://www.salesforce.com/plus/experience/dreamforce_2026/true-to-the-core%3A-live-q_a-with-product-leaders">Watch on Salesforce+</a></span></p>
<h2><b>Build the Agentic Enterprise in Trailblazer Forest</b></h2>
<p><span style="font-weight: 400">Once you’ve secured your badge, head to Trailblazer Forest to see the Agentic Enterprise in action. Created for admins, developers, and architects, this core hub brings Agentforce, Headless 360, Slack, and Data 360 to life through hands-on experiences, technical demos, and expert-led sessions. Gain the foundational expertise and confidence to build and deploy trusted agents in production at scale.</span></p>
<h3><span style="font-weight: 400">Attend introductory sessions at Headless 360 Theater</span></h3>
<p><span style="font-weight: 400">Headless 360 Theater features six repeating 20-minute sessions that break down the core innovations of the Agentic Enterprise. Whether you’re an admin, developer, architect, or new to the Salesforce ecosystem, these expert-led introductory sessions provide the essential foundation you need before diving into deeper demos and workshops at Dreamforce. Sessions include:</span></p>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">Introduction to Headless 360</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Introduction to Agentforce</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Introduction to Agentic Experiences in Slack</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Introduction to Salesforce Vibe Coding Agents</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Introduction to Data 360</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Introduction to Platform</span></li>
</ul>
<h3><span style="font-weight: 400">See Headless 360 in action through live demos</span></h3>
<p><span style="font-weight: 400">Visit the Headless 360 zone to see how unified context and flexible deployment coexist. Through live demos, discover how Headless 360, Hosted MCP Servers, Multi-Framework, and HXL empower you to ground coding agents in real org metadata. Learn how to deploy across various frameworks and render rich UIs natively on React and Slack, all with built-in governance.</span></p>
<h3><span style="font-weight: 400">Get hands-on at Headless 360 Basecamp</span></h3>
<p><span style="font-weight: 400">Headless 360 Basecamp is where you’ll get firsthand experience building with any coding agent and deploying on any surface with Salesforce Headless 360. Start at the Welcome Desk to learn how to complete this stop of the Developer Quest by participating in the area’s activity, and earn an exclusive Agent Codey backpack. Then, get hands-on in a guided, 15-minute activity where you&#8217;ll learn how to configure Salesforce MCPs within a third-party AI system. Technical experts will be available in the area to help as you go through the exercise.</span></p>
<h3><span style="font-weight: 400">Dive deeper with product demos at Platform Park</span></h3>
<p><span style="font-weight: 400">Platform Park features 20 expert-led demos, including 18 platform demos and 2 customer success demos, designed to turn inspiration into implementation. Whether you’re a developer, admin, architect, or partner, go beyond keynotes and sessions to learn how to securely connect data, applications, and AI at scale. Gain practical insights, engage in discussions, and access guided builds that equip you to turn Salesforce innovation into real business outcomes.</span></p>
<h3><span style="font-weight: 400">Hear from the experts in Developer Grove</span></h3>
<p><span style="font-weight: 400">This is your #1 stop for developer-focused sessions in Trailblazer Forest. Catch sessions and demos from Salesforce experts throughout Dreamforce, covering everything from Agentforce Vibes and Agent Script to Headless Data 360 and Apex best practices. It&#8217;s the perfect spot to sit back, recharge, and soak up technical content between your other activities and experiences in Trailblazer Forest.</span></p>
<h3><span style="font-weight: 400">Test your skills at Camp Mini Hack</span></h3>
<p><span style="font-weight: 400">Start building the Agentic Enterprise at Camp Mini Hack. Get hands-on with Agentforce, Headless 360, vibe coding, Apex &amp; Flow, and Data 360 through 30-minute challenges designed for every skill level. Build and deploy working agents with on-demand expert help and real-time automated validation, while earning prizes along the way.</span></p>
<h3><span style="font-weight: 400">Master the full agent lifecycle in the Agentforce Zone</span></h3>
<p><span style="font-weight: 400">Explore the full lifecycle of autonomous AI agents at the Agentforce Zone. Through interactive, expert-led demos, developers will see how to create, deploy, and scale production-ready agents. Discover how Agentforce Studio, Agentforce Builder, Agentforce Operations (formerly known as Regrello), Agentforce Voice, Multi-Agent Orchestration, and Agentforce Observability bring AI-first workflows to life.</span></p>
<h3><span style="font-weight: 400">Skill up at Camp Trailhead</span></h3>
<p><span style="font-weight: 400">Get hands-on with Salesforce in 30 minutes at Camp Trailhead. Whether you’re brand new to the platform or an experienced pro, complete hands-on Trailhead badges covering key innovations like Headless 360, Agentforce Coworker, Help Agent, Salesforce Flow, and more. Work on provided laptops or bring your own, receive real-time support from on-site experts, and when you complete one of the highlighted badges, be sure to stop by the prize desk to collect your reward.</span></p>
<h3><span style="font-weight: 400">Get a peek into the future at Sneak Peeks</span></h3>
<p><span style="font-weight: 400">Sneak Peeks is back at Dreamforce to give admins, developers, and architects an exclusive look at what’s next for the platform. Catch sessions covering unreleased features across Agentforce, Headless, Flow, and User Access Management. Afterward, stick around for live Q&amp;A to get your burning technical questions answered directly by the product experts.</span></p>
<h3><span style="font-weight: 400">Connect people, data, and agents in Slack</span></h3>
<p><span style="font-weight: 400">Slack is the work operating system for the Agentic Enterprise, a multiplayer workspace where Salesforce data, agents, and teams seamlessly collaborate. Step into a real Salesforce org to experience headless automation brought to life. Get hands-on working a sales cycle, service retro, or campaign using interactive Slackbot skills. Explore live demos of Code Channels, end-to-end Slack-to-Salesforce automation (using Workflow Builder, Flow, Apex, and Block Kit), and stop by the live vibe coding station where you’ll prompt Vercel’s v0 agent to build a web app on the fly based on your real-time suggestions.</span></p>
<h2><b>Skill up with developer sessions</b></h2>
<p><span style="font-weight: 400">Developer sessions are your opportunity to learn directly from product experts, Salesforce Developer Advocates, and experts from the community building the Agentic Enterprise. These sessions cover technical deep dives, real-world implementations, and innovative solutions across the Headless 360 platform. Join us to sharpen your skills and deliver production-ready solutions at scale. </span></p>
<p><span style="font-weight: 400">To find developer-focused sessions in the </span><a href="https://reg.salesforce.com/flow/plus/df26/sessioncatalog/page/catalog?search.role=option_1625262065962"><span style="font-weight: 400">Dreamforce session catalog</span></a><span style="font-weight: 400">, select “Role” in the left navigation and then select “Developer”.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206857" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260819000621/Screenshot-2026-08-19-at-12.05.35-AM-e1787123196760.png?w=1000" class="postimages" width="1000" height="562" alt="Dreamforce 2026 session catalog with Developer role box checked." />
			  </span>
			</p>
<h3><span style="font-weight: 400">Agentforce and AI integration sessions</span></h3>
<p><span style="font-weight: 400">Master Agentforce Vibes, Agent Script, Agentforce Voice, and Mobile SDK Skills to build, test, and deploy trusted agents across any surface.</span></p>
<h4><span style="font-weight: 400">Develop Apps with Metadata Grounding MCP and Skills</span></h4>
<p><b>What to expect:</b><span style="font-weight: 400"> Learn how to use the Metadata Grounding MCP and the Salesforce Skills Library to ground AI coding agents. Build with Agentforce Vibes and Claude Code using prebuilt skills and trusted context.<br />
</span><b>Featured speakers:</b><span style="font-weight: 400"> Gonzalo Gambino, Sally ElGhoul<br />
</span><span style="font-weight: 400"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span><a href="https://reg.salesforce.com/flow/plus/df26/sessioncatalog/page/catalog/session/1779839331888001GGeX"><span style="font-weight: 400">Add this session to your agenda</span></a></p>
<h4><span style="font-weight: 400">Build Deterministic Agents with Agent Script</span></h4>
<p><b>What to expect:</b><span style="font-weight: 400"> Write reliable, testable, and deterministic agents using Agent Script in your IDE. Learn how to control agent behavior precisely, eliminate unpredictability, and ship with confidence.<br />
</span><b>Featured speakers:</b><span style="font-weight: 400"> Tulsi Patel, Ismaen Aboubakare, Kevin Wang<br />
</span><span style="font-weight: 400"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span><a href="https://reg.salesforce.com/flow/plus/df26/sessioncatalog/page/catalog/session/1780411427398001P4c6"><span style="font-weight: 400">Add this session to your agenda</span></a></p>
<h3><span style="font-weight: 400">Headless 360 sessions</span></h3>
<p><span style="font-weight: 400">Explore the Headless Experience Layer (HXL), Headless Data 360, and Hosted MCP Servers to bring intelligence into every surface and render rich interfaces anywhere.</span></p>
<h4><span style="font-weight: 400">Build Document AI Automation with Headless Data 360</span></h4>
<p><b>What to expect:</b><span style="font-weight: 400"> ​​Build end-to-end document automation with Agentforce Vibes and Document AI. Create extraction schemas and integrate with Flows, LWC, and Apex using headless patterns for document workflows.</span><span style="font-weight: 400"><br />
</span><b>Featured speakers:</b><span style="font-weight: 400"> Ananth Anto, Nishan Naseer</span><span style="font-weight: 400"><br />
</span><span style="font-weight: 400"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span><a href="https://reg.salesforce.com/flow/plus/df26/sessioncatalog/page/catalog/session/1779839378808001GCuu"><span style="font-weight: 400">Add this session to your agenda</span></a></p>
<h4><span style="font-weight: 400">Query Data 360 from Apex in Five Lines, Not 100</span></h4>
<p><b>What to expect:</b><span style="font-weight: 400"> Discover the Data 360 Apex query experience. Learn about synchronous and asynchronous SQL query patterns that replace complex Connect API integrations with minimal code and built-in test mocks.</span><span style="font-weight: 400"><br />
</span><b>Featured speakers:</b><span style="font-weight: 400"> Geoff Rothman, Manuel Then </span><span style="font-weight: 400"><br />
</span><span style="font-weight: 400"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span><a href="https://reg.salesforce.com/flow/plus/df26/sessioncatalog/page/catalog/session/1779839357312001GYnr"><span style="font-weight: 400">Add this session to your agenda</span></a></p>
<h3><span style="font-weight: 400">Roadmap sessions</span></h3>
<p><span style="font-weight: 400">Join Salesforce product leaders for exclusive insights into upcoming developer tools, MCP, Apex limits, and Agentforce 360 platform innovations.</span></p>
<h4><span style="font-weight: 400">Explore the Agentic App Dev Roadmap</span></h4>
<p><b>What to expect: </b><span style="font-weight: 400">Get an overview of the new agentic app dev and governance tools on the Headless 360 Platform. See how to plan, build, test, deploy, and observe using the coding agents of your choice.<br />
</span><b>Featured speakers:</b><span style="font-weight: 400"> Dan Fernandez, Karishma Lalwani<br />
</span><span style="font-weight: 400"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span><a href="https://reg.salesforce.com/flow/plus/df26/sessioncatalog/page/catalog/session/1780016746502001fCHz"><span style="font-weight: 400">Add this session to your agenda</span></a></p>
<h4><span style="font-weight: 400">Explore the Data 360 Roadmap for Developers</span></h4>
<p><b>What to expect:</b><span style="font-weight: 400"> Preview upcoming Data 360 capabilities, including Catalog APIs and Python Code Extension enhancements. Learn how these investments will impact your architecture and development strategy.<br />
</span><b>Featured speakers:</b><span style="font-weight: 400"> William Yeh, Rohit Dar<br />
</span><span style="font-weight: 400"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span><a href="https://reg.salesforce.com/flow/plus/df26/sessioncatalog/page/catalog/session/1779839330648001G0C8"><span style="font-weight: 400">Add this session to your agenda</span></a></p>
<h3><span style="font-weight: 400">More product sessions</span></h3>
<p><span style="font-weight: 400">Explore more technical deep dives, real-world implementations, and platform best practices curated to sharpen your developer skills.</span></p>
<h4><span style="font-weight: 400">Accelerate Mobile App Development with Skills</span></h4>
<p><b>What to expect:</b><span style="font-weight: 400"> Use prebuilt Salesforce Mobile SDK skills with any coding agent. Quickly add authentication, offline sync, push notifications, and camera access to your mobile apps.<br />
</span><b>Featured speaker:</b><span style="font-weight: 400"> Shalini Jain<br />
</span><span style="font-weight: 400"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span><a href="https://reg.salesforce.com/flow/plus/df26/sessioncatalog/page/catalog/session/1779865403729001c1no"><span style="font-weight: 400">Add this session to your agenda</span></a></p>
<h4><span style="font-weight: 400">Discover Apex Best Practices for Apps and Agents</span></h4>
<p><b>What to expect:</b><span style="font-weight: 400"> Explore asynchronous patterns, concurrency scaling, exception logging, trigger architecture, and other advanced Apex techniques for building production-ready agents and apps.<br />
</span><b>Featured speakers:</b><span style="font-weight: 400"> Daniel Ballinger, Szandor Knapp<br />
</span><span style="font-weight: 400"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span><a href="https://reg.salesforce.com/flow/plus/df26/sessioncatalog/page/catalog/session/1779759594263001KlWk"><span style="font-weight: 400">Add this session to your agenda</span></a></p>
<h2><b>More things to check out at Dreamforce 2026</b></h2>
<h3><span style="font-weight: 400">Explore opportunities for admins and architects</span></h3>
<p><span style="font-weight: 400">Looking to expand your perspective? Check out sessions on the </span><a href="https://reg.salesforce.com/flow/plus/df26/sessioncatalog/page/catalog?search.role=option_1625262044603"><span style="font-weight: 400">admin</span></a><span style="font-weight: 400"> and </span><a href="https://reg.salesforce.com/flow/plus/df26/sessioncatalog/page/catalog?search.role=option_1625262049014"><span style="font-weight: 400">architect</span></a><span style="font-weight: 400"> tracks to see how the Agentic Enterprise is being built, governed, and scaled in production. Explore the </span><a href="http://admin.salesforce.com/blog/2026/salesforce-admins-guide-to-dreamforce-2026"><span style="font-weight: 400">Admin</span></a><span style="font-weight: 400"> and </span><a href="https://www.salesforce.com/blog/salesforce-architect-guide-dreamforce-2026"><span style="font-weight: 400">Architect</span></a><span style="font-weight: 400"> Guides to Dreamforce 2026 for more can’t-miss experiences tailored to each role.</span></p>
<h3><span style="font-weight: 400">Grow your network at Community Cove</span></h3>
<p><span style="font-weight: 400">Community Cove is the destination for all Trailblazers to connect, learn, and celebrate 20 years of the Trailblazer Community. Catch career growth and thought leadership sessions in Trailblazer Theater, and dive into interest-based networking sessions. Be sure to design your custom Trailblazer card before you continue exploring everything else Dreamforce has to offer.</span></p>
<h3><span style="font-weight: 400">Get certified at Trailblazer Bootcamp</span></h3>
<p><span style="font-weight: 400">Go deeper at Dreamforce with Trailblazer Bootcamp. This is your opportunity to gain hands-on product expertise, elevate your skills, and build lasting connections with peers. It’s all happening from Saturday, September 12, to Monday, September 14, 2026. </span><a href="https://www.salesforce.com/dreamforce/training-and-certifications/"><span style="font-weight: 400">Learn more</span></a><span style="font-weight: 400"> about this pre-Dreamforce bootcamp and jumpstart your certification goals.</span></p>
<h3><span style="font-weight: 400">Experience Dreamfest at Oracle Park</span></h3>
<p><a href="https://reg.salesforce.com/flow/plus/df26/sessioncatalog/page/catalog/session/1786567772225001hg8P"><span style="font-weight: 400">Dreamfest</span></a><span style="font-weight: 400">, the ultimate Dreamforce celebration and Concert for Kids, will be on Wednesday, September 16, 2026 from 6:00 p.m. &#8211; 10:00 p.m. at Oracle Park to benefit </span><a href="https://www.linkedin.com/company/ucsfchildrens/"><span style="font-weight: 400">UCSF Benioff Children’s Hospitals</span></a><span style="font-weight: 400">. Dreamfest is included with your in-person Dreamforce registration. All you need to attend is your Dreamforce conference badge and a government-issued ID. Stay tuned for performance announcements.</span></p>
<h2><b>Quick Dreamforce tips <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4dd.png" alt="📝" class="wp-smiley" style="height: 1em; max-height: 1em;" /></b></h2>
<h3><span style="font-weight: 400">Watching from home? Join on Salesforce+</span></h3>
<p><span style="font-weight: 400">Can’t make it to Dreamforce in person? Select keynotes and sessions will be live-streamed on Salesforce+ during the entirety of the event. In addition to the live experience, a selection of on-demand episodes will be available for viewing once Dreamforce concludes.</span></p>
<p><a href="https://www.salesforce.com/plus"><span style="font-weight: 400">Register for Salesforce+</span></a><span style="font-weight: 400"> for free to get access to featured content.</span></p>
<h3><span style="font-weight: 400">Accessible Guide to Dreamforce 2026 <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/267f.png" alt="♿" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span></h3>
<p><span style="font-weight: 400">Explore what to expect throughout Dreamforce this year from a </span><a href="https://www.salesforce.com/dreamforce/accessibility/"><span style="font-weight: 400">first-person explanation</span></a><span style="font-weight: 400"> of the event, </span><span style="font-weight: 400">discover accessibility services and accommodations, and find resources to help you plan the experience that’s right for you.</span></p>
<h2><b>Your Dreamforce 2026 checklist <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></b></h2>
<p><span style="font-weight: 400">Dreamforce 2026 will be here before you know it. Take these steps now to prepare for the big event.</span></p>
<ul>
<li style="font-weight: 400"><a href="https://www.salesforce.com/dreamforce/register/?pr=https%3A%2F%2Fwww.salesforce.com%2Fdreamforce%2F&amp;d=701ed00000p9KZYAA2&amp;utm_content=701ed00000p9KZYAA2&amp;utm_source=google&amp;utm_medium=paid_search&amp;utm_campaign=23626787453&amp;utm_adgroup=194012597916&amp;utm_term=dreamforce+san+francisco&amp;utm_matchtype=p&amp;utm_variant=Control&amp;utm_agent_cohort=qualified"><span style="font-weight: 400">Register to attend Dreamforce</span></a><span style="font-weight: 400"> if you haven’t already. </span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Start building your perfect Dreamforce agenda now with </span><a href="https://reg.salesforce.com/flow/plus/df26/myagenda/page/myagenda"><span style="font-weight: 400">My Agenda</span></a><span style="font-weight: 400">. Refer to the sessions in this post to guide you. </span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Download the Salesforce Events app </span><span style="font-weight: 400">in the</span><a href="https://apps.apple.com/us/app/salesforce-events/id1021413071"> <span style="font-weight: 400">App Store</span></a><span style="font-weight: 400"> or</span><a href="https://play.google.com/store/search?q=salesforce%20events&amp;c=apps&amp;hl=en_US&amp;gl=US"> <span style="font-weight: 400">Google Play Store</span></a><span style="font-weight: 400"> to keep track of everything on your agenda in one easy-to-access place.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">If you’re not attending in person, be sure to </span><a href="https://www.salesforce.com/plus/experience/dreamforce_2026"><span style="font-weight: 400">register and watch on Salesforce+</span></a><span style="font-weight: 400">. </span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Follow</span><span style="font-weight: 400"> Salesforce Developers </span><span style="font-weight: 400">on</span><a href="https://x.com/SalesforceDevs"> <span style="font-weight: 400">X</span></a><span style="font-weight: 400"> and</span><a href="https://www.linkedin.com/showcase/salesforcedevs/"> <span style="font-weight: 400">LinkedIn</span></a><span style="font-weight: 400"> for more Dreamforce updates.</span></li>
</ul>
<h2><b>About the author</b></h2>
<p><b>Sarah Welker</b><span style="font-weight: 400"> is a Developer Marketing Manager at Salesforce. She balances her love for sustainable shopping and Sunday league soccer with a mission to visit every MLB ballpark, while maintaining her status as her kids&#8217; #1 fan on the sidelines. Find her on </span><a href="https://www.linkedin.com/in/sarahwelker47/"><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/08/developers-guide-dreamforce-2026">The Salesforce Developer’s Guide to Dreamforce 2026</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/08/developers-guide-dreamforce-2026/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206837</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260814100038/SF-TRLH-26-01-Dreamforce26-1000x563_Guide-Dev.png?w=1000" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260814100038/SF-TRLH-26-01-Dreamforce26-1000x563_Guide-Dev.png?w=1000" medium="image" />
	</item>
		<item>
		<title>Headless Development with Skills and a Claude Code Plugin</title>
		<link>https://developer.salesforce.com/blogs/2026/08/headless-development-with-skills-and-a-claude-code-plugin</link>
		<comments>https://developer.salesforce.com/blogs/2026/08/headless-development-with-skills-and-a-claude-code-plugin#respond</comments>
		<pubDate>Wed, 19 Aug 2026 03:00:05 +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[Developer Tooling]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[New Developments]]></category>
		<category><![CDATA[Agent Skills]]></category>
		<category><![CDATA[Apex]]></category>
		<category><![CDATA[Claude Code]]></category>
		<category><![CDATA[Model context protocol]]></category>
		<category><![CDATA[Salesforce CLI]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206808</guid>
		<description><![CDATA[<p>Discover how the Salesforce development plugin for Claude Code simplifies headless development by packaging skills, MCP servers, and developer tools into a single install.</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/08/headless-development-with-skills-and-a-claude-code-plugin">Headless Development with Skills and a Claude Code Plugin</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">Modern software development is increasingly decoupled from specific IDEs. Thanks to agentic technology and headless development, developers can now complete tasks using any IDE or even a CLI. This shift provides greater freedom of choice, as AI agents allow development workflows to function independently of traditional monolithic environments.</span></p>
<p><span style="font-weight: 400">In this post, we’ll present the key components of headless development and explore how Salesforce enables this approach at scale. We’ll also introduce a Claude Code plugin that streamlines the practice before sharing what’s on the roadmap.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206810" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260810083227/image5-e1786375962200.png?w=1000" class="postimages" width="1000" height="697" alt="Screenshot of the Salesforce development plugin for Claude Code]" />
			  </span>
			</p>
<h2><span style="font-weight: 400">The components of headless development</span></h2>
<p><span style="font-weight: 400">Headless development relies on a few main components: agent skills, MCP servers, and agent plugins.</span></p>
<h3><span style="font-weight: 400">Agent skills</span></h3>
<p><a href="https://agentskills.io/home"><u>Agent skills</u></a> are reusable, validated instructions that teach AI agents how to perform specific tasks. A skill is a folder that contains a <code>SKILL.md</code> markdown file. The file has a header with a set of standard attributes (<code>name</code><code> </code>and <code>description</code> at a minimum) followed by free-text instructions. Skills can also include subfolders and files such as templates or scripts.</p>
<p><span style="font-weight: 400">Thanks to a detailed </span><a href="https://agentskills.io/specification"><span style="font-weight: 400">specification</span></a><span style="font-weight: 400">, skills are interoperable across agents. Skills work with a lazy-loading mechanism: only skill names and descriptions are initially loaded in the agent context. When running a prompt, the agent determines which skills it needs to activate, and then loads them in context.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206811" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260810083324/image3_71e1e8-e1786376018640.png?w=1000" class="postimages" width="1000" height="564" alt="Diagram illustrating the components of a skill and their lazy loading." />
			  </span>
			</p>
<h3><span style="font-weight: 400">MCP servers</span></h3>
<p><span style="font-weight: 400">The </span><a href="https://modelcontextprotocol.io/docs/2026-07-28/getting-started/intro"><span style="font-weight: 400">Model Context Protocol</span></a><span style="font-weight: 400"> (MCP) is an open-source standard that provides a standardized way to connect AI applications to external systems. MCP helps by decoupling AI agents from API clients for those external systems. Agents embed a standard MCP client that can connect to any MCP server. Service providers ship MCP servers that interact with their systems’ APIs and expose MCP tools, prompts, and resources to agents. Thanks to this standard, connecting agents to external systems becomes plug and play just like using USB-C.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206812" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260810083413/image1_58263f-e1786376076590.png?w=1000" class="postimages" width="1000" height="527" alt="Diagram illustrating how MCP decouples agents from external services’ APIs." />
			  </span>
			</p>
<h3><span style="font-weight: 400">Agent plugins</span></h3>
<p><span style="font-weight: 400">Setting up a headless development environment requires that you retrieve skills and configure MCP servers. This can be time-consuming during initial setup and a bother to keep up to date. Agent plugins are precisely designed to address these pain points.</span></p>
<p><span style="font-weight: 400">Plugins package skills, MCP servers, and other utilities into a single installable unit for a specific AI platform. This simplifies setup and eases maintenance over time as there’s generally an update mechanism for plugins. A key limitation of plugins at the time of writing is that they remain AI vendor-specific, unlike skills and MCP servers, which are standard.</span></p>
<h2><span style="font-weight: 400">How Salesforce is scaling headless development</span></h2>
<h3><span style="font-weight: 400">Salesforce skills are evolving</span></h3>
<p><span style="font-weight: 400">Salesforce ships a collection of over a hundred skills for development across its clouds and products in the open-source </span><a href="https://github.com/forcedotcom/sf-skills"><span style="font-weight: 400">Salesforce skills library (sf-skills)</span></a><span style="font-weight: 400"> GitHub repository.</span></p>
<p><span style="font-weight: 400">Each skill focuses on a narrow capability such as generating Apex classes, running Data 360 queries, designing mobile apps, generating OmniScript, and more. Each skill includes context about the platform, best practices, and error handling.</span></p>
<p><span style="font-weight: 400">The Salesforce skills library comes pre-installed in </span><a href="https://developer.salesforce.com/docs/platform/agentforcevibes/guide/afv-overview.html"><span style="font-weight: 400">Agentforce Vibes</span></a><span style="font-weight: 400">. You can install some or all of its skills in the agentic environment of your choice (for example, OpenCode, Claude Code, Codex, or Cursor) by running this interactive command (requires Node.js):</span></p>
<pre language="shell">npx skills add forcedotcom/sf-skills
</pre>
<p><span style="font-weight: 400">With Salesforce driving headless development across products, the number of available skills has skyrocketed since the launch of the skills library. And, with multiple teams contributing, it became clear that strict governance is needed to manage skills at scale to ensure </span><b>discoverability</b><span style="font-weight: 400"> and </span><b>distribution</b><span style="font-weight: 400">.</span></p>
<h4><span style="font-weight: 400">Improved discoverability</span></h4>
<p><span style="font-weight: 400">Developers and agents can&#8217;t predict skill names (should a skill be named “generate-X”, “build-X”, or “create-X”?). The problem becomes ever more visible as coverage for multiple products and features is added to the mix. Without a structured and defined taxonomy, skills fall out of step with how Salesforce officially names and groups features. This leads to developer frustration and agents that can’t execute tasks effectively or consistently.</span></p>
<p>To prevent this, skills have been renamed in accordance with a well-defined taxonomy. For example, the <code>dx-devops-test-failures-analyze</code> skill belongs to the following classification path: DX &gt; DevOps &gt; Test &gt; Failures Analyze.</p>
<p><span style="font-weight: 400">To prevent context dilution and structural drift as multiple teams and individuals contribute to the library over time, an automated, gated verification pipeline ensures skills are checked for taxonomy alignment, accuracy, and expected outcomes before they are cleared for distribution.</span></p>
<h4><span style="font-weight: 400">Robust distribution</span></h4>
<p><span style="font-weight: 400">In initial releases of the skills library, skills were not individually versioned (only the library was versioned) and dependencies weren’t expressed in a standardized manner. As skill instructions and dependencies were updated, these changes could occasionally introduce undocumented behavior changes in dev workflows.</span></p>
<p>To provide more visibility and control over skills, we’ve used skill metadata to define individual skill versions and dependencies. For example, below is the header of the <a href="https://github.com/forcedotcom/sf-skills/blob/main/skills/dx-org-manage/SKILL.md"><u><code>dx-org-manage</code><span> skill</span></u></a><span>. Note the metadata section that includes the skill version, minimum required Salesforce API version, related skills, and dependencies.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206813" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260810083507/image2_c80791-e1786376120426.png?w=1000" class="postimages" width="1000" height="458" alt="Screenshot of the header of the dx-org-manage skill featuring the skill version and its dependencies in the metadata section" />
			  </span>
			</p>
<h3><span style="font-weight: 400">Introducing the Salesforce development plugin for Claude Code</span></h3>
<p><span style="font-weight: 400">The </span><b>Salesforce development plugin</b><span style="font-weight: 400"> is our first official plugin, built for </span><a href="https://claude.ai/code"><span style="font-weight: 400">Claude Code</span></a><span style="font-weight: 400">, Anthropic&#8217;s AI-powered command-line development tool. This plugin transforms Claude from a general-purpose coding assistant into a Salesforce development expert.</span></p>
<p><span style="font-weight: 400">Here are the details of what&#8217;s included in the Salesforce development plugin for Claude Code: a collection of Salesforce development skills, MCP servers, specialized agents, hooks, and commands.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206814" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260810083553/image4_513bc1-e1786376179779.png?w=1000" class="postimages" width="1000" height="625" alt="Diagram showing an overview of the features of the Salesforce development plugin for Claude Code and how they integrate with Salesforce." />
			  </span>
			</p>
<h4><span style="font-weight: 400">Salesforce development skills</span></h4>
<p><span style="font-weight: 400">The plugin bundles a subset of about 40 skills from the Salesforce skills library. This collection of skills covers core Salesforce development. Skills for other clouds and features (including Data 360, Commerce, and mobile development) are not included in this plugin. We plan to collect feedback on this initial plugin before shipping dedicated plugins for these domains.</span></p>
<h4><span style="font-weight: 400">Specialized agents</span></h4>
<p><span style="font-weight: 400">The plugin includes specialized Claude agents that automatically activate based on context:</span></p>
<ul>
<li style="font-weight: 400"><b>salesforce-dev</b><span style="font-weight: 400">: The primary development agent that auto-detects Salesforce projects and routes requests through </span><a href="https://github.com/forcedotcom/sf-skills"><span style="font-weight: 400">skills</span></a><span style="font-weight: 400"> → </span><a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_intro.htm"><span style="font-weight: 400">Salesforce CLI</span></a><span style="font-weight: 400"> → </span><a href="https://developer.salesforce.com/docs/apis#browse"><span style="font-weight: 400">Salesforce APIs</span></a><span style="font-weight: 400"> in that priority order.</span></li>
<li style="font-weight: 400"><b>architecture-review</b><span style="font-weight: 400">: A read-only agent that grades your project against the </span><a href="https://architect.salesforce.com/docs/architect/well-architected/guide/overview.html"><span style="font-weight: 400">Well-Architected pillars</span></a><span style="font-weight: 400"> (Trusted, Easy, Adaptable) and provides a governance checklist.</span></li>
<li style="font-weight: 400"><b>Agentforce Development Lifecycle (ADLC) agents</b><span style="font-weight: 400">: A set of specialized agents for authoring, engineering, and testing Agentforce agents.</span></li>
</ul>
<h4><span style="font-weight: 400">Salesforce MCP servers</span></h4>
<p><span style="font-weight: 400">The plugin exposes three MCP servers that provide Claude with deep platform integration without requiring that you configure them manually one by one:</span></p>
<ul>
<li style="font-weight: 400"><b>salesforce-api-context</b><span style="font-weight: 400">: Offers API and metadata guidance.</span></li>
<li style="font-weight: 400"><b>salesforce-metadata-experts</b><span style="font-weight: 400">: Provides expert knowledge about Salesforce metadata types.</span></li>
<li style="font-weight: 400"><b>salesforce-lsp</b><span style="font-weight: 400">: Hosts local Apex and SOQL language servers, exposing semantic capabilities (diagnostics, completions, and code actions) as MCP tools. This means that Claude can perform real-time Apex syntax validation, suggest code fixes, and provide intelligent completions just like the </span><a href="https://developer.salesforce.com/docs/platform/sfvscode-extensions/overview"><span style="font-weight: 400">Salesforce Extensions for VS Code</span></a><span style="font-weight: 400">, but from the terminal.</span></li>
</ul>
<h4><span style="font-weight: 400">Hooks</span></h4>
<p><span style="font-weight: 400">The plugin ships with custom Claude Code hooks. A hook is a shell command that automatically runs in response to specific events, like before/after tool calls or when certain actions occur. They let you extend Claude Code&#8217;s behavior without changing the core tool.</span></p>
<p><span style="font-weight: 400">Here are some examples of hooks that ship with the plugin:</span></p>
<ul>
<li style="font-weight: 400"><b>Automated context discovery</b><span style="font-weight: 400">: When Claude Code starts or changes directories, a hook runs to detect whether the folder is a Salesforce DX project and, if so, loads information such as the default org.</span></li>
<li style="font-weight: 400"><b>Agent Script syntax validation</b><span style="font-weight: 400">: When a <code>.agent</code> file is edited, a hook runs an Agent Script syntax validation command.</span></li>
<li style="font-weight: 400"><b>Deployment validation</b><span style="font-weight: 400">: When a metadata deployment command runs, a hook validates the deployment result and analyzes potential errors.</span></li>
</ul>
<h4><span style="font-weight: 400">Commands</span></h4>
<p><span style="font-weight: 400">The plugin ships with a set of convenient commands that let you run operations from the Claude Code interface such as:</span></p>
<ul>
<li><b>A </b><b><code>/setup</code></b><b> command</b> for validating the state of the plugin and the org.</li>
<li><b>A </b><b><code>/discovery</code></b><b> command</b> for exploring available skills.</li>
<li><b>A set of utility commands</b> that act as shortcuts for common CLI commands such as getting the status of the default org (<code>/org</code>), logging into an org (<code>/login</code>), or logging out of an org (<code>/logout</code>). These are convenient as you can’t directly run Salesforce CLI commands from within the Claude Code interface and calling the related MCP tools for simple tasks like these is overkill.</li>
</ul>
<h3><span style="font-weight: 400">Getting started with the Salesforce development plugin</span></h3>
<p><span style="font-weight: 400">Setting up the plugin is straightforward:</span></p>
<ol>
<li style="font-weight: 400"><span style="font-weight: 400">Install the prerequisites:</span>
<ul>
<li><a href="https://claude.ai/code"><u>Claude Code</u></a></li>
<li><a href="https://nodejs.org"><u>Node.js</u></a> LTS (v22 or v24 at time of writing)</li>
<li><a href="https://developer.salesforce.com/tools/salesforcecli"><u>Salesforce CLI</u></a></li>
<li><a href="https://www.python.org/downloads/"><u>Python 3.8 or above</u></a>. This is only required for some internal hooks related to org detection and deployment safety. The Python requirement may go away in future versions. Check the <a href="https://github.com/forcedotcom/sf-skills/tree/main/plugins/builder/salesforce-development#quick-start"><u>official setup instructions</u></a> for the latest information.</li>
</ul>
</li>
<li style="font-weight: 400"><span style="font-weight: 400"><span style="font-weight: 400">Open any Salesforce DX project and authenticate to an org with the Salesforce CLI:<br />
</span></span></p>
<pre language="shell">sf org login web --alias my-org --set-default
</pre>
</li>
<li style="font-weight: 400"><span style="font-weight: 400"><span style="font-weight: 400">In Claude Code, add the Salesforce Claude Plugin Marketplace and install the plugin:<br />
</span></span></p>
<pre language="text">/plugin marketplace add forcedotcom/sf-skills
/plugin install salesforce-development@salesforce
</pre>
</li>
<li style="font-weight: 400"><span style="font-weight: 400"><span style="font-weight: 400">Validate your environment in Claude Code (optional but recommended):<br />
</span></span></p>
<pre language="text">/salesforce-development:setup
</pre>
</li>
</ol>
<p>That&#8217;s it. Claude will automatically detect your org context from your project and activate the <code>salesforce-dev</code> agent. You can now use natural language prompts like:</p>
<ul>
<li>&#8220;Create an Apex service class to handle Account territory assignments&#8221;</li>
<li>&#8220;Generate a <code>Project__c</code> custom object with fields for Status, Due Date, and Priority&#8221;</li>
<li>&#8220;Deploy the project to my org&#8221;</li>
<li>&#8220;Write a test class for <code>AccountTerritoryService</code> and run it&#8221;</li>
</ul>
<h2><span style="font-weight: 400">What&#8217;s next</span></h2>
<p><span style="font-weight: 400">We&#8217;re expanding development plugins across the AI agent ecosystem. Upcoming work (subject to change) includes:</span></p>
<ul>
<li style="font-weight: 400"><b>Claude Cowork plugin</b><span style="font-weight: 400">: Bringing skills to Anthropic&#8217;s collaborative agentic workspace</span></li>
<li style="font-weight: 400"><b>Open-source plugin architecture</b><span style="font-weight: 400">: Community-contributed plugins for domain-specific use cases (Agentforce Service, Agentforce Sales, Agentforce Commerce)</span></li>
<li style="font-weight: 400"><b>Coding Agent Platform Governance (CAP-G)</b><span style="font-weight: 400">: Integration with governance tools for session tracking, policy enforcement, and compliance reporting</span></li>
</ul>
<p><span style="font-weight: 400">Expanding development plugins is the first step in shipping plugins for broader use cases. We are considering options and frameworks to ship </span><b>plugins for knowledge workers</b><span style="font-weight: 400">. For instance, you could see an Agentforce 360 for Automotive plugin with a set of business skills, custom, hosted MCP servers preconfigured with access to business processes, and more.</span></p>
<h2><span style="font-weight: 400">Conclusion</span></h2>
<p><span style="font-weight: 400">This concludes our tour of how Salesforce is scaling headless development from expanding skills and MCP servers to the adoption of plugins. You learned about governance applied to skills, the launch of our first Salesforce development plugin for Claude Code, and our plans for additional plugins.</span></p>
<p><span style="font-weight: 400">Try the Salesforce development plugin today and remember that Salesforce skills and plugins are open-source initiatives. You can participate by exploring the skills and plugins repository and sharing your feedback on GitHub.</span></p>
<h2><span style="font-weight: 400">Resources</span></h2>
<ul>
<li style="font-weight: 400"><a href="https://sfdc.co/sf-claude"><span style="font-weight: 400">Plugin homepage</span></a></li>
<li style="font-weight: 400"><a href="https://github.com/forcedotcom/sf-skills"><span style="font-weight: 400">Salesforce skills library repository</span></a></li>
<li style="font-weight: 400"><a href="https://code.claude.com/docs"><span style="font-weight: 400">Claude Code documentation</span></a></li>
<li style="font-weight: 400"><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"><a href="https://code.claude.com/docs/en/plugins"><span style="font-weight: 400">Plugin development guide</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>
<ul></ul>
<ol></ol>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/08/headless-development-with-skills-and-a-claude-code-plugin">Headless Development with Skills and a Claude Code Plugin</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/08/headless-development-with-skills-and-a-claude-code-plugin/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206808</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260810084536/SingleHeadshot-8-e1786376751346.png?w=1000" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260810084536/SingleHeadshot-8-e1786376751346.png?w=1000" medium="image" />
	</item>
		<item>
		<title>Migrate From Managed Package Runtime to the Omnistudio Standard Runtime</title>
		<link>https://developer.salesforce.com/blogs/2026/08/migrate-from-managed-package-runtime-to-the-omnistudio-standard-runtime</link>
		<comments>https://developer.salesforce.com/blogs/2026/08/migrate-from-managed-package-runtime-to-the-omnistudio-standard-runtime#respond</comments>
		<pubDate>Fri, 14 Aug 2026 15:00:31 +0000</pubDate>
		<dc:creator><![CDATA[Sarah Welker]]></dc:creator>
				<category><![CDATA[App Development]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Developer Tooling]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Data Model Migration]]></category>
		<category><![CDATA[Flexcards]]></category>
		<category><![CDATA[Integration Procedures]]></category>
		<category><![CDATA[Managed Packages]]></category>
		<category><![CDATA[Omnistudio]]></category>
		<category><![CDATA[OmniStudio Migration Assistant]]></category>
		<category><![CDATA[Salesforce CLI]]></category>
		<category><![CDATA[Standard Runtime]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206835</guid>
		<description><![CDATA[<p>Learn how the Omnistudio Migration Assistant (OMA) automates the migration of your Omnistudio components, reduces manual effort, and helps you transition to the standard runtime.</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/08/migrate-from-managed-package-runtime-to-the-omnistudio-standard-runtime">Migrate From Managed Package Runtime to the Omnistudio Standard Runtime</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">Upgrading a tech stack is rarely anyone&#8217;s favorite project, especially when it involves tedious, manual work. Previously, migrating your Omnistudio components from a managed package runtime to the Omnistudio standard runtime meant facing a mountain of manual steps. It was notoriously time-consuming, frustrating, and error-prone.</span></p>
<p><span style="font-weight: 400">Nevertheless, the Omnistudio standard runtime is the future, offering new innovations and faster performance. Whether you&#8217;re migrating from a Vlocity Industries managed package or the Omnistudio Foundation package, the standard runtime removes the need for managed package installations. And now you can simplify this process. The </span><a href="https://www.npmjs.com/package/@salesforce/plugin-omnistudio-migration-tool?activeTab=versions"><span style="font-weight: 400">Omnistudio Migration Assistant (OMA)</span></a><span style="font-weight: 400"> tool is specifically designed to automate the heavy lifting, making your move to the standard runtime fast and simple.</span></p>
<p><span style="font-weight: 400">Note: Package uninstallation is not recommended as existing org workflows and custom components may still rely on package schema or underlying metadata.</span></p>
<h2><span style="font-weight: 400">Omnistudio evolution: From managed packages to the standard runtime </span></h2>
<p><span style="font-weight: 400">Before we dive into the &#8220;how,&#8221; let’s review a brief history of where Omnistudio started, where it&#8217;s going, and where you might fit in:</span></p>
<p><b>Before the acquisition:</b><span style="font-weight: 400"> Initially, customers were dependent on Vlocity Industries managed packages, such as </span><a href="https://www.salesforce.com/communications/cloud/"><span style="font-weight: 400">Communications</span></a><span style="font-weight: 400">, </span><a href="https://www.salesforce.com/media/cloud/"><span style="font-weight: 400">Media</span></a><span style="font-weight: 400">, and </span><a href="https://www.salesforce.com/energy-utilities/cloud/"><span style="font-weight: 400">Energy</span></a><span style="font-weight: 400"> (CME), </span><a href="https://www.salesforce.com/financial-services/digital-insurance-software/"><span style="font-weight: 400">Insurance</span></a><span style="font-weight: 400">, and </span><a href="https://www.salesforce.com/government/solutions/"><span style="font-weight: 400">Public Sector</span></a><span style="font-weight: 400">, to use Omnistudio components on the Vlocity Industries managed package runtime.</span></p>
<p><b>After the acquisition: </b><span style="font-weight: 400">Following the acquisition, these Vlocity Industries managed packages remained, but the Omnistudio Foundation package was created for customers using solutions like </span><a href="https://www.salesforce.com/financial-services/cloud/"><span style="font-weight: 400">Financial Services Cloud (now Agentforce Financial Services)</span></a><span style="font-weight: 400"> or </span><a href="https://www.salesforce.com/healthcare/cloud/"><span style="font-weight: 400">Health Cloud (now Agentforce Health)</span></a><span style="font-weight: 400">. Now, some customers are on the managed package runtimes and some are on the standard runtime.</span></p>
<p><b>The future:</b><span style="font-weight: 400"> Our goal is to bid goodbye to the managed packages and their runtimes and move toward a package-free Omnistudio experience by transitioning all customers to the Omnistudio standard runtime.</span></p>
<h2><span style="font-weight: 400">Benefits of migrating to the standard runtime</span></h2>
<p><span style="font-weight: 400">Here are the benefits of making the switch to the </span><a href="https://www.salesforce.com/industries/omnistudio/omnistudio-on-core-guide/"><span style="font-weight: 400">Omnistudio standard runtime</span></a><span style="font-weight: 400">:</span></p>
<h3><span style="font-weight: 400">Massive performance gains</span></h3>
<p><span style="font-weight: 400">Who doesn&#8217;t want a faster system? Moving to the Omnistudio standard runtime delivers incredible runtime performance gains for your end-users on the Salesforce platform. Depending on your configuration, your runtime architecture will execute 2x to 5x faster, with Flexcards delivering up to 5x better performance, Integration Procedures processing data up to 4x faster, Data Mappers providing up to 3x faster data mapping and transformation, and Omniscripts delivering up to 2x faster interactive guided experiences.</span></p>
<p><i><span style="font-weight: 400">Note: All data presented above is derived from internal testing, which showed that execution averaged 2112 ms on the standard runtime versus 5061 ms on a managed package runtime.</span></i></p>
<h3><span style="font-weight: 400">Zero functionality loss</span></h3>
<p><span style="font-weight: 400">The standard runtime completely supports all critical business functions, providing a faster experience with no compromise on capability.</span></p>
<h3><span style="font-weight: 400">Access to the latest innovations</span></h3>
<p><span style="font-weight: 400">Business logic and components can transition directly to the standard runtime, which offers a more native experience within the Salesforce platform, reducing the overhead typically associated with managed packages.</span></p>
<p><span style="font-weight: 400">Staying on a managed package runtime means you risk missing out on the new product innovations, including </span><a href="https://help.salesforce.com/s/articleView?id=release-notes.rn_omnistudio_configure_integration_procedure_on_agentforce.htm&amp;release=256&amp;type=5"><span style="font-weight: 400">Agentforce integration for your Integration Procedures</span></a><span style="font-weight: 400">, design assistance, and </span><a href="https://www.learnexperiencecloud.com/topic/a081U00000OhIqgQAF/lightning-web-runtime-lwr"><span style="font-weight: 400">Lightning Web Runtime (LWR)</span></a><span style="font-weight: 400"> support for your </span><a href="https://www.learnexperiencecloud.com/"><span style="font-weight: 400">Experience Cloud</span></a><span style="font-weight: 400"> implementations.</span></p>
<h3><span style="font-weight: 400">Simplified deployment</span></h3>
<p><a href="https://developer.salesforce.com/blogs/2026/01/create-faster-lighter-experience-cloud-sites-with-omnistudio-components-and-lwr"><span style="font-weight: 400">Deploying changes</span></a><span style="font-weight: 400"> is significantly easier. Standardized Salesforce CLI-based deployments replace the older, complex Vlocity build tools. This reduces the time and complexity of your deployments, ensuring that future patches, bug fixes, and upgrades are smooth.</span></p>
<h2><span style="font-weight: 400">Find your transition path</span></h2>
<p><span style="font-weight: 400">Every business has a slightly different setup. Use the following table to identify the transition path for your specific setup:</span></p>
<table>
<tbody>
<tr>
<td><span style="font-weight: 400">Customer Segment</span></td>
<td><span style="font-weight: 400">Current Setup</span></td>
<td><span style="font-weight: 400">Transition Path</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">Vlocity Industries managed packages (CME, Insurance, and so on)</span></td>
<td><span style="font-weight: 400">Custom data model pointing to the managed package runtime.</span></td>
<td><span style="font-weight: 400">Migration required. Use the Omnistudio Migration Assistant (OMA) tool to move to the standard runtime.</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">Omnistudio Foundation packages (Financial Services Cloud, Health Cloud, and so on)</span></td>
<td><span style="font-weight: 400">Standard data model pointing to the managed package runtime.</span></td>
<td><span style="font-weight: 400">Migration required. Use the OMA tool to move to the standard runtime.</span></td>
</tr>
<tr>
<td><span style="font-weight: 400">Customers on the standard runtime</span></td>
<td><span style="font-weight: 400">Already using the standard runtime.</span></td>
<td><span style="font-weight: 400">No action needed. The OMA tool is not required.</span></td>
</tr>
</tbody>
</table>
<p><span style="font-weight: 400">Note: Beginning with Summer ’25, Omnistudio is package-free for new customers. Designers and runtime are available natively with supported cloud licenses.</span></p>
<h2><span style="font-weight: 400">Managed package runtime versus standard runtime</span></h2>
<p><span style="font-weight: 400">Let’s briefly review </span><a href="https://help.salesforce.com/s/articleView?id=xcloud.os_differences_between_omnistudio_and_omnistudio_for_vlocity.htm&amp;type=5"><span style="font-weight: 400">the core differences between the managed package runtime and the standard runtime</span></a><span style="font-weight: 400">. The runtime describes the look and feel of your configured Omnistudio components:</span></p>
<ul>
<li style="font-weight: 400"><b>Managed package runtime: </b><span style="font-weight: 400">This legacy environment is highly flexible but relies on an older architecture. It supports both the custom data model (which uses custom objects provided by Industries managed packages) and the standard data model.</span></li>
<li style="font-weight: 400"><b>Standard runtime:</b><span style="font-weight: 400"> This is the native, modernized environment on the Salesforce platform. It operates strictly on the standard data model (using standard Salesforce objects) and does not support custom objects from the legacy managed packages.</span></li>
</ul>
<h2><span style="font-weight: 400">What is the Omnistudio Migration Assistant (OMA)?</span></h2>
<p><span style="font-weight: 400">The </span><a href="https://help.salesforce.com/s/articleView?id=xcloud.os_migrate_install_oma.htm&amp;type=5"><span style="font-weight: 400">OMA</span></a><span style="font-weight: 400"> is a handy Salesforce </span><a href="https://developer.salesforce.com/tools/salesforcecli"><span style="font-weight: 400">command-line interface (CLI)</span></a><span style="font-weight: 400"> plugin built specifically to help you automatically move your Omnistudio components from a custom data model (industry-specific or package-based data structures, such as those from managed packages, where objects and relationships are predefined within the package) to the standard data model (the native Salesforce data structure, using standard objects and custom objects built directly on the platform). It takes the components you’ve already built, such as Flexcards, Omniscripts, Data Mappers, and Integration Procedures, and smoothly shifts them to the standard runtime.</span></p>
<table>
<tbody>
<tr>
<td><b>Custom Data Model </b></td>
<td><b>Standard Data Model </b></td>
</tr>
<tr>
<td><span><br />
<code>OmniScript__c</code>, <code>Element__c</code></span></td>
<td><span><br />
<code>OmniProcess</code>, <code>OmniProcessElement</code></span></td>
</tr>
<tr>
<td><span><br />
<code>OmniScriptDefinition__c</code></span></td>
<td><span><br />
<code>OmniProcessCompilation</code></span></td>
</tr>
<tr>
<td><span><br />
<code>OmniScriptInstance__c</code></span></td>
<td><span><br />
<code>OmniScriptSavedSession</code></span></td>
</tr>
<tr>
<td><span><br />
<code>DRBundle__c</code> / <code>DRMapItem__c</code></span></td>
<td><span><br />
<code>OmniDataTransform</code></span></td>
</tr>
<tr>
<td><span><br />
<code>VlocityCard__c</code> / <code>GeneralSettings__c</code></span></td>
<td><span><br />
<code>OmniUiCard</code> / <code>OmniInteractionConfig</code></span></td>
</tr>
</tbody>
</table>
<p><span style="font-weight: 400">No one wants to manually update hundreds of components piece by piece. Luckily, the OMA tool automates most of the migration effort. It handles the tedious, repetitive tasks for you, such as automatically updating namespace references and managing complex dependencies. This enables a much faster migration process and significantly reduces the chance of human error.</span></p>
<p><span style="font-weight: 400">Using the OMA tool can reduce your team&#8217;s manual efforts in migration by 95%. While it handles much of the migration, a few unique items (such as rebuilding older Angular-based components or mapping industry-specific objects) will still need manual attention.</span></p>
<h2><span style="font-weight: 400">How the migration process works</span></h2>
<p><span style="font-weight: 400">Migrating your entire system might sound like a massive undertaking, but the process is highly structured and controlled. To make the transition as smooth as possible, let’s understand it in three manageable phases: development, testing, and production.</span></p>
<p><span style="font-weight: 400">First things first. Before jumping into the first phase, install the plugin. Open your terminal and install the recommended OMA plugin version: <code>sf plugins install @salesforce/plugin-omnistudio-migration-tool@2.0.0-rc.57</code></span></p>
<p><span style="font-weight: 400">Next, assess exactly where you currently stand and plan how you will migrate. You should never run a migration directly on your live system. Instead, start by creating and refreshing a sandbox from your production org to provide a safe environment for the migration. In this environment, you will set up your detailed test flows and outline all of your critical business workflows to prepare for the move.</span></p>
<p><b>Note: </b><span style="font-weight: 400">Upgrade to the Vlocity Industries managed package version Winter ’26 or later before starting the migration process, regardless of your transition path.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206841" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260813154238/image3_03016d.png?w=800" class="postimages" width="800" height="621" alt="A flow diagram outlining the three-phase Omnistudio migration process across sandbox and production environments." />
			  </span>
			</p>
<h3><span style="font-weight: 400">Phase 1: Development (with Assess and Migrate modes)</span></h3>
<p><span style="font-weight: 400">This is the phase where the OMA really gets to work. It has four steps.</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206842" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260813154319/image1_74cedc-e1786661015156.png?w=1000" class="postimages" width="1000" height="558" alt="The four steps of the development phase of migration." />
			  </span>
			</p>
<ol>
<li style="font-weight: 400"><b>Run your baseline tests: </b><span style="font-weight: 400">Before you even touch the OMA tool, you should run your full automation suite, including sanity checks, business workflows, smoke tests, and regressions, and carefully record the results. This gives you a reliable baseline to compare against later.</span></li>
<li style="font-weight: 400"><b>Run Assess mode:</b><span style="font-weight: 400"> Next, run the OMA tool in Assess mode. It generates a highly detailed report of your Omnistudio configuration, flagging exactly what needs your attention, such as namespace issues or older Angular-based components. Analyze your components for potential migration blockers without modifying any data. Use the </span><span style="font-weight: 400">-a</span><span style="font-weight: 400"> flag to assess all component versions: <code>sf omnistudio:migration:assess -u dev_sandbox_username@domain.com -a</code></span><span style="font-weight: 400"><span style="font-weight: 400"><br />
</span></span><b>Tip:</b><span style="font-weight: 400"> You can isolate the analysis by appending </span><span style="font-weight: 400">&#8211;only=dm,ip</span><span style="font-weight: 400"> to target specific components.<br />
</span><span style="font-weight: 400">
			  <span class="postimagessection_specify alignnone size-medium wp-image-206843" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260813154414/image4_ee9b64-e1786661067742.png?w=1000" class="postimages" width="1000" height="586" alt="A dashboard displaying successful migration metrics for standard Omnistudio components." />
			  </span>
			</span></li>
<li style="font-weight: 400"><b>Fix issues:</b><span style="font-weight: 400"> Now it is time for a little manual intervention. Your team will manually fix the specific issues identified in the assessment report. Once fixed, simply rerun Assess mode until the report comes back completely &#8220;green&#8221; and error-free.</span></li>
<li style="font-weight: 400"><b>Run Migrate mode: </b><span style="font-weight: 400">With a green light, you can now run the tool in Migrate mode to actually move your components over to the standard runtime. What gets moved depends on your current setup: if your Omnistudio Metadata setting is enabled, the tool will only migrate your package dependencies. If your setting is disabled, the tool will migrate both your Omnistudio assets and the package dependencies. Once your assessment report is green, use the following command to execute the actual metadata migration: <code>sf omnistudio:migration:migrate -u dev_sandbox_username@domain.com -a</code></span>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206844" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260813154631/image2_afeb4a-e1786661208417.png?w=1000" class="postimages" width="1000" height="522" alt="A dashboard displaying successful migration metrics for standard Omnistudio components." />
			  </span>
			</li>
</ol>
<h3><span style="font-weight: 400">Phase 2: Validation</span></h3>
<p><span style="font-weight: 400">This phase is all about testing. Once the migration steps are complete in your development sandbox, you&#8217;ll deploy those freshly migrated components over to a new, clean test sandbox. In this environment, you need to perform thorough regression testing, running all of the automation test suites you recorded back in Phase 1. This ensures that every single business flow works flawlessly before your users ever see the changes.</span></p>
<h3><span style="font-weight: 400">Phase 3: Production </span></h3>
<p><span style="font-weight: 400">You’ve made it to the finish line! After your sandbox and test-environment validations are complete, it&#8217;s time to deploy those tested changes into your production environment. Once deployed, you&#8217;ll perform a few final readiness checks, like assigning the proper permission sets to your users, and perform post-deployment validation. Congratulations, you&#8217;re now officially running on the Omnistudio standard runtime!</span></p>
<h2><span style="font-weight: 400">Scenario-specific migration process variations</span></h2>
<p><span style="font-weight: 400">The three-phase migration process described above applies across scenarios, but some steps differ depending on your current managed package and data model configuration. </span></p>
<p><span style="font-weight: 400">For customers using Vlocity Industries managed packages with the standard data model, the process looks like:</span></p>
<ul>
<li style="font-weight: 400"><b>Development phase: </b><span style="font-weight: 400">After upgrading your sandboxes to the latest release and migrating any older calculation logic to the Business Rules Engine (BRE), run the OMA tool in Assess mode. Then, after you have manually resolved any flagged issues, run the tool in Migrate mode to convert your components. Finally, turn off the &#8220;Managed Package Runtime&#8221; and &#8220;Managed Package Designer&#8221; settings.</span></li>
<li style="font-weight: 400"><b>Validation phase: </b><span style="font-weight: 400">Here&#8217;s the key difference in the validation phase: you only run the OMA tool to move your Omni Global Auto Numbers. For everything else (like Flexcards and Omniscripts), you&#8217;ll manually switch your settings to the standard runtime and use standard deployment tools (like VS Code) to push the migrated components over from your development sandbox. Test everything thoroughly.</span></li>
<li style="font-weight: 400"><b>Production phase: </b><span style="font-weight: 400">Prepare your production org by </span><a href="https://help.salesforce.com/s/articleView?id=xcloud.os_enable_omnistudio_metadata_api_support.htm&amp;type=5"><span style="font-weight: 400">enabling Omnistudio Metadata API support</span></a><span style="font-weight: 400">. Just like in the Validation phase, you only run the OMA tool to migrate your Global Auto Numbers. Then, deploy your fully tested components from the test sandbox, switch off the &#8220;Managed Package Runtime&#8221; and &#8220;Managed Package Designer&#8221; settings, and validate your live workflows.</span></li>
</ul>
<p><span style="font-weight: 400">For customers using the Omnistudio Foundation package with the standard data model, the migration is a bit more streamlined.</span></p>
<ul>
<li style="font-weight: 400"><b>Development phase: </b><span style="font-weight: 400">Start by upgrading your Foundation package and moving calculation logic to the BRE. Run OMA in Assess mode, fix any flagged issues manually, and run it again in Migrate mode. The tool will automatically update references and strip away package dependencies for you.</span></li>
<li style="font-weight: 400"><b>Validation phase: </b><span style="font-weight: 400">There&#8217;s a notable difference here: Omni Global Auto Numbers aren&#8217;t supported in this use case because they don&#8217;t exist in the Omnistudio namespace. Because of this, you don&#8217;t run the OMA tool at all in this phase. Simply switch your sandbox settings to the standard runtime and use standard deployment tools (like VS Code) to bring your migrated components over from the development sandbox. Run your full suite of regression tests.</span></li>
<li style="font-weight: 400"><b>Production phase:</b><span style="font-weight: 400"> In your production org, enable Omnistudio Metadata API support. Switch your settings to the standard runtime, deploy your successfully tested components from the test sandbox, validate your workflows, and you&#8217;re officially live on the standard runtime.</span></li>
</ul>
<h2><span style="font-weight: 400">Migrate to all-new Omnistudio today</span></h2>
<p><span style="font-weight: 400">Migrating your Omnistudio components from the managed package runtime to the Omnistudio standard runtime is no longer the daunting, manual chore it used to be. OMA does most of the heavy lifting. Moving to the standard runtime means you can enjoy up to 5x better runtime performance, vastly simplified deployments, and immediate access to cutting-edge features like Agentforce integration.</span></p>
<p><span style="font-weight: 400">Don&#8217;t let a managed package runtime hold you back from the platform&#8217;s latest innovations. Download the </span><a href="https://www.npmjs.com/package/@salesforce/plugin-omnistudio-migration-tool?activeTab=versions"><span style="font-weight: 400">OMA tool</span></a><span style="font-weight: 400"> via the Salesforce CLI and migrate to standard </span><a href="https://www.salesforce.com/products/omnistudio/overview/"><span style="font-weight: 400">Omnistudio</span></a><span style="font-weight: 400"> to future-proof your business workflows today.</span></p>
<h2><b>Resources</b></h2>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">Trailhead: </span><a href="https://trailhead.salesforce.com/content/learn/modules/omnistudio-development-essentials"><span style="font-weight: 400">Omnistudio Development Essentials</span></a><span style="font-weight: 400"> </span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Trailhead: </span><a href="https://trailhead.salesforce.com/content/learn/modules/omnistudio-omniscript-fundamentals"><span style="font-weight: 400">Omnistudio Omniscript Fundamentals</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">External site: </span><a href="https://youtu.be/x7kwVCFpKyM?si=k7V_kyNXkUpMv1q4"><span style="font-weight: 400">YouTube: Build Low-Code Digital Experiences with All-New OmniStudio  | TDX Bengaluru</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">Documentation: </span><a href="https://help.salesforce.com/s/articleView?language=en_US&amp;id=xcloud.os_migrate_omnistudio_custom_objects_to_standard_objects.htm&amp;type=5&amp;_ga=2.251188102.1251986665.1771926946-585422095.1771404282"><span style="font-weight: 400">Migrate Omnistudio Components from Vlocity Industries Managed Packages and Custom Data Model to Omnistudio Standard Runtime</span></a></li>
</ul>
<h2><b>About the author</b></h2>
<p><b>Kishore Kumar Kurri</b><span style="font-weight: 400"> is a Principal Member of Technical Staff (PMTS) at Salesforce with nearly 20 years of software engineering experience. He&#8217;s part of the Industries Common Services – OmniStudio team, specializing in cloud performance, AI-driven features, and developer tooling at platform scale. Kishore has led key initiatives, including Omnistudio&#8217;s Connect API modernization, the OmniStudio Migration Assessment (OMA) tool, and Command Center Live Cards for OmniSupervisor. His work focuses on scalability, customer trust, and engineering excellence across Salesforce&#8217;s intelligent cloud experiences. Connect with him on </span><a href="https://www.linkedin.com/in/kishore-kumar-kurri-9857461b/"><span style="font-weight: 400">LinkedIn</span></a><span style="font-weight: 400">.</span></p>
<p><b>Krishna Kruthiventi</b><span style="font-weight: 400"> is a Senior Product Manager at Salesforce, specializing in Industries Cloud solutions. His primary focus is on the Omnistudio product suite on simplifying complex enterprise workflows and elevating Omnistudio to deliver best-in-class, consumer-grade digital experiences for both administrators and end users. Follow him on </span><a href="https://www.linkedin.com/in/krishna-deepak-kruthiventi-08339183/"><span style="font-weight: 400">LinkedIn</span></a><span style="font-weight: 400">.</span></p>
<p><b>Payal Verma</b><span style="font-weight: 400"> is a Content Marketing Analyst at Salesforce with over 4 years of professional experience in product, brand, and content marketing. She&#8217;s worked across both B2B and B2C markets, developing and executing content strategies for a wide range of formats, including blogs, social media, scripts, e-books, guides, etc. Follow her on </span><a href="https://www.linkedin.com/in/payal-verma-writer-marketer/"><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/08/migrate-from-managed-package-runtime-to-the-omnistudio-standard-runtime">Migrate From Managed Package Runtime to the Omnistudio Standard Runtime</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/08/migrate-from-managed-package-runtime-to-the-omnistudio-standard-runtime/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206835</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260813161140/Generic-B-5-e1786662712525.png?w=1000" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260813161140/Generic-B-5-e1786662712525.png?w=1000" medium="image" />
	</item>
		<item>
		<title>Salesforceのスキルを活用して、Claude Codeで本番運用可能なアプリを構築する</title>
		<link>https://developer.salesforce.com/blogs/2026/08/build-production-ready-apps-in-claude-code-with-salesforce-skills-jp</link>
		<comments>https://developer.salesforce.com/blogs/2026/08/build-production-ready-apps-in-claude-code-with-salesforce-skills-jp#respond</comments>
		<pubDate>Wed, 12 Aug 2026 07:05:07 +0000</pubDate>
		<dc:creator><![CDATA[Akshata Sawant]]></dc:creator>
				<category><![CDATA[Apex]]></category>
		<category><![CDATA[App Development]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Developer Tooling]]></category>
		<category><![CDATA[Lightning Web Components]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Claude Code]]></category>
		<category><![CDATA[Salesforce CLI]]></category>
		<category><![CDATA[Salesforce Code Analyzer]]></category>
		<category><![CDATA[Salesforce Skills]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Test Classes]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206831</guid>
		<description><![CDATA[<p>Salesforce Skills &#12434;&#20351;&#29992;&#12375;&#12390;&#12289;Claude Code &#12391;&#26412;&#30058;&#29872;&#22659;&#21521;&#12369;&#12398;&#12450;&#12503;&#12522;&#12434;&#27083;&#31689;&#12375;&#12289;&#19968;&#25324;&#29983;&#25104;&#12373;&#12428;&#12383;&#12467;&#12540;&#12489;&#12289;Apex &#12467;&#12531;&#12488;&#12525;&#12540;&#12521;&#12540;&#12398;&#12525;&#12472;&#12483;&#12463;&#12289;&#12362;&#12424;&#12403;&#12486;&#12473;&#12488;&#12463;&#12521;&#12473;&#12434;&#29983;&#25104;&#12375;&#12414;&#12377;&#12290;</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/08/build-production-ready-apps-in-claude-code-with-salesforce-skills-jp">Salesforceのスキルを活用して、Claude Codeで本番運用可能なアプリを構築する</a> appeared first on <a href="https://developer.salesforce.com/blogs">Salesforce Developers Blog</a>.</p>
]]></description>
				<content:encoded><![CDATA[<blockquote><p>※本記事は2026年7月22日に米国で公開された <a href="//developer.salesforce.com/blogs/2026/06/build-production-ready-apps-in-claude-code-with-salesforce-skills">Build Production-Ready Apps in Claude Code with Salesforce Skills</a>の抄訳です。本記事の正式言語は英語であり、その内容および解釈については英語が優先されます。</p></blockquote>
<p><span style="font-weight: 400">Claude Codeの<a href="https://github.com/forcedotcom/sf-skills">Salesforceスキル</a>を使うと、自然言語で指示するだけで、本番品質のApexコード、Lightning Webコンポーネント（LWC）、テストクラスを生成できます。生成されたコードは</span><a href="https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/overview"><span style="font-weight: 400">Salesforce Code Analyzer</span></a><span style="font-weight: 400">（英語）のチェックに自動的に合格し、テストのコードカバー率も75%以上を達成します。つまり、必要なものを簡単な言葉で説明するだけで、あとはClaudeがSalesforceのベストプラクティスに従った、そのままデプロイできるコードを生成してくれるのです。</span></p>
<p><span style="font-weight: 400">この記事では、LWC、Apexコントローラー、テストクラスを組み合わせて、完全な取引先作成フォームを構築する流れを見ていきます。その後で、スキルシステム内部の仕組みを説明し、バッチジョブ、サービスレイヤー、デバッグワークフローなどの高度なパターンを取り上げます。</span></p>
<h2><span style="font-weight: 400">Salesforceスキルとは</span></h2>
<p><span style="font-weight: 400">Salesforceスキルは、Salesforceのアーキテクチャー、ガバナ制限、セキュリティパターン、デプロイ要件を理解している、Salesforceに特化したAI機能です。いわば、開発ワークフローに熟練の開発者が直接組み込まれているようなものと考えてください。</span></p>
<p>Claude Codeに「取引先作成フォームを作成して」と指示すると、生成されるのは、単なる汎用的なコードではありません。<code>generating-apex</code>スキルがプロジェクトの規則やパターンを理解し、適切なエラー処理とガバナ制限を考慮したクエリーを含む、本番品質のコードを生成します。また、ループ内でのSOQLの実行を防ぐといったガードレールを適用し、一括処理化のパターンを検証します。続いて、<code>TestDataFactory</code>パターンを使用し、75%以上のコードカバー率を達成するテストクラスを作成します。タスクを完了する前に、Salesforce Code Analyzerを実行し、テストスイートも自動的に実行します。</p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206500" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260608144207/Claude-Code-terminal-showing-the-generating-apex-skill-being-activated--e1780954943727.png?w=1000" class="postimages" width="1000" height="526" alt="generating-apexスキルが有効化されているClaude Codeのターミナル" />
			  </span>
			</p>
<h2><span style="font-weight: 400">スキルの仕組み</span></h2>
<p>Claude Codeに指示を出すと、システムは4つの段階からなるワークフローに沿って動作します。まず、Claudeがプロンプトの内容を分析し、適切なスキルに対応付けます。たとえば、「Lightning Webコンポーネント」というキーワードがあれば<code>generating-lwc-components</code>が有効になります。プロンプトに「Apexクラス」が入っていれば<code>generating-apex</code>が、「テストクラス」なら<code>generating-apex-test</code>が起動します。</p>
<p>該当するスキルが特定されると、それぞれのスキルがワークフローを実行します。<code>generating-apex</code>は、命名パターンや既存のクラスなど、プロジェクトの決まりを把握します。サービス、コントローラー、バッチ、その他のアーキテクチャーから適切なパターンを選択し、assetsディレクトリ内のテンプレートを確認します。続いて、共有ルールを適用し、ループ内でのSOQLの実行を防ぐガードレールを組み込んだクラスを生成します。次に、<code>generating-apex-test</code>スキルを呼び出し、網羅的なテストを作成して十分なコードカバー率を確保します。</p>
<p>このプロセス全体を通じて、スキルがガードレールを自動的に適用します。スキルは、ループ内でクエリーを実行するコードを拒否し、すべてのクラスに共有ルールを強制し、テストクラスを生成するまで処理を完了しません。Lightning Webコンポーネントについては、クライアント側とサーバー側の両方が所定のパターンに従っているかどうかを検証します。各スキルは<code>.cls-meta.xml</code>など、必要となるメタデータファイルも自動で生成します。</p>
<p>最後に、スキルはタスクの正常完了を報告する前に、生成したコードを検証します。<code>sf code-analyzer</code>を実行してセキュリティ上の問題を検出し、<code>sf apex run test</code>を実行してコードが正しく動作することを確認し、75%以上のコードカバー率を確保します。その結果、単なる定型コードではなく、本番運用を想定したコードが生成されるのです。</p>
<h2><span style="font-weight: 400">チュートリアル – 取引先作成フォームの作成</span></h2>
<p><span style="font-weight: 400">では、実際に機能を作成してみましょう。このチュートリアルでは、検証、エラー処理、テストまで含めた、取引先レコード作成用のLightning Webコンポーネントフォームを構築します。</span></p>
<h3><span style="font-weight: 400">概要</span></h3>
<p><span>ここでは、3つの要素で構成される完全なソリューションを作成します。3つの要素とは、取引先名と電話番号を入力項目として持つLightning Webコンポーネント、</span><code><span>@AuraEnabled</span></code><span>メソッドとエラー処理を備えたApexコントローラー、75%以上のコードカバー率を確保し、251件以上のレコードで一括処理をテストするテストクラスです。フォームにはインライン検証とトースト通知を実装し、アプリケーションビルダーに追加してホームページに配置できる状態にします。</span></p>
<h3><span style="font-weight: 400">事前準備</span></h3>
<p><span>構築に取りかかる前に、</span><a href="https://claude.ai/code"><u>Claude Code</u></a>（個人開発者は無料）と、Node.js（スキルのインストールに使用）がインストールされていることを確認してください。また、組織に対して、<a href="https://developer.salesforce.com/tools/salesforcecli"><u>Salesforce CLI</u></a>の認証を済ませておいてください。この例では開発者向けエディションの組織、Sandbox組織、またはスクラッチ組織のいずれかが必要です。まだ認証していない場合は、<code>sf org login web</code>を実行してください。</p>
<h3><span style="font-weight: 400">Salesforceスキルをインストールする</span></h3>
<p><span style="font-weight: 400">Salesforceスキルのセットアップは、コマンドを1つ実行するだけで完了します。Salesforceプロジェクトのディレクトリに移動し、次のコマンドを実行してください。</span></p>
<pre language="text">npx skills add forcedotcom/sf-skills
</pre>
<p><span style="font-weight: 400">これで、GitHubからSalesforceスキルの公式ライブラリが取得されます。</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206501" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260608144246/Interactive-skill-selection-interface-showing-various-Salesforce-skills.png?w=968" class="postimages" width="968" height="994" alt="さまざまなSalesforceスキルを選択できる対話型インターフェース" />
			  </span>
			</p>
<p><span style="font-weight: 400"></span><b>スペースキー</b><span style="font-weight: 400">を使って、インストールするスキルを選択します。このチュートリアルでは、以下のスキルを選択してください。</span></p>
<ul>
<li><code>generating-apex</code>：Apexクラスを生成</li>
<li><code>generating-apex-test</code>：Apexテストクラスを生成</li>
<li><code>generating-lwc-components</code>：Lightning Webコンポーネントを生成</li>
<li><code>debugging-apex-logs</code>：Apexクラスをデバッグ</li>
</ul>
<p><span style="font-weight: 400"></span><b>Enter</b><span style="font-weight: 400">キーを押してインストールします。 </span></p>
<p><span style="font-weight: 400">インストールの範囲は、次のいずれかを選択できます。 </span></p>
<ul>
<li style="font-weight: 400"><b>Project</b><span style="font-weight: 400">：現在のディレクトリにインストール（プロジェクトと一緒にコミット） </span></li>
<li style="font-weight: 400"><b style="color: #4a4a4a">Global</b><span style="font-weight: 400">：ホームディレクトリにインストール（すべてのプロジェクトで利用可能）</span></li>
</ul>
<p>これで、Salesforceプロジェクトでスキルを利用できるようになります。インストール済みのスキルは、プロジェクト内の<code>skills-lock.json</code>に記録されます。<code> </code></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206502" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260608144334/Screenshot-of-a-Salesforce-Project-folder-showing-installed-skills.png?w=678" class="postimages" width="678" height="405" alt="インストール済みのスキルが表示されたSalesforceプロジェクトフォルダーのスクリーンショット" />
			  </span>
			</p>
<p><span style="font-weight: 400"></span><span style="font-weight: 400">skills-lock.json</span><span style="font-weight: 400">ファイルを開くと、インストール済みのすべてのスキルを確認できます。</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206503" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260608144404/Screenshot-of-the-skills-lock.json-file-showing-installed-skills-e1780955067628.png?w=1000" class="postimages" width="1000" height="855" alt="インストール済みのスキルが表示されたskills-lock.jsonファイルのスクリーンショット" />
			  </span>
			</p>
<p><span style="font-weight: 400">現在、forcedotcom/sf-skillsライブラリには60以上のスキルがあり、その数は増え続けています。スキルの一覧は、</span><a href="https://github.com/forcedotcom/sf-skills"><span style="font-weight: 400">公式のsf-skillsリポジトリ</span></a><span style="font-weight: 400">（英語）で確認できます。</span></p>
<p>利用可能なすべてのスキルをインストールするには、<code>--all</code>フラグを追加してください。</p>
<pre language="text">npx skills add forcedotcom/sf-skills --all
</pre>
<p><span style="font-weight: 400">注 – </span><span style="font-weight: 400">Salesforceスキルは、npmパッケージとしては提供されていません。また、</span><a href="https://www.npmjs.com/package/skills"><span style="font-weight: 400">「skills」npmパッケージ</span></a><span style="font-weight: 400">（英語）は、Salesforceが所有しているものではありません。Salesforceは、このパッケージをGitHubリポジトリにあるスキルを簡単にインストールするために利用しています。</span></p>
<h3><span style="font-weight: 400">ステップ1：Claude Codeを起動する</span></h3>
<p><span style="font-weight: 400">プロジェクトディレクトリでClaude Codeを起動します。</span></p>
<pre language="text">claude
</pre>
<p><span style="font-weight: 400">Claude Codeの対話型プロンプトが表示されます。ここから、Claude Codeが威力を発揮します。</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206504" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260608144445/Claude-Code-command-line-interface-showing-the-welcome-message-and-prompt-ready-for-input-e1780955128999.png?w=1000" class="postimages" width="1000" height="246" alt="ウェルカムメッセージが表示され、プロンプトへの入力が可能なClaude Codeのコマンドライン画面" />
			  </span>
			</p>
<h3><span style="font-weight: 400">ステップ2：指示を入力する</span></h3>
<p><span style="font-weight: 400">以下のプロンプトを入力するか、コピーして貼り付けます。</span></p>
<pre language="text">以下の要素で構成される、完全なSalesforceソリューションを作成してください。

1. Lightning Webコンポーネント（LWC）
accountCreationFormという名前で、次の2つの入力項目を持つフォームコンポーネントを作成してください。
- 取引先名（必須）
- 電話（必須、10～15桁の数字）
- 両方の項目の入力値が有効になるまで、［保存］ボタンを無効にする
- 入力検証のエラーメッセージをインラインで表示する
- 保存に成功した場合は成功のトースト通知を、失敗した場合はエラーのトースト通知を表示する
- 読み込み中はスピナーを表示する

2. Apexコントローラー
- AccountCreationControllerクラスを作成する
- メソッド：@AuraEnabled(cacheable=false) saveAccount(String accountName, String phone)
- 標準の電話項目を使用する（取引先には標準のメール項目がありません）
- AuraHandledExceptionを使用して、適切なエラー処理を実装する
- コードカバー率が85%以上になるテストクラスを作成する

3. アプリケーションビルダーとの統合
- アプリケーションページとホームページで使用できるよう、*.js-meta.xmlを設定する
- デプロイ手順を示す

制約：
- DML処理であるため、@wireではなくApexメソッドを命令として呼び出してください
- SalesforceのLWCベストプラクティスに従ってください
- 標準オブジェクトと標準項目のみを使用してください
</pre>
<p><span style="font-weight: 400">上記の要件をすべて含む、取引先作成フォームのプロンプトをターミナルに入力すると、次のように表示されます。 </span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206511" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260609002034/image5-e1780989648382.png?w=1000" class="postimages" width="1000" height="526" alt="取引先作成フォームを作成するための完全なプロンプトが表示されているターミナル" />
			  </span>
			</p>
<h3><span style="font-weight: 400">ステップ3：スキルの動作を確認する</span></h3>
<p>プロンプトを入力すると、Claude Codeは適切なスキルを自動的に有効にします。UIには<code>generating-lwc-components</code>、コントローラーには<code>generating-apex</code>、テストには<code>generating-apex-test</code>が使用されます。</p>
<p>Claude Codeは、既存の命名規則やアーキテクチャーレイヤーを含む、プロジェクトのパターンを検出します。続いて、必要なファイルをすべて生成します。</p>
<ul>
<li><code>accountCreationForm.html:</code> Lightning Webコンポーネントのテンプレート</li>
<li><code>accountCreationForm.js:</code> Apexメソッドを命令としてコールするコンポーネントロジック</li>
<li><code>accountCreationForm.js-meta.xml:</code> アプリケーションページとホームページに公開するためのメタデータ</li>
<li><code>AccountCreationController.cls:</code> エラー処理を実装したApexコントローラー</li>
<li><code>AccountCreationController.cls-meta.xml:</code><code> </code>Apexメタデータファイル</li>
<li><code>AccountCreationControllerTest.cls:</code> テストメソッドを含むテストクラス</li>
<li><code>AccountCreationControllerTest.cls-meta.xml:</code> テストメタデータファイル</li>
</ul>
<h3><span style="font-weight: 400">ステップ4：生成されたコードとテストクラスをレビューする</span></h3>
<p><span style="font-weight: 400">生成されたコードとテストクラスの内容を確認します。Salesforceスキルによって、本番運用を想定したコードとテストクラスが生成されていることを確認できます。Apexクラスのコードカバー率も100%に達しています。</span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206505" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260608145328/Salesforce-CLI-output-showing-test-execution-results.png?w=624" class="postimages" width="624" height="934" alt="テストの実行結果を表示するSalesforce CLIの出力" />
			  </span>
			</p>
<h3><span style="font-weight: 400">ステップ5：ソリューションをデプロイしてテストする</span></h3>
<p><span style="font-weight: 400">Claudeを使用しているため、ソリューションのデプロイとテストもClaudeが手伝ってくれます。または、Salesforce CLIコマンドを使用することもできます。 </span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206506" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260608145356/Salesforce-CLI-showing-successful-deployment-of-Lightning-web-component-Apex-controller-and-test-class-files.png?w=614" class="postimages" width="614" height="975" alt="Lightning Webコンポーネント、Apexコントローラー、テストクラスの各ファイルが正常にデプロイされたことを示すSalesforce CLI" />
			  </span>
			</p>
<h3><span style="font-weight: 400">ステップ6：組織のホームページにコンポーネントを追加する</span></h3>
<p><span style="font-weight: 400"></span><b>［設定］→［Lightningアプリケーションビルダー］</b><span style="font-weight: 400">に移動し、</span><b>［新規］をクリックして［ホームページ］</b><span style="font-weight: 400">を選択します。［2つの範囲］などのテンプレートを選択します。［カスタム］コンポーネントセクションから［</span><b>AccountCreationForm</b><span style="font-weight: 400">］をページ上にドラッグします。</span><b>［保存］、［有効化］、［組織のデフォルトとして割り当て］</b><span style="font-weight: 400">の順にクリックします。</span></p>
<p>以下のスクリーンショットでは、Lightningアプリケーションビルダーで、［カスタム］コンポーネントパネルに<code>accountCreationForm</code>コンポーネントが表示され、ホームページのレイアウトに配置されています。</p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206507" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260608145422/Lightning-App-Builder-interface-with-the-accountCreationForm-component-visible-e1780955674602.png?w=1000" class="postimages" width="1000" height="511" alt="accountCreationFormコンポーネントが表示されたLightningアプリケーションビルダーのインターフェース" />
			  </span>
			</p>
<h3><span style="font-weight: 400">ステップ7：Salesforce UIでテストする</span></h3>
<p><span style="font-weight: 400">Salesforce組織のホームページに移動し、コンポーネントをテストしてみましょう。［取引先名］を空欄にすると、エラーメッセージが表示されます。9桁の無効な電話番号を入力しても、エラーメッセージが表示されます。有効なデータを入力すると、［保存］ボタンが有効になります。 </span></p>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206509" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260609001730/Salesforce-Home-page-displaying-the-Account-Creation-Form-componentAdvanced-use-cases-e1780989466621.png?w=1000" class="postimages" width="1000" height="228" alt="取引先作成フォームコンポーネントが表示されたSalesforceホームページ" />
			  </span>
			</p>
<p>このチュートリアルでは、1つのLWCとApexコントローラーを組み合わせたパターンを取り上げましたが、スキルは、<code>Database.Stateful</code>を使用するバッチジョブ、サービス、セレクター、ドメインの各レイヤーで構成されるアーキテクチャー、条件分岐を含む画面フロー、デバッグログの分析など、さらに複雑なシナリオにも対応できます。</p>
<p><span style="font-weight: 400">Salesforceスキルを使って構築できる4つのパターンを紹介します。</span></p>
<h3><span style="font-weight: 400">1. データを処理するバッチジョブの生成</span></h3>
<p><span style="font-weight: 400">Claudeへの指示：「2年よりも前のケースをアーカイブする、CaseArchivalBatchという名前のバッチApexクラスを作成してください。ClosedDate &lt; LAST_N_YEARS:2に該当するケースを検索し、Status__cを&#8217;Archived&#8217;に更新してください。また、適切なエラー処理とログ記録を組み込んでください。75%以上のコードカバー率を確保するテストクラスを生成してください」</span></p>
<p>Claudeは<code>generating-apex</code>を起動し、<code>CaseArchivalBatch.cls</code>を生成します。このクラスは、エラーを追跡するために<code>Database.Stateful</code>を実装し、適切なstart、execute、finishメソッドと、ループ内でSOQLを実行せず、ガバナ制限を考慮したクエリーを備えています。また、251件以上のレコードを使った一括処理テストを含む<code>CaseArchivalBatchTest.cls</code>も生成されます。</p>
<h3><span style="font-weight: 400">2. サービスレイヤークラスの構築</span></h3>
<p><span style="font-weight: 400">Claudeへの指示：「サービス-セレクター-ドメインパターンを使用し、取引先の請求先住所を一括更新するメソッドを備えたAccountServiceクラスを作成してください。メソッドのシグネチャは、updateBillingAddresses(Map&lt;Id, Address&gt; addressByAccountId)としてください。適切なエラー処理を組み込み、90%以上のコードカバー率を確保するテストクラスも作成してください」</span></p>
<p>Claudeは、with sharingキーワードを指定し、DMLを一括処理化した<code>AccountService.cls</code>を生成します。このクラスは、クエリーを<code>AccountSelector.cls</code>に委譲し、一部のレコードだけが成功した場合にも対応できるように<code>List<span>&lt;Database.SaveResult&gt;</span></code>を返します。Claudeは<code>TestDataFactory</code>パターンを使用したテストクラスも作成します。</p>
<h3><span style="font-weight: 400">3. 画面フローの作成</span></h3>
<p><span style="font-weight: 400">Claudeへの指示：「Lead_Qualificationという名前で、リード評価用の画面フローを作成してください。会社名、業種、年間売上の各項目に対応する画面を追加してください。売上に応じて適切なキューに振り分ける決定要素を追加してください。売上が100万ドルを超える場合はEnterprise Queueに、それ以外の場合はSMB Queueに割り当ててください」</span></p>
<p>Claudeは<code>generating-flow</code>を有効化し、Salesforceのベストプラクティスに従ったフローメタデータを生成します。</p>
<h3><span style="font-weight: 400">4. Apexログの分析</span></h3>
<p><span style="font-weight: 400">Claudeへの指示：「debug.log内のApexログを分析し、バッチジョブがガバナ制限に達している原因を特定してください」 </span></p>
<p>Claudeは<code>debugging-apex-logs</code>スキルを使用してログファイルを解析し、SOQL文とDML文を検出します。また、ループ内でSOQLを実行している箇所を特定し、CPU時間とヒープ使用量を報告して、最適化を提案します。</p>
<h2><span style="font-weight: 400">スキルを活用するためのベストプラクティス</span></h2>
<p><span style="font-weight: 400">プロンプトに具体的な情報を含めるほど、出力の質が高まります。「Apexクラスを作成して」ではなく、「名前と電話番号を検証して取引先レコードを保存する、AccountForm LWC用のApexコントローラーを作成して」といった指示にしてみましょう。項目のAPI参照名、オブジェクト間のリレーション、ビジネスロジックの具体的な要件も含めるとよいでしょう。</span></p>
<p><span style="font-weight: 400">Claude Codeは対話形式のツールですので、最初の出力が期待どおりでなければ、変更を依頼できます。「そのコントローラーに一括処理時のエラー処理を追加して」、「テストクラスでTestDataFactoryパターンを使用するように変更して」と指示するだけです。スキルが対話全体のコンテキストを保持しながら、指示に応じてコードを更新します。</span></p>
<p><span style="font-weight: 400">スキルは本番品質のコードを生成しますが、本番環境にデプロイする前に、必ず出力内容をレビューしてください。項目のAPI参照名が組織のスキーマと一致していることを確かめ、カスタムオブジェクトとカスタム項目がデプロイ先の組織に存在することも確認してください。共有ルールや項目レベルセキュリティを含む、セキュリティ設定のチェックも必要です。本番環境へのデプロイの前に、まずSandboxでテストし、さらに安全性を再確認するため、Salesforce Code Analyzerを手動で実行しましょう。</span></p>
<p>経験豊富な開発者であっても、スキルから新たに学べることがあります。ぜひスキルを使ってみてください。見逃していたベストプラクティスを発見できるかもしれません。また<code>Given/When/Then</code>パターンを使ったテストクラスの構成方法を理解し、セキュリティとパフォーマンスにとって重要なCode Analyzerのフラグを知ることもできます。スキルは自動化ツールであると同時に、開発を学ぶためのツールでもあります。</p>
<h2><span style="font-weight: 400">スキルをさらに活用する</span></h2>
<p><span style="font-weight: 400">ここまでスキルの実際の動作を見てきました。</span><a href="https://github.com/forcedotcom/sf-skills"><span style="font-weight: 400">スキルライブラリ</span></a><span style="font-weight: 400">（英語）には60以上の利用可能なスキルが公開されています。こうしたスキルを使えば、FlexCardとIntegration Procedureを使用したOmniStudioソリューションの構築、Data 360データソースへの接続、B2Bコマースストアの作成、オーケストレーションと連携する画面フローの生成など、さまざまなことが可能になります。</span></p>
<p>さらに高度なパターンも試してみましょう。Trigger Actions Framework（TAF）を使って <code>Trigger Frameworks</code>を構築したり、<code>Queueable with Finalizers</code>を組み合わせて後処理ロジックを伴う非同期処理を実装したりすることもできます。また、<code>Custom REST Resources</code>を使って、適切なエラー処理を備えたバージョン付きのAPIを構築することもできます。</p>
<p><span style="font-weight: 400">スキルはオープンソースです。そのため、リポジトリをフォークしてパターンをカスタマイズし、チームの命名規則をテンプレートに追加できます。組織固有のスキルを作成することも可能です。</span><a href="https://github.com/forcedotcom/sf-skills/blob/main/CONTRIBUTING.md"><span style="font-weight: 400">コントリビューションガイド</span></a><span style="font-weight: 400">（英語）を参考にして開発を始めてみましょう。</span></p>
<p><span style="font-weight: 400">最後に、スキルを既存のワークフローと統合しましょう。スキルは、</span><a href="https://marketplace.visualstudio.com/items?itemName=Anthropic.claude-code"><span style="font-weight: 400">Claude CodeのVS Code拡張機能</span></a><span style="font-weight: 400">（英語）や、自動化ワークフローでコードを生成するCI/CDパイプラインとスムーズに連携します。また、プルリクエストを提出する前の一次レビュアーとして、コードレビュープロセスにも組み込めます。</span></p>
<h2><span style="font-weight: 400">まとめ</span></h2>
<p><span style="font-weight: 400">Claude CodeのSalesforceスキルによって、AIは単なるコード生成ツールから開発のエキスパートへと進化します。定型コードの記述や、ガバナ制限を考慮した実装を手作業で行わなくても、やりたいことを説明するだけで、Claudeが本番品質のパターンを使って形にします。</span></p>
<p><span style="font-weight: 400">ApexやLWCの生成からログのデバッグまで、スキルはベストプラクティスを実践しながら、ワークフローを加速させます。そのため、開発者は実装作業の繰り返しに時間を費やすのではなく、ビジネス課題の解決に注力できます。</span></p>
<p>さっそく始めてみませんか？<a href="https://claude.ai/code"><u>Claude Codeを無料でダウンロード</u></a>し、Salesforceプロジェクトで<code>npx skills</code>を実行して<code>forcedotcom/sf-skills</code>を追加しましょう。数分後には、自然言語で指示するだけで、本番環境に対応したコードを生成できるようになります。</p>
<p><span style="font-weight: 400">質問がある方やスキルで構築したものを共有したい方は、</span><a href="https://developer.salesforce.com/forums"><span style="font-weight: 400">Salesforceの開発者コミュニティ</span></a><span style="font-weight: 400">に参加してください。</span><a href="https://www.linkedin.com/showcase/salesforce-developers/"><span style="font-weight: 400">LinkedIn</span></a><span style="font-weight: 400">と</span><a href="https://twitter.com/SalesforceDevs"><span style="font-weight: 400">X（旧Twitter）</span></a><span style="font-weight: 400">でつながることもできます。スキルを使った感想や体験を、ぜひお聞かせください。</span></p>
<h2><span style="font-weight: 400">関連情報</span></h2>
<ul>
<li style="font-weight: 400"><a href="http://github.com/forcedotcom/sf-skills"><span style="font-weight: 400">Salesforceスキルライブラリ（英語）</span></a><b> </b></li>
<li style="font-weight: 400"><a href="http://claude.ai/code"><span style="font-weight: 400">Claude Codeドキュメント</span></a><b> </b></li>
<li style="font-weight: 400"><a href="http://docs.anthropic.com/claude-code"><span style="font-weight: 400">Claude Code入門ガイド</span></a><b> </b></li>
<li style="font-weight: 400"><a href="http://agentskills.io"><span style="font-weight: 400">Agent Skillsの仕様（英語）</span></a><b> </b></li>
<li style="font-weight: 400"><a href="http://developer.salesforce.com/tools/salesforcecli"><span style="font-weight: 400">Salesforce CLIリファレンス</span></a><b> </b></li>
<li style="font-weight: 400"><a href="http://trailhead.salesforce.com/content/learn/modules/lightning-web-components-basics"><span style="font-weight: 400">Trailhead：</span><span style="font-weight: 400">Lightning Web コンポーネントの基本</span></a><b> </b></li>
<li style="font-weight: 400"><a href="http://trailhead.salesforce.com/content/learn/modules/apex_testing"><span style="font-weight: 400">Trailhead：Apexテスト</span></a></li>
</ul>
<h2><span style="font-weight: 400">執筆者について</span></h2>
<p><b>Akshata Sawant</b><span style="font-weight: 400">は、Salesforceのシニアデベロッパーアドボケート。Packt Publishingから出版された『MuleSoft for Salesforce Developers』の共著者です。詳しい経歴や実績については、</span><a href="https://www.linkedin.com/in/akshatasawant02/"><span style="font-weight: 400">LinkedIn</span></a><span style="font-weight: 400">プロフィールをご覧ください。 </span></p>
<p>&nbsp;</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/08/build-production-ready-apps-in-claude-code-with-salesforce-skills-jp">Salesforceのスキルを活用して、Claude Codeで本番運用可能なアプリを構築する</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/08/build-production-ready-apps-in-claude-code-with-salesforce-skills-jp/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206831</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260608135949/SingleHeadshot-3-e1780952406426.png?w=1000" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260608135949/SingleHeadshot-3-e1780952406426.png?w=1000" medium="image" />
	</item>
		<item>
		<title>Extending Agentforce with External MCP Tools via MuleSoft</title>
		<link>https://developer.salesforce.com/blogs/2026/08/extending-agentforce-with-external-mcp-tools-via-mulesoft</link>
		<comments>https://developer.salesforce.com/blogs/2026/08/extending-agentforce-with-external-mcp-tools-via-mulesoft#respond</comments>
		<pubDate>Tue, 11 Aug 2026 15:00:59 +0000</pubDate>
		<dc:creator><![CDATA[Alex Martinez]]></dc:creator>
				<category><![CDATA[Agentforce]]></category>
		<category><![CDATA[APIs and Integrations]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Developer Tooling]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Agent Studio]]></category>
		<category><![CDATA[connected apps]]></category>
		<category><![CDATA[DataWeave 2.0]]></category>
		<category><![CDATA[GenAiFunction]]></category>
		<category><![CDATA[JSON-RPC]]></category>
		<category><![CDATA[Model context protocol]]></category>
		<category><![CDATA[MuleSoft CloudHub]]></category>

		<guid isPermaLink="false">https://developer.salesforce.com/blogs/?p=206817</guid>
		<description><![CDATA[<p>Learn how to build and deploy an OAuth-secured MCP server on MuleSoft CloudHub, register it in Salesforce, and empower Agentforce agents to execute external tools without custom Apex.</p>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/08/extending-agentforce-with-external-mcp-tools-via-mulesoft">Extending Agentforce with External MCP Tools via MuleSoft</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">Agentforce agents excel at streamlining Salesforce-native operations, from surfacing CRM insights and querying knowledge bases to automating complex record workflows. Using new MCP (Model Context Protocol) capabilities, these agents can now seamlessly interact with external utilities. </span></p>
<p><span style="font-weight: 400">This provides your agents with the capacity to execute external computational logic, access third-party data repositories, or trigger microservices hosted on disparate platforms. The integration bypasses traditional Apex callouts or intricate middleware, utilizing a standardized protocol to link your agent with any remote MCP-compatible tool.</span></p>
<p><span style="font-weight: 400">In this post, we will demonstrate how to deploy a </span><b>timezone MCP server</b><span style="font-weight: 400"> utilizing MuleSoft CloudHub, register the service within your Salesforce environment, and empower an Agentforce agent to leverage these tools through the robust MCP architecture.</span></p>
<h2><span style="font-weight: 400">Why MCP matters for developers</span></h2>
<p><span style="font-weight: 400">When Agentforce agents can call MCP-compliant tools, you gain:</span></p>
<ul>
<li style="font-weight: 400"><b>Standardized tool discovery</b><span style="font-weight: 400">: MCP servers advertise capabilities via tools/list. Salesforce automatically discovers available tools during registration.</span></li>
<li style="font-weight: 400"><b>Zero custom Apex</b><span style="font-weight: 400">: MCP tool calls are JSON-RPC over HTTP. The platform handles serialization, authentication, and error handling.</span></li>
<li style="font-weight: 400"><b>Secure external context</b><span style="font-weight: 400">: MCP servers can be secured with OAuth 2.0. Salesforce manages token acquisition and refresh automatically.</span></li>
<li style="font-weight: 400"><b>Reusable infrastructure</b><span style="font-weight: 400">: One MCP server can serve multiple agents, orgs, or non-Salesforce AI systems.</span></li>
</ul>
<p><span style="font-weight: 400">Your tools become platform-agnostic services.</span></p>
<h2><span style="font-weight: 400">Why MuleSoft for hosting MCP servers</span></h2>
<p><span style="font-weight: 400">MuleSoft Anypoint Platform provides the exact primitives MCP requires out of the box:</span></p>
<ul>
<li style="font-weight: 400"><b>HTTP Listener</b><span style="font-weight: 400">: Mounts the /mcp endpoint with method routing. No framework boilerplate.</span></li>
<li style="font-weight: 400"><b>DataWeave 2.0</b><span style="font-weight: 400">: Pure functional transformations handle JSON-RPC parsing, tool logic, and response formatting in a single expression.</span></li>
<li style="font-weight: 400"><b>CloudHub</b><span style="font-weight: 400">: One-click deploy with auto-scaling, monitoring, and zero infrastructure management.</span></li>
<li style="font-weight: 400"><b>Connected Apps</b><span style="font-weight: 400">: Client credentials grant for machine-to-machine auth. Salesforce consumes these natively.</span></li>
</ul>
<p><span style="font-weight: 400">The result: a production-grade MCP server with no external dependencies beyond the Mule runtime.</span></p>
<h3><span style="font-weight: 400">Example: Timezone MuleSoft MCP server</span></h3>
<p><span style="font-weight: 400">Our example server brings world clock and timezone conversion capabilities to Agentforce agents. It exposes four tools that handle the most common timezone queries.</span></p>
<table>
<thead>
<tr>
<th><b>Tool</b></th>
<th><b>Description</b></th>
<th><b>Parameters</b></p>
<p><span style="font-weight: 400"> </span></th>
</tr>
</thead>
<tbody>
<tr>
<td><code>get_current_time</code></td>
<td><span style="font-weight: 400">Current time for a city</span></td>
<td><span style="font-weight: 400">city (string)</span></td>
</tr>
<tr>
<td><code>convert_time</code></td>
<td><span style="font-weight: 400">Convert time between zones</span></td>
<td><span style="font-weight: 400">time, from_city, to_city</span></td>
</tr>
<tr>
<td><code>time_difference</code></td>
<td><span style="font-weight: 400">Hours offset between cities</span></td>
<td><span style="font-weight: 400">city1, city2</span></td>
</tr>
<tr>
<td><code>list_timezones</code></td>
<td><span style="font-weight: 400">Available cities by region</span></td>
<td><span style="font-weight: 400">region (optional)</span></td>
</tr>
</tbody>
</table>
<p><span style="font-weight: 400">All timezone logic uses </span><b>DataWeave 2.0</b><span style="font-weight: 400"> with built-in timezone support — no external API calls. The server maps 50+ common cities (NYC, London, Tokyo, Dubai) to IANA timezone IDs (America/New_York, Europe/London, Asia/Tokyo). DataWeave handles offset arithmetic, date formatting, and timezone conversion in pure functional expressions.</span></p>
<h3><span style="font-weight: 400">MCP protocol methods</span></h3>
<p><span style="font-weight: 400">The MCP server implements three core methods: initialize (handshake), tools/list (catalog), and tools/call (invocation).</span></p>
<p><span style="font-weight: 400">When Salesforce calls the server, requests flow through these stages:</span></p>
<ol>
<li style="font-weight: 400"><b>Bearer token validation</b><span style="font-weight: 400">: Returns JSON-RPC error code -32000 (Unauthorized) if the Authorization header is missing or invalid</span></li>
<li style="font-weight: 400"><b>Method routing</b><span style="font-weight: 400">: Dispatches to the appropriate flow based on method field (initialize, tools/list, or tools/call)</span></li>
<li style="font-weight: 400"><b>Tool execution</b><span style="font-weight: 400">: For tools/call, extracts the tool name and arguments, then routes to timezone-specific logic</span></li>
<li style="font-weight: 400"><b>Response formatting</b><span style="font-weight: 400">: Wraps results in MCP content arrays: {&#8220;type&#8221;:&#8221;text&#8221;,&#8221;text&#8221;:&#8221;&#8230;&#8221;}</span></li>
</ol>
<h3><span style="font-weight: 400">Production features</span></h3>
<p><span style="font-weight: 400">The server is deployed to </span><b>CloudHub</b><span style="font-weight: 400"> as a single JAR (0.1 vCores, Micro worker) with HTTPS auto-provisioned. </span><b>OAuth 2.0</b><span style="font-weight: 400"> secures the endpoint via an Anypoint Connected App (client credentials grant) and an API Manager policy. The stateless design requires no session storage — it is fully horizontally scalable. CORS headers allow browser-based clients.</span></p>
<h2><span style="font-weight: 400">Ready to configure the MCP server on your MuleSoft (Anypoint Platform) instance? </span></h2>
<p><span>Grab the full source from our </span><a href="https://github.com/SalesforceLabs/mule-mcp-timezone"><u>GitHub repo</u></a><span>. Clone the repo, build the deployable JAR with </span><code>./build.sh</code><span>, and upload it to CloudHub via Runtime Manager. The </span><a href="https://github.com/SalesforceLabs/mule-mcp-timezone/blob/main/README.md"><u>README.md</u></a><span> walks you through the prerequisites, deployment steps, and how to verify the server.</span></p>
<h2><span style="font-weight: 400">Registering the MCP server in Salesforce</span></h2>
<p><span style="font-weight: 400">With the MCP server deployed and secured, we can now register it in Salesforce.</span></p>
<p><b>Pre-requisites:</b></p>
<ul>
<li style="font-weight: 400"><span style="font-weight: 400">MuleSoft Anypoint subscription tier </span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Agentforce/Einstein enablement </span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Connected App with client-credentials grant </span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Agent Studio access</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">CloudHub application</span></li>
</ul>
<h3><span style="font-weight: 400">Import external MCP server</span></h3>
<ol>
<li style="font-weight: 400"><span style="font-weight: 400">Open </span><b>Setup</b><span style="font-weight: 400"> → Quick Find → API Catalog → </span><b>&#8220;MCP Server&#8221;.</b></li>
<li style="font-weight: 400"><span style="font-weight: 400">Click </span><b>Add MCP Server</b><span style="font-weight: 400"> → </span><b>Import External MCP Server.</b></li>
<li style="font-weight: 400"><span style="font-weight: 400">Configure:</span>
<ul>
<li style="font-weight: 400"><b>Label</b><span style="font-weight: 400">: TimezoneMCP</span></li>
<li style="font-weight: 400"><b>MCP server URL</b><span style="font-weight: 400">: Your CloudHub application URL (e.g., https://timezone-mcp-server.us-e2.cloudhub.io/mcp)</span></li>
<li style="font-weight: 400"><b>Authentication</b><span style="font-weight: 400">: OAuth 2.0</span></li>
<li style="font-weight: 400"><b>Identity provider URL</b><span style="font-weight: 400">: https://anypoint.mulesoft.com/accounts/api/v2/oauth2/token</span></li>
<li style="font-weight: 400"><b>Client ID</b><span style="font-weight: 400">: (from Connected App)</span></li>
<li style="font-weight: 400"><b>Client secret</b><span style="font-weight: 400">: (from Connected App)</span></li>
</ul>
</li>
<li style="font-weight: 400"><span style="font-weight: 400">Click </span><b>Create and Continue.</b></li>
</ol>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206818" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260810093628/image3_11d7fa-e1786379800288.png?w=1000" class="postimages" width="1000" height="554" alt="Screenshot of the &quot;Create Connection&quot; form for an MCP server." />
			  </span>
			</p>
<h3><span style="font-weight: 400">What happens during registration</span></h3>
<p><span style="font-weight: 400">Salesforce performs these steps automatically:</span></p>
<ol>
<li style="font-weight: 400"><b>Token acquisition</b><span style="font-weight: 400">: Calls the Identity provider URL with client credentials to obtain a Bearer token</span></li>
<li style="font-weight: 400"><b>MCP initialize</b><span style="font-weight: 400">: Calls the MCP server&#8217;s /mcp endpoint with method &#8220;initialize&#8221; to negotiate protocol version (2024-11-05)</span></li>
<li style="font-weight: 400"><b>Tool discovery</b><span style="font-weight: 400">: Calls method: &#8220;tools/list&#8221; to fetch the tool catalog</span></li>
<li style="font-weight: 400"><b>GenAiFunction creation</b><span style="font-weight: 400">: Creates Salesforce metadata records for each discovered tool</span></li>
</ol>
<p>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206819" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260810093725/image2_0d8ba5-e1786379857586.png?w=1000" class="postimages" width="1000" height="580" alt="Screenshot of the MCP Server Allowlist interface displaying four available TimeZoneMCP tools to select." />
			  </span>
			</p>
<h3><span style="font-weight: 400">Add tools to allowlist</span></h3>
<p><span style="font-weight: 400">After discovery, Salesforce displays the four timezone tools. </span><b>Select all four</b><span style="font-weight: 400"> and click </span><b>Add to Allowlist</b><span style="font-weight: 400">. This makes them available for use in Agent Script.</span></p>
<h2><span style="font-weight: 400">Agentforce integration: Invoking MCP tools via JSON-RPC</span></h2>
<p><span style="font-weight: 400">With tools registered, we can now configure an Agentforce agent to call them. This happens in </span><b>Agent Script</b><span style="font-weight: 400">, the YAML-based DSL that defines agent behavior.</span></p>
<h3><span style="font-weight: 400">Incorporating MCP actions into Agent Script</span></h3>
<p><span style="font-weight: 400">Once imported, your MCP agents become available within the Asset library, allowing you to select the tool and add it directly to the subagent&#8217;s action.</span></p>
<ol>
<li style="font-weight: 400"><span style="font-weight: 400">Navigate to </span><b>Agent Studio</b><span style="font-weight: 400">.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Click </span><b>New Agent</b><span style="font-weight: 400"> and select </span><b>Agentforce Employee Agent</b><span style="font-weight: 400">.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Name your agent “Time Zone Assistant” and keep the default developer name.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Switch to </span><b>Canvas View</b><span style="font-weight: 400">.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">In the subagent section, click the </span><b>+</b><span style="font-weight: 400"><span style="font-weight: 400"> button to create a new subagent named “Time Zone Expert”.<br />
</span></span>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206820" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260810093813/image7-e1786379905796.png?w=1000" class="postimages" width="1000" height="400" alt="Screenshot of the &quot;Add Subagent&quot; modal." />
			  </span>
			</li>
<li style="font-weight: 400"><span style="font-weight: 400">Configure the subagent:</span>
<ol>
<li style="font-weight: 400"><b>Description</b><span style="font-weight: 400">: “Help users with Time Zone conversions and related questions.”</span></li>
<li style="font-weight: 400"><b>Reasoning Instructions</b><span style="font-weight: 400">: “Leverage available tools to assist users with timezone conversions and related inquiries.”</span></li>
</ol>
</li>
<li style="font-weight: 400"><span style="font-weight: 400">Click </span><b>Select Action</b><span style="font-weight: 400"> and choose </span><b>Add from Asset Library</b><span style="font-weight: 400"><span style="font-weight: 400"> to import your registered Timezone tools.<br />
</span></span>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206821" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260810093859/image5_8ab023.png?w=702" class="postimages" width="702" height="764" alt="Screenshot of the expanded &quot;Select action&quot; dropdown menu." />
			  </span>
			</li>
<li style="font-weight: 400"><span style="font-weight: 400">Select the Time Zone MCP tools and click </span><b>Add to Agent</b><span style="font-weight: 400">.<br />

			  <span class="postimagessection_specify alignnone size-medium wp-image-206822" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260810093939/image1_50ff8f-e1786379990817.png?w=1000" class="postimages" width="1000" height="975" alt="Screenshot of the Asset Library displaying available Time Zone MCP tools to select." />
			  </span>
			<br />
</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Choose Review and Validate: verify that the subagent properly displays the new actions in its configuration panel.<br />

			  <span class="postimagessection_specify alignnone size-medium wp-image-206823" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260810094024/image6-e1786380035442.png?w=1000" class="postimages" width="1000" height="748" alt="Screenshot of the Agentforce Studio UI showing the Time Zone Expert Sub-Agent configuration and a list of available timezone actions." />
			  </span>
			<br />
</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Click </span><b>Save</b><span style="font-weight: 400">, then click </span><b>Commit Version &amp; Activate</b><span style="font-weight: 400">.</span></li>
<li style="font-weight: 400"><span style="font-weight: 400">Navigate to </span><b>Preview</b><span style="font-weight: 400"> and test the setup by asking: &#8220;What is the current time in New Delhi?&#8221;</span></li>
</ol>
<h3><span style="font-weight: 400">How RPC calls flow from agent to MCP server</span></h3>
<p><span style="font-weight: 400">When a user asks &#8220;What time is it in Tokyo?&#8221;, here&#8217;s the execution flow:</span></p>
<ol>
<li style="font-weight: 400"><b>User input parsing</b><span style="font-weight: 400">: The agent&#8217;s reasoning model extracts city = &#8220;Tokyo&#8221; from natural language</span></li>
<li style="font-weight: 400"><b>Action selection</b><span style="font-weight: 400">: <span>The </span><code>@subagent.Timezone</code><span> reasoning determines the </span><code>get_current_time_action</code><span> should be called</span></span></li>
<li style="font-weight: 400"><b>Target resolution</b><span style="font-weight: 400">: <span>Salesforce looks up the</span><code> GenAiFunction</code><span> with </span><code>DeveloperName</code></span></li>
<li style="font-weight: 400"><b>Token acquisition</b><span style="font-weight: 400">: Salesforce calls the MCP server&#8217;s token endpoint to get a Bearer token (cached for subsequent calls)</span></li>
<li style="font-weight: 400"><b>JSON-RPC invocation</b><span style="font-weight: 400"><span style="font-weight: 400">: Salesforce constructs and sends the following:<br />
</span></span></p>
<pre language="json">{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_current_time",
    "arguments": {
      "city": "Tokyo"
    }
  }
}
</pre>
<p><span style="font-weight: 400"></span></li>
<li style="font-weight: 400"><b>MCP server processing</b><span style="font-weight: 400"><span style="font-weight: 400">: The Mule flow validates the token, routes to the timezone logic flow, and returns the following:<br />
</span></span></p>
<pre language="json">{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Wednesday, July 3, 2026 12:40:30 AM JST (Asia/Tokyo)"
      }
    ]
  }
}
</pre>
<p><span style="font-weight: 400"></span></li>
<li style="font-weight: 400"><b>Agent response</b><span style="font-weight: 400">: The agent receives the formatted time and responds: &#8220;</span><span style="font-weight: 400">The current time in Tokyo is Friday, July 3, 2026, 12:40 AM JST (Japan Standard Time).</span><span style="font-weight: 400">&#8221;<br />
</span>
			  <span class="postimagessection_specify alignnone size-medium wp-image-206824" >
			    <img loading="lazy" decoding="async" src="https://d259t2jj6zp7qm.cloudfront.net/images/20260810094110/image4_4b88bc-e1786380081794.png?w=1000" class="postimages" width="1000" height="860" alt="Screenshot of the Agentforce Preview Screen displaying a Time Zone Assistant chat alongside its detailed execution trace." />
			  </span>
			</li>
</ol>
<p><span style="font-weight: 400">The entire exchange happens over HTTP — no Apex, no custom callouts, no manual credential management. Salesforce handles token refresh, retries, and error handling automatically.</span></p>
<h2><span style="font-weight: 400">Conclusion</span></h2>
<p><span style="font-weight: 400">By implementing MCP over MuleSoft and connecting it to Agentforce, you&#8217;ve created a reusable, OAuth-secured tool server that any MCP-compatible agent can call. This same pattern applies to real-time inventory queries, shipping label generation, knowledge base retrieval, and multi-step external workflows.</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://modelcontextprotocol.io/docs/getting-started/intro"><span style="font-weight: 400">Model Context Protocol (MCP)</span></a></li>
<li style="font-weight: 400"><span style="font-weight: 400">Documentation: </span><a href="https://help.salesforce.com/s/articleView?id=ai.agent_mcp.htm&amp;type=5"><span style="font-weight: 400">MCP for Agentforce</span></a></li>
</ul>
<h2><span style="font-weight: 400">About the authors</span></h2>
<p><b>Parvinder Singh </b><span style="font-weight: 400">is a Senior Forward Deployed Engineer at Salesforce with deep expertise in Salesforce and Agentforce, specializing in building intelligent, customized agent experiences for enterprise customers. He is passionate about sharing developer insights with the community and bringing practical, field-tested patterns to life through hands-on content.</span><span style="font-weight: 400"><br />
</span><span style="font-weight: 400"><br />
</span><b>Alex Martinez</b><span style="font-weight: 400"> was part of the MuleSoft Community before joining MuleSoft as a Developer Advocate. She founded ProstDev to help other professionals learn more about content creation. In her free time, you’ll find Alex playing Nintendo or PlayStation games and writing reviews about them. Follow Alex on </span><a href="https://www.linkedin.com/in/alexandra-n-martinez/"><span style="font-weight: 400">LinkedIn</span></a><span style="font-weight: 400"> or in the </span><a href="https://www.salesforce.com/trailblazer/devalexmartinez"><span style="font-weight: 400">Trailblazer Community</span></a><span style="font-weight: 400">.</span></p>
<ul></ul>
<ol></ol>
<p>The post <a href="https://developer.salesforce.com/blogs/2026/08/extending-agentforce-with-external-mcp-tools-via-mulesoft">Extending Agentforce with External MCP Tools via MuleSoft</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/08/extending-agentforce-with-external-mcp-tools-via-mulesoft/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">206817</post-id><media:thumbnail url="https://d259t2jj6zp7qm.cloudfront.net/images/20260810101459/DoubleHeadshot-6-e1786651404985.png?w=1000" />
<media:content url="https://d259t2jj6zp7qm.cloudfront.net/images/20260810101459/DoubleHeadshot-6-e1786651404985.png?w=1000" medium="image" />
	</item>
	</channel>
</rss>
