{"id":80539,"date":"2026-07-08T21:35:22","date_gmt":"2026-07-08T16:05:22","guid":{"rendered":"https:\/\/www.tothenew.com\/blog\/?p=80539"},"modified":"2026-07-17T07:51:58","modified_gmt":"2026-07-17T02:21:58","slug":"adobe-and-gen-ai-part-2-local-mcp-servers-for-aem-development","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/adobe-and-gen-ai-part-2-local-mcp-servers-for-aem-development\/","title":{"rendered":"Adobe and Gen AI \u2013 Part 2: Local MCP Servers for AEM Development"},"content":{"rendered":"<h2>Introduction<\/h2>\n<p>In <a href=\"https:\/\/www.tothenew.com\/blog\/adobe-gen-ai-part-1-getting-started-with-adobe-skills\/\" target=\"_blank\" rel=\"noopener\">Part 1<\/a> of this series, we looked at Adobe Skills. Skills teach AI coding assistants Adobe&#8217;s recommended way of doing things.<\/p>\n<p>Skills tell the assistant how to do something. But on their own, they do not know what is happening in your running AEM instance right now. They do not know which bundle is stuck, what the last few requests looked like, or why a page is not caching. That is where Model Context Protocol (MCP) comes in.<\/p>\n<p>In this part, we will look at how Adobe uses MCP to give AI coding assistants, like Cursor and Claude Code, live visibility into your local AEM and Dispatcher environments.<\/p>\n<p>&nbsp;<\/p>\n<h2>AEM Quickstart MCP Server<\/h2>\n<p>MCP, or Model Context Protocol, is an open standard that lets an AI assistant talk to external tools and services. Instead of relying only on the chat history or the file open in your editor, the assistant can call a tool and pull in real information: log entries, running service status, API responses, config files. This is the same thing a developer would do by checking a log file or hitting an endpoint. The assistant just does it as part of answering your question.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\" wp-image-80523\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2026\/07\/generic-mcp-architecture.png\" alt=\"generic-mcp-architecture\" width=\"823\" height=\"242\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2026\/07\/generic-mcp-architecture.png 680w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/generic-mcp-architecture-300x88.png 300w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/generic-mcp-architecture-624x184.png 624w\" sizes=\"(max-width: 823px) 100vw, 823px\" \/><\/p>\n<p>Adobe provides an MCP server for local AEM SDK (Valid for AEM as a cloud) development. Once it is connected, your AI assistant can look directly at your running Author or Publish instance, instead of relying only on the code you paste into the chat.<\/p>\n<h3>Prerequisites<\/h3>\n<ul>\n<li>Validated with AEM SDK 2026.2.24678.20260226T154829Z-260200 and newer.<\/li>\n<li>A running local AEM Author and\/or Publish instance.<\/li>\n<li>Install the <a href=\"https:\/\/experience.adobe.com\/#\/downloads\/content\/software-distribution\/en\/aemcloud.html?fulltext=mcp*&amp;1_group.propertyvalues.property=.%2Fjcr%3Acontent%2Fmetadata%2Fdc%3AsoftwareType&amp;1_group.propertyvalues.operation=equals&amp;1_group.propertyvalues.0_values=software-type%3Atooling&amp;orderby=%40jcr%3Acontent%2Fjcr%3AlastModified&amp;orderby.sort=desc&amp;layout=list&amp;p.offset=0&amp;p.limit=3\" target=\"_blank\" rel=\"noopener\">AEM CQ Quickstart MCP Server v0.1.6 package<\/a> through CRX Package Manager.<\/li>\n<li>The config below assumes Author runs on the default port 4502, and Publish runs on the default port 4503. If your local instances use different ports, update the URLs.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h2>Configure the MCP Server<\/h2>\n<p>Add the following to the MCP config file of your agentic IDE or tool, for example Cursor&#8217;s mcp.json or Claude Code&#8217;s MCP settings.<\/p>\n<h3>Author<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" class=\" wp-image-80549\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2026\/07\/Screenshot-2026-07-09-at-1.42.26\u202fAM.png\" alt=\"author-mcp-config\" width=\"545\" height=\"271\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2026\/07\/Screenshot-2026-07-09-at-1.42.26\u202fAM.png 1326w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/Screenshot-2026-07-09-at-1.42.26\u202fAM-300x149.png 300w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/Screenshot-2026-07-09-at-1.42.26\u202fAM-1024x508.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/Screenshot-2026-07-09-at-1.42.26\u202fAM-768x381.png 768w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/Screenshot-2026-07-09-at-1.42.26\u202fAM-624x310.png 624w\" sizes=\"(max-width: 545px) 100vw, 545px\" \/><\/p>\n<h3>Publish<\/h3>\n<p><img decoding=\"async\" loading=\"lazy\" class=\" wp-image-80551\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2026\/07\/Screenshot-2026-07-09-at-1.44.38\u202fAM.png\" alt=\"mcp-publish-config\" width=\"554\" height=\"295\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2026\/07\/Screenshot-2026-07-09-at-1.44.38\u202fAM.png 1326w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/Screenshot-2026-07-09-at-1.44.38\u202fAM-300x160.png 300w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/Screenshot-2026-07-09-at-1.44.38\u202fAM-1024x545.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/Screenshot-2026-07-09-at-1.44.38\u202fAM-768x409.png 768w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/Screenshot-2026-07-09-at-1.44.38\u202fAM-624x332.png 624w\" sizes=\"(max-width: 554px) 100vw, 554px\" \/><\/p>\n<p>Reconnect the MCP servers from Cursor or Claude Code after you save the config.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\" wp-image-80519\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2026\/07\/aem-mcp.png\" alt=\"aem-mcp\" width=\"753\" height=\"256\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2026\/07\/aem-mcp.png 512w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/aem-mcp-300x102.png 300w\" sizes=\"(max-width: 753px) 100vw, 753px\" \/><\/p>\n<h2>Available Tools<\/h2>\n<table style=\"border-style: solid; border-color: #000000;\" border=\"1\" cellpadding=\"8\">\n<thead>\n<tr>\n<th style=\"width: 320px;\">Tool<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>\u00a0 logs<\/strong><\/td>\n<td>Pulls AEM and OSGi log entries. You can filter by regex, log level, and entry count.<\/td>\n<\/tr>\n<tr>\n<td><strong>\u00a0 diagnose-osgi-bundle<\/strong><\/td>\n<td>Checks why an OSGi bundle or DS component will not start. Reports missing packages, unsatisfied references, and config issues.<\/td>\n<\/tr>\n<tr>\n<td><strong>\u00a0 recent-requests<\/strong><\/td>\n<td>Returns recent HTTP requests, with Sling resource resolution, script resolution, and filter chain details.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<h2>A realistic example<\/h2>\n<p>Say your local AEM author instance is not coming up, or a component just isn&#8217;t showing in the dialog and you can&#8217;t tell if it&#8217;s a startup problem. You ask:<\/p>\n<blockquote><p><em>&#8220;My AEM author is not up. Can you check why?&#8221;<\/em><\/p><\/blockquote>\n<p>That triggers two tool calls. <strong>logs<\/strong> pulls the recent ERROR-level entries first, then <strong>diagnose-osgi-bundle<\/strong> runs an OSGi diagnostic pass. In one run against a local instance, that second call flagged ten problematic bundles in one shot, something that would have taken a fair bit of clicking through the Felix console to find manually. From there, the assistant can point at the specific dependency chain that&#8217;s broken instead of just listing bundle names.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\" wp-image-80518\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2026\/07\/aem-mcp-triggered.png\" alt=\"aem-mcp-triggered\" width=\"589\" height=\"596\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2026\/07\/aem-mcp-triggered.png 506w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/aem-mcp-triggered-296x300.png 296w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/aem-mcp-triggered-120x120.png 120w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/aem-mcp-triggered-24x24.png 24w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/aem-mcp-triggered-48x48.png 48w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/aem-mcp-triggered-96x96.png 96w\" sizes=\"(max-width: 589px) 100vw, 589px\" \/><\/p>\n<p>Other prompts that work well:<\/p>\n<ul>\n<li><em>&#8220;Show me ERROR logs from the last 100 entries.&#8221;<\/em><\/li>\n<li><em>&#8220;Analyze requests for \/content\/we-retail.&#8221;<\/em><\/li>\n<li><em>&#8220;Why is this servlet not resolving?&#8221;<\/em><\/li>\n<li><em>&#8220;Help me identify the cause of this 500 response.&#8221;<\/em><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h2>Dispatcher MCP Server<\/h2>\n<p>Adobe also provides an MCP server for Dispatcher development. It lets the assistant validate configs, check cache behaviour, analyse requests, and troubleshoot Dispatcher directly.<\/p>\n<h2>Packages<\/h2>\n<ul>\n<li>Mac\/Unix &#8211; <a href=\"https:\/\/experience.adobe.com\/#\/downloads\/content\/software-distribution\/en\/aemcloud.html?fulltext=mcp*&amp;1_group.propertyvalues.property=.%2Fjcr%3Acontent%2Fmetadata%2Fdc%3AsoftwareType&amp;1_group.propertyvalues.operation=equals&amp;1_group.propertyvalues.0_values=software-type%3Atooling&amp;orderby=%40jcr%3Acontent%2Fjcr%3AlastModified&amp;orderby.sort=desc&amp;layout=list&amp;p.offset=0&amp;p.limit=3\" target=\"_blank\" rel=\"noopener\">AEM Dispatcher Tools for Unix\/Mac with MCP Server v2.0.269.1 (Beta)<\/a><\/li>\n<li>Windows &#8211; <a href=\"https:\/\/experience.adobe.com\/#\/downloads\/content\/software-distribution\/en\/aemcloud.html?fulltext=mcp*&amp;1_group.propertyvalues.property=.%2Fjcr%3Acontent%2Fmetadata%2Fdc%3AsoftwareType&amp;1_group.propertyvalues.operation=equals&amp;1_group.propertyvalues.0_values=software-type%3Atooling&amp;orderby=%40jcr%3Acontent%2Fjcr%3AlastModified&amp;orderby.sort=desc&amp;layout=list&amp;p.offset=0&amp;p.limit=3\" target=\"_blank\" rel=\"noopener\">AEM Dispatcher Tools for Windows with MCP Server v2.0.269.1 (Beta)<\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h2>Installation (macOS)<\/h2>\n<hr \/>\n<p>chmod +x aem-sdk-dispatcher-tools-&lt;version&gt;-unix.sh<br \/>\n.\/aem-sdk-dispatcher-tools-&lt;version&gt;-unix.sh<\/p>\n<p>cd dispatcher-sdk-&lt;version&gt;<br \/>\nchmod +x .\/bin\/docker_run_mcp.sh<br \/>\n.\/bin\/docker_run_mcp.sh test<\/p>\n<hr \/>\n<p>Make sure Docker Desktop is running before you run this.<\/p>\n<h2><\/h2>\n<h2>Configure Dispatcher MCP<\/h2>\n<p>Add the following to the same MCP config file in your agentic IDE or tool.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\" wp-image-80557\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2026\/07\/Screenshot-2026-07-09-at-2.03.34\u202fAM.png\" alt=\"dispatcher-mcp-config\" width=\"578\" height=\"373\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2026\/07\/Screenshot-2026-07-09-at-2.03.34\u202fAM.png 1398w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/Screenshot-2026-07-09-at-2.03.34\u202fAM-300x194.png 300w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/Screenshot-2026-07-09-at-2.03.34\u202fAM-1024x661.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/Screenshot-2026-07-09-at-2.03.34\u202fAM-768x496.png 768w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/Screenshot-2026-07-09-at-2.03.34\u202fAM-624x403.png 624w\" sizes=\"(max-width: 578px) 100vw, 578px\" \/><\/p>\n<p>Reconnect the MCP server after you save the config.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\" wp-image-80521\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2026\/07\/dispatcher-mcp.png\" alt=\"dispatcher-mcp\" width=\"552\" height=\"346\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2026\/07\/dispatcher-mcp.png 512w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/dispatcher-mcp-300x188.png 300w\" sizes=\"(max-width: 552px) 100vw, 552px\" \/><\/p>\n<h2>Available Tools<\/h2>\n<table style=\"border-style: solid; border-color: #000000;\" border=\"1\" cellpadding=\"8\">\n<thead>\n<tr>\n<th style=\"width: 320px;\">Tool<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>\u00a0validate<\/strong><\/td>\n<td>Validates Dispatcher and Apache HTTPD configuration.<\/td>\n<\/tr>\n<tr>\n<td><strong>\u00a0lint<\/strong><\/td>\n<td>Runs static analysis and checks best practices.<\/td>\n<\/tr>\n<tr>\n<td><strong>\u00a0sdk<\/strong><\/td>\n<td>Runs Dispatcher SDK workflows, such as validate, docker-test, and check-files.<\/td>\n<\/tr>\n<tr>\n<td><strong>\u00a0trace_request<\/strong><\/td>\n<td>Traces how Dispatcher processes a request.<\/td>\n<\/tr>\n<tr>\n<td><strong>\u00a0inspect_cache<\/strong><\/td>\n<td>Checks Dispatcher cache behavior for a given URL.<\/td>\n<\/tr>\n<tr>\n<td><strong>\u00a0monitor_metrics<\/strong><\/td>\n<td>Reads runtime metrics from Dispatcher and HTTPD logs.<\/td>\n<\/tr>\n<tr>\n<td><strong>\u00a0tail_logs<\/strong><\/td>\n<td>Streams Dispatcher and Apache logs.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<h2>A realistic example<\/h2>\n<p>Caching issues are usually the annoying kind: nothing throws an error, the page just keeps hitting Publish when it shouldn&#8217;t. You&#8217;d normally start diffing <strong>.any<\/strong> files by hand to figure out which rule is catching the request. Instead, try:<\/p>\n<blockquote><p><em>&#8220;Debug why dispatcher caching is not working for \/content\/we-retail.&#8221;<\/em><\/p><\/blockquote>\n<p>The assistant investigates the caching configuration and traces the request through <strong>inspect_cache<\/strong>, checking the rules for that exact path. Because the tool call is scoped to the URL you gave it, the answer comes back specific to that page rather than a generic rundown of your whole dispatcher config. In practice this usually turns out to be something like a <strong>no_cache<\/strong> rule that matches too broadly, or a query string that&#8217;s disabling the cache under your current setup, and you get told which one it is.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\" wp-image-80520\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2026\/07\/dispatcher-mcp-triggered.png\" alt=\"dispatcher-mcp-triggered\" width=\"578\" height=\"306\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2026\/07\/dispatcher-mcp-triggered.png 512w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/dispatcher-mcp-triggered-300x159.png 300w\" sizes=\"(max-width: 578px) 100vw, 578px\" \/><\/p>\n<p>Other prompts that work well:<\/p>\n<ul>\n<li><em>&#8220;Validate my Dispatcher configuration.&#8221;<\/em><\/li>\n<li><em>&#8220;Trace the request for \/content\/we-retail\/en.html.&#8221;<\/em><\/li>\n<li><em>&#8220;Review my rewrite rules.&#8221;<\/em><\/li>\n<li><em>&#8220;Show Dispatcher errors from the last five minutes.&#8221;<\/em><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h2>How Adobe Skills and MCP Work Together<\/h2>\n<p>Skills and MCP solve two different problems. They come together on a single prompt:<\/p>\n<blockquote><p><strong>User prompt \u2192 Adobe Skill selected \u2192 MCP tool invoked \u2192 runtime data retrieved \u2192 AI generates response<\/strong><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\" wp-image-80522\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2026\/07\/aem-mcp-architecture-v2.png\" alt=\"aem-mcp-architecture-v2\" width=\"803\" height=\"378\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2026\/07\/aem-mcp-architecture-v2.png 680w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/aem-mcp-architecture-v2-300x141.png 300w, \/blog\/wp-ttn-blog\/uploads\/2026\/07\/aem-mcp-architecture-v2-624x294.png 624w\" sizes=\"(max-width: 803px) 100vw, 803px\" \/><\/p><\/blockquote>\n<p>For example, say you ask the assistant to debug a failing workflow. It can use the <strong>aem-workflow<\/strong> skill from <a href=\"https:\/\/www.tothenew.com\/blog\/adobe-gen-ai-part-1-getting-started-with-adobe-skills\/\">Part 1<\/a> to understand how AEM workflows are built, while pulling the actual failure straight from logs through MCP. The skill supplies the domain knowledge, MCP supplies the live evidence, and you need both. We&#8217;ve found a skill without MCP tends to guess at your environment, confidently, and a bit wrongly. MCP without a skill just hands you raw log data with no AEM-specific read on what it means.<\/p>\n<h2>Conclusion<\/h2>\n<p>Whether you are chasing an OSGi bundle, reviewing logs, checking a Dispatcher config, or tracing a request, MCP turns your AI assistant into something that can actually look at your project, not just talk about it in general terms.<\/p>\n<p>If you have not read <a href=\"https:\/\/www.tothenew.com\/blog\/adobe-gen-ai-part-1-getting-started-with-adobe-skills\/\"><strong>Part 1: Adobe Skills for AI Coding Assistants<\/strong><\/a>, start there before you set up these MCP servers. Together, the two parts cover the foundation for AI-assisted AEM development.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction In Part 1 of this series, we looked at Adobe Skills. Skills teach AI coding assistants Adobe&#8217;s recommended way of doing things. Skills tell the assistant how to do something. But on their own, they do not know what is happening in your running AEM instance right now. They do not know which bundle [&hellip;]<\/p>\n","protected":false},"author":1362,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":14},"categories":[5868],"tags":[1522,5314,8672,4847,8678,7392,8702,1233,5733,8703,7637,8241],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/80539"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/1362"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=80539"}],"version-history":[{"count":16,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/80539\/revisions"}],"predecessor-version":[{"id":80707,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/80539\/revisions\/80707"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=80539"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=80539"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=80539"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}