[{"data":1,"prerenderedAt":615},["ShallowReactive",2],{"bootstrap":3,"blog-agentic-workers-for-commerce-operations-poc":277},{"navigation":4,"globalConfig":196,"forms":218},{"headerSections":5,"headerFooterLinks":67,"footer":76,"legalLinks":153,"socialLinks":176},[6,39,44,50,57,62],{"hasSubMenu":7,"title":8,"links":9,"columns":38},true,"Product",[10,20,26,32],{"showTag":11,"_modelApiKey":12,"text":13,"subtitle":14,"icon":15,"isExternal":11,"link":16,"openForm":11},false,"navigation_link","Universal checkout","Sell anywhere","globe-simple",{"_modelApiKey":17,"slug":18,"title":19},"page","universal-checkout","Universal Checkout",{"showTag":11,"_modelApiKey":12,"text":21,"subtitle":22,"icon":23,"isExternal":11,"link":24,"openForm":11},"Distributed OMS","Manage orders","package",{"_modelApiKey":17,"slug":25,"title":21},"distributed-oms",{"showTag":11,"_modelApiKey":12,"text":27,"subtitle":28,"icon":29,"isExternal":11,"link":30,"openForm":11},"Promotion engine","Automated discounts","seal-percent",{"_modelApiKey":17,"slug":31,"title":27},"promotion-engine",{"showTag":11,"_modelApiKey":12,"text":33,"subtitle":34,"icon":35,"isExternal":11,"link":36,"openForm":11},"POS system","Operate stores","devices",{"_modelApiKey":17,"slug":37,"title":33},"pos-system",2,{"hasSubMenu":11,"showTag":11,"_modelApiKey":12,"text":40,"isExternal":11,"link":41,"openForm":11,"title":40},"Pricing",{"_modelApiKey":42,"slug":43},"pricing_page","pricing",{"hasSubMenu":11,"showTag":11,"_modelApiKey":12,"text":45,"isExternal":11,"link":46,"openForm":11,"title":45},"Customers",{"_modelApiKey":47,"slug":48,"title":49},"customer_landing_page","customers","Customers page",{"hasSubMenu":11,"showTag":11,"_modelApiKey":12,"text":51,"isExternal":11,"link":52,"openForm":11,"form":54,"title":51},"Partners",{"_modelApiKey":17,"slug":53,"title":51},"partners",{"_modelApiKey":55,"slug":53,"name":56},"form","PartnersForm",{"hasSubMenu":11,"showTag":11,"_modelApiKey":12,"text":58,"label":59,"isExternal":7,"url":60,"openForm":11,"title":61},"Docs Hub","Learn more","https:\u002F\u002Fdocs.commercelayer.io\u002F","Docs",{"hasSubMenu":11,"showTag":11,"_modelApiKey":12,"text":63,"isExternal":11,"link":64,"openForm":11,"title":63},"Blog",{"_modelApiKey":65,"slug":66},"blog_landing_page","blog",[68,72],{"text":69,"link":70},"Sign in",{"_modelApiKey":12,"text":69,"isExternal":7,"url":71,"openForm":11},"https:\u002F\u002Fdashboard.commercelayer.io\u002Fsign_in",{"text":73,"link":74},"Sign up for free",{"_modelApiKey":12,"text":73,"isExternal":7,"url":75,"openForm":11},"https:\u002F\u002Fdashboard.commercelayer.io\u002Fsign_up",[77,89,109,132],{"hasSubMenu":7,"title":8,"links":78},[79,81,83,85,87],{"showTag":11,"_modelApiKey":12,"text":13,"subtitle":14,"icon":15,"isExternal":11,"link":80,"openForm":11},{"_modelApiKey":17,"slug":18,"title":19},{"showTag":11,"_modelApiKey":12,"text":21,"subtitle":22,"icon":23,"isExternal":11,"link":82,"openForm":11},{"_modelApiKey":17,"slug":25,"title":21},{"showTag":11,"_modelApiKey":12,"text":27,"subtitle":28,"icon":29,"isExternal":11,"link":84,"openForm":11},{"_modelApiKey":17,"slug":31,"title":27},{"showTag":11,"_modelApiKey":12,"text":33,"subtitle":34,"icon":35,"isExternal":11,"link":86,"openForm":11},{"_modelApiKey":17,"slug":37,"title":33},{"showTag":11,"_modelApiKey":12,"text":40,"isExternal":11,"link":88,"openForm":11},{"_modelApiKey":42,"slug":43},{"hasSubMenu":7,"title":90,"links":91},"Resources",[92,94,99,104,107],{"showTag":11,"_modelApiKey":12,"text":93,"isExternal":7,"url":60,"openForm":11},"Documentation",{"showTag":11,"_modelApiKey":12,"text":95,"label":95,"isExternal":11,"link":96,"openForm":11},"Agentic Commerce",{"_modelApiKey":17,"slug":97,"title":98},"agentic-commerce-whitepaper","Agentic Commerce Whitepaper",{"showTag":11,"_modelApiKey":12,"text":100,"isExternal":11,"link":101,"openForm":11},"Core concepts",{"_modelApiKey":17,"slug":102,"title":103},"headless-commerce","Headless commerce",{"showTag":11,"_modelApiKey":12,"text":105,"isExternal":7,"url":106,"openForm":11},"Changelog","https:\u002F\u002Fdocs.commercelayer.io\u002Fchangelog\u002F",{"showTag":11,"_modelApiKey":12,"text":63,"isExternal":11,"link":108,"openForm":11},{"_modelApiKey":65,"slug":66},{"hasSubMenu":7,"title":110,"links":111},"Company",[112,116,118,121,126],{"showTag":11,"_modelApiKey":12,"text":113,"isExternal":11,"link":114,"openForm":11},"Vision",{"_modelApiKey":17,"slug":115,"title":113},"vision",{"showTag":11,"_modelApiKey":12,"text":45,"isExternal":11,"link":117,"openForm":11},{"_modelApiKey":47,"slug":48,"title":49},{"showTag":11,"_modelApiKey":12,"text":51,"isExternal":11,"link":119,"openForm":11,"form":120},{"_modelApiKey":17,"slug":53,"title":51},{"_modelApiKey":55,"slug":53,"name":56},{"showTag":11,"_modelApiKey":12,"text":122,"isExternal":11,"link":123,"openForm":11},"Security",{"_modelApiKey":17,"slug":124,"title":125},"security","Security at Commerce Layer",{"showTag":11,"_modelApiKey":12,"text":127,"label":128,"isExternal":11,"openForm":7,"form":129},"Giveback","Giveback program",{"_modelApiKey":55,"slug":130,"name":131},"giveback","GivebackForm",{"hasSubMenu":7,"title":133,"links":134},"Get in touch",[135,140,145,149],{"showTag":11,"_modelApiKey":12,"text":136,"isExternal":11,"openForm":7,"form":137},"Contact",{"_modelApiKey":55,"slug":138,"name":139},"contact","ContactUsForm",{"showTag":11,"_modelApiKey":12,"text":141,"isExternal":11,"openForm":7,"form":142},"Book a demo",{"_modelApiKey":55,"slug":143,"name":144},"demo","RequestDemoForm",{"showTag":11,"_modelApiKey":12,"text":146,"label":147,"isExternal":7,"url":148,"openForm":11},"Support","Email support","mailto:support@commercelayer.io",{"showTag":11,"_modelApiKey":12,"text":150,"label":151,"isExternal":7,"url":152,"openForm":11},"Community","Discord community","https:\u002F\u002Fdiscord.gg\u002Fcommercelayer",{"hasSubMenu":7,"title":154,"links":155},"Legal",[156,161,165,169,173],{"showTag":11,"_modelApiKey":12,"text":157,"label":158,"isExternal":7,"url":159,"openForm":11,"htmlClassNames":160},"Terms","Terms and conditions","\u002Flegal-embed\u002Fterms-of-service","iubenda-nostyle no-brand iubenda-noiframe iubenda-embed",{"showTag":11,"_modelApiKey":12,"text":162,"label":163,"isExternal":7,"url":164,"openForm":11,"htmlClassNames":160},"Privacy","Privacy policy","\u002Flegal-embed\u002Fprivacy-policy",{"showTag":11,"_modelApiKey":12,"text":166,"label":167,"isExternal":7,"url":168,"openForm":11,"htmlClassNames":160},"Cookies","Cookie policy","\u002Flegal-embed\u002Fcookie-policy",{"showTag":11,"_modelApiKey":12,"text":170,"isExternal":7,"url":171,"openForm":11,"htmlClassNames":172},"Notice at collection","#","iubenda-cs-uspr-link",{"showTag":11,"_modelApiKey":12,"text":174,"isExternal":7,"url":171,"openForm":11,"htmlClassNames":175},"Privacy preferences","iubenda-cs-preferences-link",[177,180,184,188,192],{"title":178,"type":179,"url":152,"isExternal":7},"Discord","discord-logo",{"title":181,"type":182,"url":183,"isExternal":7},"Github","github","https:\u002F\u002Fgithub.com\u002Fcommercelayer",{"title":185,"type":186,"url":187,"isExternal":7},"Bluesky","bluesky-logo","https:\u002F\u002Fbsky.app\u002Fprofile\u002Fcommercelayer.io",{"title":189,"type":190,"url":191,"isExternal":7},"X","x-logo","https:\u002F\u002Fx.com\u002Fcommercelayer",{"title":193,"type":194,"url":195,"isExternal":7},"LinkedIn","linkedin","https:\u002F\u002Fwww.linkedin.com\u002Fcompany\u002Fcommerce-layer",{"pagesWithoutCtaPanel":197,"ctaPanel":198,"notification":208,"showApiResponseTime":11,"newsletterSignup":216},[],{"title":199,"subtitle":200,"ctas":201},"Ready to get started?","Discover how we can help your business.",[202,205],{"_modelApiKey":203,"text":204,"isExternal":7,"url":75,"openForm":11},"link","Get started for free",{"_modelApiKey":203,"text":206,"isExternal":11,"openForm":7,"form":207},"Contact us",{"_modelApiKey":55,"slug":138,"name":139},{"showNotification":7,"link":209,"linkText":210,"text":215},{"_modelApiKey":203,"text":210,"isExternal":11,"link":211,"openForm":11},"Read article",{"_modelApiKey":212,"slug":213,"title":214},"blog_post","the-new-payments-api-built-for-how-people-pay-now","The new Payments API. Built for how people pay now.","\u003Cp>The new Payments API. Built for how people pay now.\u003C\u002Fp>\n",{"ctaText":217},"Subscribe",[219,225,229,236,240,246,249,253,261,262,267,272,274],{"_modelApiKey":55,"slug":220,"pardotFormEmbedCode":221,"formEmbedMinHeight":222,"successTitle":223,"successCopy":224},"agentic-commerce","https:\u002F\u002Fcommercelayer.fillout.com\u002Ft\u002F5w4Khwgxr6us?whitepaper=agentic",520,"Thank you for your request!","We’ll be in touch soon to arrange a date and time for your personalized demo.",{"_modelApiKey":55,"slug":226,"pardotFormEmbedCode":227,"formEmbedMinHeight":228,"successTitle":223,"successCopy":224},"shopify","https:\u002F\u002Fform.fillout.com\u002Ft\u002FgVnLSmKZwRus",850,{"_modelApiKey":55,"slug":130,"pardotFormEmbedCode":230,"formEmbedMinHeight":231,"displayTitle":232,"copy":233,"successTitle":234,"successCopy":235},"https:\u002F\u002Fform.fillout.com\u002Ft\u002FmVDF8aAiofus",500,"We give back.","\u003Cp>Part of Commerce Layer&#39;s company ethos is to empathize and support one another: co-workers, customers, and community. We want to do our part to help nonprofit organizations and small businesses who may feel adversely affected by the current global economic climate, and as a result, need in-kind support to reach their customers.\u003C\u002Fp>\n\n\u003Cp>If this general description matches your organization’s needs, please tell us your story by completing the following form so we can consider helping your cause.\u003C\u002Fp>\n","Thank you!","We will contact you soon to learn more about your story.",{"_modelApiKey":55,"slug":237,"pardotFormEmbedCode":227,"formEmbedMinHeight":228,"displayTitle":238,"copy":239},"book-an-onboarding-session","Book an onboarding session","\u003Cp>Schedule some time and our devs will help you set up a Commerce Layer + Sanity store.\u003C\u002Fp>\n",{"_modelApiKey":55,"slug":241,"pardotFormEmbedCode":242,"formEmbedMinHeight":243,"displayTitle":244,"successTitle":234,"successCopy":245},"download-our-whitepaper","https:\u002F\u002Fform.fillout.com\u002Ft\u002F5YPWmy8oT7us?whitepaper=ComposableCommerce",450,"Download our whitepaper.","Check your inbox. You should receive a download link soon.",{"_modelApiKey":55,"slug":247,"pardotFormEmbedCode":248,"formEmbedMinHeight":243,"displayTitle":244,"successTitle":234,"successCopy":245},"download-the-content-and-commerce-whitepaper","https:\u002F\u002Fform.fillout.com\u002Ft\u002F5YPWmy8oT7us?whitepaper=ContentAndCommerce",{"_modelApiKey":55,"slug":250,"pardotFormEmbedCode":251,"formEmbedMinHeight":243,"displayTitle":244,"copy":252,"successTitle":234,"successCopy":245},"whitepaper","https:\u002F\u002Fform.fillout.com\u002Ft\u002F5YPWmy8oT7us?whitepaper=Jamstack","\u003Cp>Commerce Layer is the perfect platform for building commerce on the Jamstack. Convert any design into pixel perfect HTML pages. Connect a best-of-breed headless CMS. Go serverless and forget the hassle of managing complex infrastructures.\u003C\u002Fp>\n",{"_modelApiKey":55,"slug":254,"pardotFormEmbedCode":255,"formEmbedMinHeight":256,"displayTitle":257,"copy":258,"successTitle":259,"successCopy":260},"contact-links","https:\u002F\u002Fform.fillout.com\u002Ft\u002FeWPyhHGHT7us",750,"Contact us.","\u003Cp>Tell us about your project. Our team will reach out to you for a personalized offer.\u003C\u002Fp>\n","Thanks for your message!","We’ll be in touch soon to discuss your project details.",{"_modelApiKey":55,"slug":138,"pardotFormEmbedCode":255,"formEmbedMinHeight":256,"displayTitle":257,"copy":258,"successTitle":259,"successCopy":260},{"_modelApiKey":55,"slug":263,"pardotFormEmbedCode":227,"formEmbedMinHeight":228,"displayTitle":264,"successTitle":265,"successCopy":266},"demo-embed","Want to see it in action? Request a demo.","Thanks for your request!","We’ll be in touch soon to arrange a date and time for your free live demo.",{"_modelApiKey":55,"slug":53,"pardotFormEmbedCode":268,"formEmbedMinHeight":228,"displayTitle":269,"copy":270,"successTitle":234,"successCopy":271},"https:\u002F\u002Fform.fillout.com\u002Ft\u002F9MTkDWMUSqus","Become our partner.","\u003Cp>Join us and get our guidance in helping your clients succeed. Our partners are our ambassadors. We are committed to your success as much as you are.\u003C\u002Fp>\n","We will contact you soon to discuss the details of our partnership.",{"_modelApiKey":55,"slug":273,"pardotFormEmbedCode":268,"formEmbedMinHeight":228,"displayTitle":269,"copy":270,"successTitle":234,"successCopy":271},"partners-embed",{"_modelApiKey":55,"slug":143,"pardotFormEmbedCode":227,"formEmbedMinHeight":228,"displayTitle":275,"copy":276,"successTitle":265,"successCopy":266},"Get a free live demo.","\u003Cp>Get a personalized demo and learn more about what Commerce Layer can do for your company.\u003C\u002Fp>\n",{"_modelApiKey":212,"link":278,"subtitle":283,"date":283,"author":284,"additionalAuthors":294,"icon":295,"abstract":296,"tag":297,"displayTitle":279,"cardRatio":300,"featured":11,"seoMetaTags":301,"layout":365,"blogPostCarousel":303,"_seoMetaTags":576,"authors":610},{"text":279,"isExternal":11,"url":280,"link":281},"Agentic workers for commerce operations: a proof of concept.","",{"_modelApiKey":212,"slug":282},"agentic-workers-for-commerce-operations-poc","September 16, 2026",{"name":285,"picture":286},"Fabrizio Picca",{"url":287,"alt":288,"title":288,"width":289,"height":289,"format":290,"focalPoint":291,"customData":293},"https:\u002F\u002Fwww.datocms-assets.com\u002F35053\u002F1614875259-commercelayeravatarsquare113f26.png","Fabrizio Picca —      Partnerships Manager at Commerce Layer",1280,"png",{"x":292,"y":292},0.5,{},[],"robot","A hands-on look at how AI agents can transform commerce ops using Mastra, MCP, and Commerce Layer’s Stream Hub — automate workflows, reduce errors, and power a new era of intelligent backend systems.",{"color":298,"name":299},"gray","Tutorials","portrait",[302,306,310,313,317,320,323,327,331,335,338,342,346,350,354,357,361],{"attributes":303,"tag":304,"content":305},null,"title","Agentic workers for commerce operations: a proof of concept",{"attributes":307,"tag":309,"content":303},{"property":308,"content":305},"og:title","meta",{"attributes":311,"tag":309,"content":303},{"name":312,"content":305},"twitter:title",{"attributes":314,"tag":309,"content":303},{"name":315,"content":316},"description","Learn how to automate commerce operations with agentic AI workers using Mastra.ai, MCP, and Commerce Layer’s Stream Hub.",{"attributes":318,"tag":309,"content":303},{"property":319,"content":316},"og:description",{"attributes":321,"tag":309,"content":303},{"name":322,"content":316},"twitter:description",{"attributes":324,"tag":309,"content":303},{"property":325,"content":326},"og:image","https:\u002F\u002Fwww.datocms-assets.com\u002F35053\u002F1761314368-agentic-commerce-poc.jpg?auto=format&fit=max&w=1200",{"attributes":328,"tag":309,"content":303},{"property":329,"content":330},"og:image:width","1200",{"attributes":332,"tag":309,"content":303},{"property":333,"content":334},"og:image:height","630",{"attributes":336,"tag":309,"content":303},{"name":337,"content":326},"twitter:image",{"attributes":339,"tag":309,"content":303},{"property":340,"content":341},"og:locale","en",{"attributes":343,"tag":309,"content":303},{"property":344,"content":345},"og:type","article",{"attributes":347,"tag":309,"content":303},{"property":348,"content":349},"og:site_name","Commerce Layer",{"attributes":351,"tag":309,"content":303},{"property":352,"content":353},"article:modified_time","2026-09-16T14:10:54Z",{"attributes":355,"tag":309,"content":303},{"property":356,"content":280},"article:publisher",{"attributes":358,"tag":309,"content":303},{"name":359,"content":360},"twitter:card","summary_large_image",{"attributes":362,"tag":309,"content":303},{"name":363,"content":364},"twitter:site","@commercelayer",[366,371,376,383,386,391,394,397,401,404,407,414,417,422,425,428,438,441,444,449,451,454,457,460,462,465,467,470,472,475,477,480,482,485,488,491,493,496,498,501,504,506,509,511,514,516,519,521,524,532,535,538,541,543,546,548,551,553,556,558,561,563,566,568,571,573],{"_modelApiKey":367,"icon":368,"copy":369,"color":370},"banner","info","\u003Cp>This article was originally published on October 27, 2025. It has recently been updated to reflect the release of the official Commerce Layer Core MCP server, which gives AI agents a native, standardized way to access Commerce Layer APIs.\u003C\u002Fp>\n","red",{"_modelApiKey":372,"copy":373,"listStyle":374,"darkTheme":11,"buttons":375,"color":370,"indent":7},"wysiwyg","\u003Cp>In our recent white paper \u003Cem>Principles of agentic commerce\u003C\u002Fem>, Filippo Conforti, CEO and Co-founder of Commerce Layer, shared our vision for this new frontier of commerce experiences.\u003C\u002Fp>\n","directional",[],{"_modelApiKey":377,"title":378,"preTitle":379,"linkText":380,"darkTheme":11,"link":381},"link_block","Principles of agentic commerce","White paper","Download",{"_modelApiKey":203,"text":380,"label":280,"subtitle":280,"icon":280,"isExternal":11,"url":280,"link":382,"anchor":280,"openForm":11,"form":303,"htmlClassNames":280},{"_modelApiKey":17,"slug":97,"title":98},{"_modelApiKey":372,"copy":384,"listStyle":374,"darkTheme":11,"buttons":385,"color":370,"indent":11},"\u003Cp>In the (very) near future \u003Ca href=\"https:\u002F\u002Fopenai.com\u002Findex\u002Fbuy-it-in-chatgpt\u002F\">as OpenAI itself suggests\u003C\u002Fa>, agents will buy and sell on our behalf, helping us find the best deals and tailoring product recommendations around our behaviors and preferences.\u003C\u002Fp>\n\n\u003Cp>With the recent introduction of the \u003Cstrong>Agentic Commerce Protocol\u003C\u002Fstrong> (\u003Cstrong>ACP\u003C\u002Fstrong>) by OpenAI and Stripe, the horizon for how merchants can engage with customers is rapidly expanding — from conversational shopping experiences within ChatGPT to new, intelligent commerce touchpoints across the web. Yet, the same principles behind ACP extend well beyond customer interactions. Agents can become powerful allies for \u003Cstrong>backend operations\u003C\u002Fstrong>, assisting business users in automating workflows, surfacing insights, and taking action directly on commerce data.\u003C\u002Fp>\n",[],{"_modelApiKey":377,"title":387,"preTitle":388,"linkText":59,"darkTheme":11,"link":389},"Agentic Commerce Protocol","Getting started",{"_modelApiKey":203,"text":59,"label":280,"subtitle":280,"icon":280,"isExternal":7,"url":390,"link":303,"anchor":280,"openForm":11,"form":303,"htmlClassNames":280},"https:\u002F\u002Fdevelopers.openai.com\u002Fcommerce\u002F",{"_modelApiKey":372,"copy":392,"listStyle":374,"darkTheme":11,"buttons":393,"color":370,"indent":11},"\u003Cp>Emerging standards like \u003Cstrong>A2A\u003C\u002Fstrong> (\u003Cstrong>Agent-to-Agent Protocol\u003C\u002Fstrong>, more on this \u003Ca href=\"https:\u002F\u002Fa2aprotocol.ai\u002F\">here\u003C\u002Fa>) and \u003Cstrong>MCP\u003C\u002Fstrong> (\u003Cstrong>Model Context Protocol\u003C\u002Fstrong>, covered later in this article) are setting the foundation for a new level of interoperability — where agents can seamlessly collaborate with each other and connect with legacy systems such as ERPs or CRMs, orchestrating complex workflows with minimal human intervention.\u003C\u002Fp>\n\n\u003Cp>This article presents the results of a proof of concept I’ve been working on over the last few weeks, showing how you can start \u003Cem>today\u003C\u002Fem> bringing AI into your business operations. And of course, Commerce Layer — \u003Cstrong>API-first\u003C\u002Fstrong> since the \u003Ca href=\"\u002Fblog\u002Fwhy-we-created-a-new-ecommerce-platform\">very beginning\u003C\u002Fa> — is the true enabler of this new era of interactions.\u003C\u002Fp>\n",[],{"_modelApiKey":367,"icon":395,"copy":396,"color":370},"lightbulb","\u003Cp>The learnings from this experiment are already inspiring new ideas for how Commerce Layer could make agentic automation more accessible to merchants in the near future.\u003C\u002Fp>\n",{"_modelApiKey":372,"copy":398,"listStyle":399,"darkTheme":11,"buttons":400,"color":370,"indent":11},"\u003Ch3>The business need\u003C\u002Fh3>\n\n\u003Cp>Before diving into the proof of concept, it’s worth stepping back to understand \u003Cem>why\u003C\u002Fem> agentic workers matter for commerce operations. Modern digital commerce teams are already surrounded by data — from orders and inventory to customer interactions — yet much of this information still requires manual supervision, periodic reports, and repetitive interventions. Tasks like reviewing fraudulent orders, reconciling stock levels, or following up on abandoned carts are often handled through rigid workflows or human oversight, making them both time-consuming and error-prone.\u003C\u002Fp>\n\n\u003Cp>Agentic workers offer a new approach. By combining \u003Cstrong>autonomous reasoning\u003C\u002Fstrong> with \u003Cstrong>direct access to APIs and business tools\u003C\u002Fstrong>, agents can continuously monitor operations, detect anomalies, and act on them in real time — without waiting for human input. This doesn’t replace people; it \u003Cem>amplifies\u003C\u002Fem> their capacity to make faster, more informed decisions.\u003C\u002Fp>\n\n\u003Cp>From a business standpoint, this shift has measurable outcomes: reduced operational overhead, faster response times, and more consistent execution across repetitive processes. Over time, those gains compound into tangible ROI — lower costs, fewer errors, and improved customer satisfaction through timely, context-aware interventions.\u003C\u002Fp>\n\n\u003Cp>In this proof of concept, we’ll focus on two concrete examples where agentic workers can already deliver value:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>\u003Cstrong>\u003Cem>Abandoned cart management\u003C\u002Fem>\u003C\u002Fstrong>---Where an agent identifies customers who left items in their carts and triggers timely recovery actions.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>\u003Cem>Early fraud detection\u003C\u002Fem>\u003C\u002Fstrong>---Where an agent monitors incoming orders and flags those that deviate from expected behavior.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>These two scenarios demonstrate how even small, well-scoped agents can make commerce operations more efficient, adaptive, and ultimately more profitable — while keeping human teams focused on strategy rather than supervision.\u003C\u002Fp>\n","checkbox",[],{"_modelApiKey":372,"copy":402,"listStyle":374,"darkTheme":11,"buttons":403,"color":370,"indent":11},"\u003Ch3>Main tools\u003C\u002Fh3>\n\n\u003Cp>Before getting in the details of the implementation let’s first introduce the main actors of this PoC.\u003C\u002Fp>\n\n\u003Ch4>Mastra as the agentic platform\u003C\u002Fh4>\n\n\u003Cp>\u003Ca href=\"http:\u002F\u002Fmastra.ai\">Mastra\u003C\u002Fa> will be our reference platform to build our agents and manage runtime. With its pragmatic approach to agent programming it made very quick and easy to set up agents and wire them with tools, memory, and everything needed in order to build our “automated commerce backend”.\u003C\u002Fp>\n\n\u003Cp>It&#39;s not in the scope of this article to get over the internals of Mastra, but you can find plenty of documentation \u003Ca href=\"https:\u002F\u002Fmastra.ai\u002Fen\u002Fdocs\">on their website\u003C\u002Fa>.\u003C\u002Fp>\n\n\u003Ch4>MCP Server\u003C\u002Fh4>\n\n\u003Cp>There’s plenty of resources on the MCP protocol since it took the stage in every AI-related discussion in the last few months. The full specification can be found \u003Ca href=\"https:\u002F\u002Fmodelcontextprotocol.io\u002Fdocs\u002Fgetting-started\u002Fintro\">here\u003C\u002Fa> along with a lot of interesting and useful resources.\u003C\u002Fp>\n\n\u003Cp>In our case we implemented a couple of tools and made them available through a local MCP server to Mastra-based agents. \u003C\u002Fp>\n\n\u003Cp>These tools give agents the possibility of:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>Searching for orders according to some criteria (time frame, markets).\u003C\u002Fli>\n\u003Cli>Tagging resources according to some logic (i.e. mark a cart as abandoned if some conditions are met).\u003C\u002Fli>\n\u003C\u002Ful>\n",[],{"_modelApiKey":367,"icon":405,"copy":406,"color":370},"book-open-text","\u003Cp>Since this article was published, we&#39;ve released the official Commerce Layer Core MCP server. It gives agents a native, standardized way to access Commerce Layer APIs — no need to build and maintain a custom local implementation like the one described below. \u003Ca href=\"https:\u002F\u002Fdocs.commercelayer.io\u002Fai\u002Fmcp\u002Fservers\u002Fcore\">Check out the documentation\u003C\u002Fa> to get started.\u003C\u002Fp>\n",{"_modelApiKey":377,"title":408,"preTitle":409,"linkText":410,"darkTheme":11,"link":411},"Meet the Commerce Layer Core MCP.","Related article","Read",{"isExternal":11,"link":412},{"_modelApiKey":212,"slug":413},"core-mcp-server",{"_modelApiKey":372,"copy":415,"listStyle":374,"darkTheme":11,"buttons":416,"color":370,"indent":11},"\u003Ch4>Commerce Layer Stream API\u003C\u002Fh4>\n\n\u003Cp>One of the newest released features of our platform. The \u003Ca href=\"https:\u002F\u002Fdocs.commercelayer.io\u002Fcore\u002Fevent-stream-hub\">Stream Hub\u003C\u002Fa> offers a CDC system to capture and  track changes to data instantly. In our PoC, it will be the source of events which agents will act upon, feeding back to the platform via MCP tools and Commerce Layer APIs.\u003C\u002Fp>\n",[],{"_modelApiKey":377,"title":418,"preTitle":409,"linkText":410,"darkTheme":11,"link":419},"Introducing our new event Stream Hub.",{"isExternal":11,"link":420},{"_modelApiKey":212,"slug":421},"introducing-our-new-event-stream-hub",{"_modelApiKey":372,"copy":423,"listStyle":399,"darkTheme":11,"buttons":424,"color":370,"indent":11},"\u003Ch3>PoC scope and architecture\u003C\u002Fh3>\n\n\u003Cp>Now that we introduced the main concepts, let’s dive in the PoC structure.\u003C\u002Fp>\n\n\u003Cp>For this proof of concept we relied on Mastra, a platform that provides a very straightforward development environment for building and running agents. Mastra comes with built-in support for the Model Context Protocol (MCP) and can work with a wide range of LLMs — in our case, we chose \u003Cstrong>OpenAI’s gpt-4o-mini\u003C\u002Fstrong> for its balance between speed and accuracy.\u003C\u002Fp>\n\n\u003Cp>The Mastra server runs locally in our PoC (although a cloud deployment is equally supported) and exposes an SDK that makes it easy to access and orchestrate agents via standard APIs.\u003C\u002Fp>\n\n\u003Cp>To connect Commerce Layer’s real-time data with Mastra, we developed a lightweight \u003Cstrong>Node.js middleware\u003C\u002Fstrong>. This middleware plays a central role in the architecture, acting as a bridge between the two environments. It provides two essential services:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>\u003Cstrong>\u003Cem>Event forwarding from the Stream Hub\u003C\u002Fem>\u003C\u002Fstrong>---The middleware listens to Commerce Layer’s event Stream Hub, captures incoming events (e.g., order updates, SKU changes, customer actions), and forwards them to Mastra through the Mastra SDK. This enables agents to immediately react to live business events.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>\u003Cem>Scheduled agent execution\u003C\u002Fem>\u003C\u002Fstrong>---Not all use cases are event-driven. For scenarios where agents need to run periodically (e.g., nightly audits, inventory reconciliations, abandoned cart checks), the middleware also embeds a scheduler. The scheduler is responsible for “waking up” agents at predefined intervals, ensuring that time-based operations complement the event-driven ones.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>Finally, we added a \u003Cstrong>local MCP server\u003C\u002Fstrong> to equip agents with the tools they need to interact directly with Commerce Layer. Through this MCP integration, agents can not only read data but also perform updates on resources in line with their programmed logic — for example, flagging anomalies, adjusting product tags, or initiating replenishment strategies.\u003C\u002Fp>\n",[],{"_modelApiKey":372,"copy":426,"listStyle":374,"darkTheme":11,"buttons":427,"color":370,"indent":11},"\u003Cp>This layered architecture — \u003Cstrong>Commerce Layer Stream Hub → Node.js middleware → Mastra agents (event-driven or scheduled) → MCP tools\u003C\u002Fstrong> — ensures a clean separation of concerns while giving agents the ability to operate in real time as well as on a scheduled basis.\u003C\u002Fp>\n",[],{"_modelApiKey":429,"border":11,"caption":280,"image":430,"size":437,"darkTheme":11,"rounded":7,"color":370},"image_block",{"url":431,"alt":432,"title":432,"width":433,"height":434,"format":290,"focalPoint":435,"customData":436},"https:\u002F\u002Fwww.datocms-assets.com\u002F35053\u002F1761142429-agentic-poc-diagram.png","Agentic PoC diagram",1920,1363,{"x":292,"y":292},{},"wide",{"_modelApiKey":372,"copy":439,"listStyle":399,"darkTheme":11,"buttons":440,"color":370,"indent":11},"\u003Ch4>The lifecycle of an agentic worker\u003C\u002Fh4>\n\n\u003Cp>Every agent in this proof of concept follows a simple but powerful lifecycle built around four key stages: \u003Cstrong>trigger\u003C\u002Fstrong>, \u003Cstrong>reason\u003C\u002Fstrong>, \u003Cstrong>act\u003C\u002Fstrong>, and \u003Cstrong>learn\u003C\u002Fstrong>.\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>\u003Cstrong>\u003Cem>Trigger\u003C\u002Fem>\u003C\u002Fstrong>---The agent wakes up in response to an external event (for example, an order update or a cart status change) or through a scheduled job.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>\u003Cem>Reason\u003C\u002Fem>\u003C\u002Fstrong>---Using its underlying LLM, the agent interprets the context: it evaluates data, checks business rules, and determines the most appropriate next step.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>\u003Cem>Act\u003C\u002Fem>\u003C\u002Fstrong>---Through the tools exposed via the MCP server, the agent performs concrete actions — querying APIs, updating records, or sending notifications.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>\u003Cem>Learn\u003C\u002Fem>\u003C\u002Fstrong>---Finally, the agent records outcomes and feedback, enabling refinement over time. While in this PoC the learning step is mostly observational, future iterations could include adaptive logic based on performance or user feedback.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>This loop — \u003Cstrong>trigger → reason → act → learn\u003C\u002Fstrong> — makes agentic workers fundamentally different from traditional automation. Instead of executing predefined scripts, they continuously interpret and respond to changing contexts, allowing commerce operations to evolve from static processes into \u003Cstrong>adaptive systems\u003C\u002Fstrong>.\u003C\u002Fp>\n",[],{"_modelApiKey":372,"copy":442,"listStyle":374,"darkTheme":11,"buttons":443,"color":370,"indent":11},"\u003Ch3>Bringing agents to life\u003C\u002Fh3>\n\n\u003Cp>With the architecture in place, the next step was to bring the pieces to life and observe how the system behaves under real conditions. In this section, I’ll walk through the role of each component — from event ingestion to agent execution — showing how they interact in practice. Along the way, I’ll include snippets of the actual code used and highlight some of the outputs, so you can get a concrete sense of how agentic workers can already enhance commerce operations today.\u003C\u002Fp>\n\n\u003Ch4>Middleware implementation\u003C\u002Fh4>\n\n\u003Cp>As already mentioned our middleware is a simple Node.js application. It has two main modules, the \u003Cstrong>streamer\u003C\u002Fstrong> and the \u003Cstrong>scheduler\u003C\u002Fstrong>.\u003C\u002Fp>\n\n\u003Ch5>Streamer\u003C\u002Fh5>\n\n\u003Cp>The streamer connects to Commerce Layer Stream Hub and forward messages to Mastra according to some routing logic contained in a simple router object:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":446,"showLineNumbers":11,"highlightLines":280,"language":447,"size":448},"code_block","const SERVICE_ROUTER = {\n  \"prices\": {\n    \"name\": \"price-auditor\",\n    \"agentId\": \"priceAuditorAgent\"\n  },\n  \"skus\": {\n    \"name\": \"skus-auditor\",\n    \"agentId\": \"skusAuditorAgent\"\n  },\n  \"orders\": {\n    \"name\": \"early-fraud-detector\",\n    \"agentId\": \"earlyFraudDetectionAgent\"\n  }\n}","javascript","Standard",{"_modelApiKey":367,"icon":368,"copy":450,"color":370},"\u003Cp>You will notice that this implementation doesn’t really scale as it allows only one agent per resource type, but a production-ready solution is not the aim of this article.\u003C\u002Fp>\n",{"_modelApiKey":372,"copy":452,"listStyle":374,"darkTheme":11,"buttons":453,"color":370,"indent":11},"\u003Cp>The idea is pretty simple: the streamer will listen for events and when a message update arrives, the streamer will intercept the resource type contained in the event payload, get the destination agent that will receive the event and send it through the Mastra SDK client.\u003C\u002Fp>\n\n\u003Cp>Let’s see how this looks like in the below code snippets:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":455,"showLineNumbers":11,"highlightLines":280,"language":447,"size":456},"const { EventSourcePlus } = require(\"event-source-plus\");\n...\nconst eventSource = new EventSourcePlus(STREAM_API_URL, {\n    headers: {\n      Authorization: \"Bearer \" + token,\n    },\n    retryInterval: 3000,\n    heartbeatTimeout: 45000,\n  });\n\n  eventSource.listen({\n    onMessage(message) {\n      switch (message.event) {\n        case \"update\":\n          handleEvent(JSON.parse(message.data), message.id);\n          break;\n        case \"error\":\n          logger.error(`Error event received: ${message}`);\n          return;\n        default:\n          return;\n      }\n    },\n    onError(err) {\n      logger.error(\"Error:\", err);\n    },\n    onOpen() {\n      logger.info(\"Connection opened\");\n    },\n    onRetrying(count) {\n      logger.info(`Reconnecting... attempt #${count}`);\n    },\n    onClosed() {\n      logger.info(\"Connection closed\");\n    },\n  });","Wide",{"_modelApiKey":372,"copy":458,"listStyle":374,"darkTheme":11,"buttons":459,"color":370,"indent":11},"\u003Cp>As you can see, in our PoC we only manage \u003Ccode>update\u003C\u002Fcode> and \u003Ccode>error\u003C\u002Fcode> messages but \u003Ccode>create\u003C\u002Fcode> and \u003Ccode>delete\u003C\u002Fcode> events can be managed as well.\u003C\u002Fp>\n\n\u003Cp>The \u003Ccode>handleEvent\u003C\u002Fcode> function is in charge of parsing the payload of the received event and pass it to the agent for evaluation using the router object to determine the right destination:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":461,"showLineNumbers":11,"highlightLines":280,"language":447,"size":456},"const { mastraClient } = require(\".\u002Flib\u002Fmastra.js\");\n\n...\n\nfunction handleEvent() {\n\t...\n\ttry {\n\t  const agent = mastraClient.getAgent(\n\t    SERVICE_ROUTER[eventData.resource_type].agentId\n\t  );\n\t  \n\t  ...\n\t  const postData = JSON.stringify(eventData);\n\t  ...\n\t\n\t  const response = await agent.generate({\n\t    messages: [\n\t      {\n\t        role: \"user\",\n\t        content: postData,\n\t      },\n\t    ],\n\t    memory: {\n\t      resource: `memory_${eventData.resource_type}`,\n\t      thread: {\n\t        id: eventData.resource_id,\n\t      },\n\t    },\n\t  });\n\t  logger.info(\n\t    `[${eventId}] Response from ${\n\t      SERVICE_ROUTER[eventData.resource_type].name\n\t    } received: ${response.text}`\n\t  );\n\t} catch (error) {\n\t  logger.error(\n\t    { err: error },\n\t    `[${eventId}] Error posting to ${\n\t      SERVICE_ROUTER[eventData.resource_type].name\n\t    }:`\n\t  );\n\t}\n\t...\n}",{"_modelApiKey":372,"copy":463,"listStyle":374,"darkTheme":11,"buttons":464,"color":370,"indent":11},"\u003Cp>Where \u003Ccode>mastra.js\u003C\u002Fcode> is just a wrapper of the \u003Ca href=\"https:\u002F\u002Fmastra.ai\u002Fen\u002Fdocs\u002Fserver-db\u002Fmastra-client\">Mastra client SDK\u003C\u002Fa>.\u003C\u002Fp>\n\n\u003Cp>The function basically forwards the payload to the agent and wait for a response (for our PoC beside actions performed by agent using MCP tools) we just return a textual response in the middleware logger.\u003C\u002Fp>\n\n\u003Ch5>Scheduler\u003C\u002Fh5>\n\n\u003Cp>The scheduler object has the purpose of &quot;awaking&quot; specific agents according to a schedule (at the moment agents are still not able to trigger themselves!).\u003C\u002Fp>\n\n\u003Cp>The schedule object is pretty simple:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":466,"showLineNumbers":11,"highlightLines":280,"language":447,"size":448},"const AGENT_SCHEDULE = [\n  {\n    \"agent_id\": \"abandoned-cart\",\n    \"schedule\": \"0 *\u002F5 * * * *\",\n    \"enabled\": true,\n    \"params\": {\n      \"lookback_hours\": 24,\n      \"max_orders\": 100\n    }\n  }\n]",{"_modelApiKey":372,"copy":468,"listStyle":374,"darkTheme":11,"buttons":469,"color":370,"indent":11},"\u003Cp>It’s basically an array of objects containing, for each agent we want to be scheduled, the schedule (in \u003Ccode>node-cron\u003C\u002Fcode> format) and some additional parameters. In this case we want the \u003Ccode>abandoned-cart\u003C\u002Fcode> agent to do his thing every 5 minutes. \u003C\u002Fp>\n\n\u003Cp>With this, it’s just a matter of starting the scheduler by reading the schedule object and schedule the trigger operation for each agent at the defined time:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":471,"showLineNumbers":11,"highlightLines":280,"language":447,"size":456},"const schedule = require(\"node-schedule\");\n\n...\n\nfunction startAgentScheduler() {\n  logger.info(\"starting agent scheduler...\");\n  AGENT_SCHEDULE.forEach((agent) => {\n    if (!agent.enabled) return;\n    logger.info(\n      `scheduling agent ${agent.agent_id} with schedule ${\n        agent.schedule\n      } and params ${JSON.stringify(agent.params)}`\n    );\n    schedule.scheduleJob(agent.schedule, () => {\n      triggerAgent(agent.agent_id, agent.params);\n    });\n  });\n}",{"_modelApiKey":372,"copy":473,"listStyle":374,"darkTheme":11,"buttons":474,"color":370,"indent":11},"\u003Cp>At each run the scheduler will just send a &quot;wake up message&quot; to the agent:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":476,"showLineNumbers":11,"highlightLines":280,"language":447,"size":456},"const TRIGGER_EVENT = {\n  event: \"scheduled_trigger\",\n  created_at: new Date().toISOString(),\n};\n\nasync function triggerAgent(agentId, params) {\n  logger.info(\n    `triggering agent ${agentId} with params ${JSON.stringify(params)}`\n  );\n\n  try {\n    const agent = mastraClient.getAgent(agentId);\n\n    const response = await agent.generate({\n      messages: [\n        {\n          role: \"user\",\n          content: TRIGGER_EVENT,\n        },\n      ],\n    });\n    logger.info(\n      `[${eventId}] Response from ${agentId} received: ${response.text}`\n    );\n  } catch (error) {\n    logger.error({ err: error }, `[${eventId}] Error posting to ${agentId}:`);\n  }\n}",{"_modelApiKey":372,"copy":478,"listStyle":374,"darkTheme":11,"buttons":479,"color":370,"indent":11},"\u003Cp>Also in this case what we do is just displaying the textual response of the agent.\u003C\u002Fp>\n\n\u003Cp>One thing to notice is that in the trigger event we always send the \u003Ccode>created_at\u003C\u002Fcode> parameter containing the current timestamp. This is needed as agents lives in a timeless dimension and a date might be needed to query for data (unless, of course, you instruct the agent to get the current time of date via MCP before doing any other operation!).\u003C\u002Fp>\n\n\u003Cp>Let’s pack everything together in an &quot;executable&quot; \u003Ccode>index.js\u003C\u002Fcode> file:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":481,"showLineNumbers":11,"highlightLines":280,"language":447,"size":456},"const args = process.argv.slice(2);\nconst RUN_AGENT_SCHEDULER = args.includes(\"-a\");\nconst RUN_STREAMER = args.includes(\"-s\");\n\nconst { logger } = require(\".\u002Futils\u002Flogging.js\");\nconst { startStreamer } = require(\".\u002Fstreamer.js\");\nconst { startAgentScheduler } = require(\".\u002Fscheduler.js\");\n\n\nif (!(RUN_AGENT_SCHEDULER || RUN_STREAMER )) {\n  logger.info(\"Usage: node index.js [-a] [-s] (at least one required)\");\n  process.exit(1);\n}\n\nif (RUN_STREAMER) {\n  startStreamer();\n}\n\nif (RUN_AGENT_SCHEDULER) {\n  startAgentScheduler();\n}\n",{"_modelApiKey":372,"copy":483,"listStyle":374,"darkTheme":11,"buttons":484,"color":370,"indent":11},"\u003Cp>And let’s give this thing a spin:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":486,"showLineNumbers":11,"highlightLines":280,"language":487,"size":456},"cl-stream-poc % npm run start -- -a -s\n\n> cl-stream-poc@0.0.1 start\n> node src\u002Findex.js -a -s\n\n[2025-10-02 08:26:10] INFO: [1759393570563][30] starting agent scheduler...\n[2025-10-02 08:26:10] INFO: [1759393570563][30] scheduling agent abandoned-cart with schedule 0 *\u002F5 * * * * and params {\"lookback_hours\":24,\"max_orders\":100}\n[2025-10-02 08:26:10] INFO: [1759393570801][30] Obtained token, connecting to stream...","shell",{"_modelApiKey":372,"copy":489,"listStyle":374,"darkTheme":11,"buttons":490,"color":370,"indent":11},"\u003Cp>Great! At this point our middleware is listening and actively triggering our agents!\u003C\u002Fp>\n\n\u003Ch4>MCP tools implementation\u003C\u002Fh4>\n\n\u003Cp>At its core, an agent is more than just a large language model (LLM) generating text. It’s an entity with a defined purpose, equipped with tools and context, that can use the reasoning power of the LLM to decide what to do and then actually carry it out. While an LLM on its own can answer questions, an agent can take action — querying data, updating resources, or triggering workflows — to achieve a specific goal.\u003C\u002Fp>\n\n\u003Cp>MCP was built with the purpose of giving agents a standardised way to access external tools by providing meaningful description of the capabilities and the outcomes.\u003C\u002Fp>\n\n\u003Cp>For this PoC we have the following tools:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>One allowing the agent to tag resources in commerce layer as the result of an evaluation (i.e. marking an order as \u003Ccode>possible_fraud\u003C\u002Fcode>).\u003C\u002Fli>\n\u003Cli>A number of other tools mapping our metrics APIs to get orders according to some filtering criteria.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>For simplicity we will show here only the code for the resource tagging tool:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":492,"showLineNumbers":11,"highlightLines":280,"language":447,"size":456},"import { z } from 'zod';\nimport { errorTextResponse, structuredTextResponse } from '..\u002F..\u002Fmcpc\u002Ftools\u002Fcommon.js';\nimport { callToolResult, getAccessToken } from '..\u002F..\u002Futils\u002Ftools.js';\nimport { CommerceLayer } from '@commercelayer\u002Fsdk';\n\nconst mcpTool = {\n    name: 'tag-resource',\n    description: 'Tags a resource with the specified attributes',\n    inputSchema: {\n        resourceId: z.string().describe('The ID of the resource to be tagged'),\n        resourceType: z.string().describe('The type of resource'),\n        tags: z.array(z.string()).describe('A comma separated list of tags to be associated with the resource, strip spaces')\n    },\n    outputSchema: {\n        success: z.boolean().describe('Indicates if the tagging operation was successful')\n    },\n    callback: async ({ resourceId, tags, resourceType }, { authInfo }) => {\n        const _resourceType = resourceType;\n        let response;\n        try {\n            \u002F\u002F Placeholder for actual implementation\n            console.log(`Tagging ${_resourceType}\u002F${resourceId} with tags: ${tags.join(', ')}`);\n            const accessToken = await getAccessToken();\n            const cl = CommerceLayer({ accessToken });\n            console.log(`tagging resource ${resourceId} with tags: ${tags.join(', ')}`);\n            await cl[_resourceType].update({\n                id: resourceId,\n                _add_tags: tags.join(', ')\n            });\n            response = structuredTextResponse({ success: true });\n        }\n        catch (error) {\n            console.error('Error tagging resource:', error);\n            console.error(`Error tagging resource ${resourceId} with tags: ${tags}`);\n            response = errorTextResponse(String(error.message || error), true);\n        }\n        return callToolResult(response);\n    }\n};\nexport default mcpTool;",{"_modelApiKey":372,"copy":494,"listStyle":374,"darkTheme":11,"buttons":495,"color":370,"indent":11},"\u003Cp>This snippet clearly shows how you can easily define an MCP tool.\u003C\u002Fp>\n\n\u003Cp>First you provide descriptions for the tool itself and the input\u002Foutput schema (using zod for validation). Then you provide the tool logic in the \u003Ccode>callback\u003C\u002Fcode> property. In our case the tool will get a token to interact with Commerce Layer APIs and will then update a resource adding the tags received as inputs. We will see later how all this come together in our PoC.\u003C\u002Fp>\n\n\u003Cp>All the tools are then bundled together into an MCP server:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":497,"showLineNumbers":11,"highlightLines":280,"language":447,"size":456},"#!\u002Fusr\u002Fbin\u002Fenv node\nimport { tools } from '.\u002Ftools\u002Findex.js';\nimport { McpLocalServer } from '..\u002Fserver\u002Flocal.js';\nimport pkg from '..\u002F..\u002Fpackage.json' with { type: 'json' };\nconst server = new McpLocalServer({\n    name: 'commercelayer-metrics',\n    version: pkg.version,\n    title: pkg.description\n});\n\u002F\u002F Register tools\nserver.registerTools(tools);\nvoid server.start().catch((error) => {\n    console.error('Fatal error during server start:', error);\n    process.exit(1);\n});",{"_modelApiKey":367,"icon":499,"copy":500,"color":370},"rocket-launch","\u003Cp>Thanks to the official \u003Ca href=\"https:\u002F\u002Fdocs.commercelayer.io\u002Fai\u002Fmcp\u002Fservers\u002Fcore\">Commerce Layer Core MCP server\u003C\u002Fa>, implementing custom MCP tools like the ones above is no longer necessary for standard commerce operations — they&#39;re already exposed out of the box. This section is kept as a reference for how a custom MCP tool implementation works, and you can still build your own tools if you need functionality beyond what the official server offers.\u003C\u002Fp>\n",{"_modelApiKey":372,"copy":502,"listStyle":399,"darkTheme":11,"buttons":503,"color":370,"indent":11},"\u003Ch4>Agents implementation\u003C\u002Fh4>\n\n\u003Cp>It’s time to give a look at the main characters of our PoC: the agents. In this article we will cover two agents:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>\u003Cstrong>\u003Cem>Abandoned cart detector agent\u003C\u002Fem>\u003C\u002Fstrong>---Runs periodically and scans carts for possible abandoned ones. It uses the update timestamp as the criterion to determine the abandoned status (if it dates back over a specified time, then the cart is considered abandoned).\u003C\u002Fli>\n\u003Cli>\u003Cstrong>\u003Cem>Early fraud detection agent\u003C\u002Fem>\u003C\u002Fstrong>---Acts on the order update status. When the order turns pending, the agent will scan the order history to check orders with the same email but with more than x different shipping addresses.\u003C\u002Fli>\n\u003C\u002Ful>\n",[],{"_modelApiKey":367,"icon":280,"copy":505,"color":370},"\u003Cp>As we said Mastra will be the platform of choice to deploy our agents. It’s important to mention that is not in the scope of this article to go through the details of agents implementation on Mastra, but you can find plenty of documentation \u003Ca href=\"https:\u002F\u002Fmastra.ai\u002Fen\u002Fdocs\">on their website\u003C\u002Fa>.\u003C\u002Fp>\n",{"_modelApiKey":372,"copy":507,"listStyle":374,"darkTheme":11,"buttons":508,"color":370,"indent":11},"\u003Cp>In Mastra agents are programmatically defined using the \u003Ccode>Agent\u003C\u002Fcode> object. The minimal structure of the object is this:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":510,"showLineNumbers":11,"highlightLines":280,"language":447,"size":448},"export const myAgent = new Agent({\n  name: 'SKUs Auditor Agent',\n  instructions: `...`,\n  model: openai('gpt-4o-mini'),\n  tools: \u002F* agent tools here *\u002F,\n  memory: \u002F* memory options  here*\u002F,\n});",{"_modelApiKey":372,"copy":512,"listStyle":374,"darkTheme":11,"buttons":513,"color":370,"indent":11},"\u003Cp>So basically Mastra allows the creation of &quot;stubs&quot; for agents running on the model of choice. The agent is defined by: \u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>\u003Cstrong>Name\u003C\u002Fstrong> — The agent name.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Instructions\u003C\u002Fstrong> — What the agent is supposed to do, expressed in natural language.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Model\u003C\u002Fstrong> — The LLM to be used (this might also require an access key in the env vars).\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Tools\u003C\u002Fstrong> — Anything the agent might need to carry out its task, this are provided via MCP.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Memory\u003C\u002Fstrong> — Agents can have a local memory to persist conversations (this could be useful to improve agent efficiency).\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>We will go over the implementation of our agents in a short while, but now I want to jump to the final result. Agents are bundled in the main \u003Ccode>index.js\u003C\u002Fcode> file:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":515,"showLineNumbers":11,"highlightLines":280,"language":447,"size":456},"import { Mastra } from '@mastra\u002Fcore\u002Fmastra';\nimport { PinoLogger } from '@mastra\u002Floggers';\nimport { LibSQLStore } from '@mastra\u002Flibsql';\nimport { earlyFraudDetectionAgent } from '.\u002Fagents\u002Ffraud-monitor';\nimport { abandonedCartDetectorAgent } from '.\u002Fagents\u002Fabandoned-cart-detector';\n\nexport const mastra = new Mastra({\n  workflows: {},\n  agents: { earlyFraudDetectionAgent,abandonedCartDetectorAgent},\n  storage: new LibSQLStore({\n    \u002F\u002F stores telemetry, evals, ... into memory storage, if it needs to persist, change to file:..\u002Fmastra.db\n    url: \":memory:\",\n  }),\n  logger: new PinoLogger({\n    name: 'Mastra',\n    level: 'info',\n  }),\n});",{"_modelApiKey":372,"copy":517,"listStyle":374,"darkTheme":11,"buttons":518,"color":370,"indent":11},"\u003Cp>We start the Mastra platform:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":520,"showLineNumbers":11,"highlightLines":280,"language":487,"size":456},"~ cl-commerce-monitor % npm run dev\n\n> cl-commerce-monitor@1.0.0 dev\n> mastra dev\n\n◐ Preparing development environment...\n✓ Initial bundle complete\n◇ Starting Mastra dev server...\n\n mastra  0.12.3-alpha.1 ready in 1474 ms\n\n│ Playground:   http:\u002F\u002Flocalhost:4111\u002F\n│ API:     http:\u002F\u002Flocalhost:4111\u002Fapi\n\n◯ watching for file changes...\n◐ Bundling...\n✓ Bundle complete\n◐ [Mastra Dev] - Bundling finished, checking if restart is allowed...\n◐ [Mastra Dev] - ✅ Restarting server...\n↻ Restarting server...\n◇ Starting Mastra dev server...",{"_modelApiKey":372,"copy":522,"listStyle":374,"darkTheme":11,"buttons":523,"color":370,"indent":11},"\u003Cp>And opening a browser on \u003Ca href=\"http:\u002F\u002Flocalhost:4111\u002F\">http:\u002F\u002Flocalhost:4111\u002F\u003C\u002Fa> we can see the Mastra admin platform showing the agents we created:\u003C\u002Fp>\n",[],{"_modelApiKey":429,"border":11,"caption":280,"image":525,"size":531,"darkTheme":11,"rounded":7,"color":370},{"url":526,"alt":527,"title":527,"width":433,"height":528,"format":290,"focalPoint":529,"customData":530},"https:\u002F\u002Fwww.datocms-assets.com\u002F35053\u002F1761236909-mastra-admin.png","Mastra admin",1301,{"x":292,"y":292},{},"standard",{"_modelApiKey":372,"copy":533,"listStyle":374,"darkTheme":11,"buttons":534,"color":370,"indent":11},"\u003Cp>Let’s now give a look at the agents we created!\u003C\u002Fp>\n\n\u003Ch5>Abandoned cart detector\u003C\u002Fh5>\n\n\u003Cp>Cart abandonment is one of the most persistent challenges in commerce operations. Every unfinished checkout represents missed revenue, but also a burden for business teams who need to track, analyze, and recover those opportunities. Traditionally, this has meant either relying on basic automation (batch emails, static reminders) or performing repetitive manual tasks.\u003C\u002Fp>\n\n\u003Cp>An abandoned cart agent changes the game: it continuously monitors for carts that go stale, evaluates the customer context in real time, and triggers the most appropriate action — whether it’s sending a personalized reminder, flagging the case for follow-up, or even applying a targeted incentive. For merchants, this means fewer repetitive tasks and a more streamlined backend process. For customers, it translates into a smoother, more relevant shopping experience.\u003C\u002Fp>\n\n\u003Cp>For the scope of our article, our agent will just flag the cart as abandoned, but the potential here, is huge.\u003C\u002Fp>\n\n\u003Cp>Abandoned Cart Agent is supposed to be triggered periodically, it will then make use of the schedule we mentioned earlier to get triggered.\u003C\u002Fp>\n\n\u003Cp>The prompt is pretty straight forward — the text says it all:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":536,"showLineNumbers":11,"highlightLines":280,"language":537,"size":456},"You are an AI agent monitoring potential abandoned carts.\n\nInstructions:\n1. You will always receive a trigger event in JSON.\n\n2. Retrieve all carts in status \"pending\" (sort by order.updated_at and *NOT* by cart.updated_at) \n using cart search tool (**NEVER** call order search use *ALWAYS* clMetrics_carts-search) \n the filter should be something like this:\n {\n    \"order\": {\n        \"statuses\": {\n            \"in\": [\"pending\"]\n        },\n        \"date_from\": \"\u003C\u003Cday before of the event time 00:00>>\",\n        \"date_to\": \"\u003C\u003Cday before of the event time 23:59>>\",\n\t\t\t\t\"date_field\": \"updated_at\"\n    }\n}\n\n3. return a message with the number of pending carts in JSON format like this:\n{\n  \"message\": \"There are \u003Cnumber_of_pending_orders> pending orders that might be abandoned carts.\"\n  \"orders\": [\u003Clist_of_order_ids>]\n}\n\n4. tags the cart as \"abandoned_cart\" using the MCP tools specifying \"orders\" as the resource type and the order id as the resource id","plain",{"_modelApiKey":372,"copy":539,"listStyle":374,"darkTheme":11,"buttons":540,"color":370,"indent":11},"\u003Cp>In the section \u003Cem>MCP tools implementation\u003C\u002Fem> we showed how we created a tool that tags resources in Commerce Layer. Our agent will make use of this tool to flag a cart as potentially abandoned. Let’s see how to integrate with our MCP Server.\u003C\u002Fp>\n\n\u003Cp>We added this code under \u003Ccode>src\u002Fmastra\u002Fmcp\u003C\u002Fcode>:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":542,"showLineNumbers":11,"highlightLines":280,"language":447,"size":456},"import { MCPClient } from \"@mastra\u002Fmcp\";\n\nconst CL_ENV = {\n        \"CL_CLIENT_ID\" : \"\u003C\u003CYOUR CL Client ID here>>\",\n        \"CL_CLIENT_SECRET\": \"\u003C\u003CYOUR CL  Secret here>>\",\n        \"CL_ORGANIZATION\": \"\u003C\u003CYOUR Client Org here>>\",\n      }\n \nexport const clMcpClient = new MCPClient({\n  id: \"cl-mcp-client\",\n  servers: {\n    myMCPServer: {\n      command: \"node\",\n      args: [\"\u003C\u003Cpath to mcp server index.js>>\"],\n      env: CL_ENV\n    },\n  }\n});",{"_modelApiKey":372,"copy":544,"listStyle":374,"darkTheme":11,"buttons":545,"color":370,"indent":11},"\u003Cp>As our MCP server is local, Mastra will spawn a node process that will run the index file containing our tools. We pass Commerce Layer credentials as env variables so that the tool can call our APIs. Then we just pass this to the agent object:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":547,"showLineNumbers":11,"highlightLines":280,"language":447,"size":456},"import { clMcpClient } from '..\u002Fmcp\u002FclMcpClient';\n...\nexport const abandonedCartDetectorAgent = new Agent({\n  name: 'Abandoned Cart Detector Agent',\n  instructions: `\n   ...\n    `,\n  model: openai('gpt-4o-mini'),\n  tools: await clMcpClient.getTools(),\n});",{"_modelApiKey":372,"copy":549,"listStyle":374,"darkTheme":11,"buttons":550,"color":370,"indent":11},"\u003Cp>That’s it. We have our abandoned cart agent set up and ready to do his thing!\u003C\u002Fp>\n\n\u003Ch5>Early fraud detection agent\u003C\u002Fh5>\n\n\u003Cp>Fraudulent orders are a critical pain point in commerce operations. They not only generate financial losses but also drain resources as teams spend time verifying suspicious transactions and handling chargebacks. Traditional fraud prevention often relies on rigid rules or third-party tools that may either miss subtle risks or create false positives that frustrate legitimate customers.\u003C\u002Fp>\n\n\u003Cp>An early fraud detection agent provides a smarter alternative. By continuously scanning incoming orders, cross-checking them against past customer behavior, and applying contextual reasoning, the agent can flag anomalies in real time. This allows business teams to focus only on genuinely suspicious cases, reducing repetitive manual checks while lowering the risk of fraud slipping through. The result is stronger protection for merchants and a more seamless purchasing experience for honest customers.\u003C\u002Fp>\n\n\u003Cp>For the scope of this PoC, our agent will just flag the cart as potential fraud. The agent is supposed to be triggered by an order update event received by the streamer.\u003C\u002Fp>\n\n\u003Cp>We&#39;ll need a more sophisticated prompt here, but as before, you can easily get what it’s supposed to do:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":552,"showLineNumbers":11,"highlightLines":280,"language":537,"size":456},"You are an AI agent monitoring incoming order updates for potential fraud.\n\n    Instructions:\n    1. You will always receive an order update in JSON.\n\n    2. Retrieve the full order using the tool with the provided \"resource_id\".\n\n   3. Check order status:\n   - Normalize the order status to lowercase.\n   - If the status is not exactly \"pending\":\n     Respond:\n     {\n       \"message\": \"✅ No fraud check required.\",\n       \"order\": \"\u003Cresource_id>\"\n     }\n     End.\n\n    4. If the order status = \"pending\":\n      - If \"shipping_address\" is missing:\n        {\n          \"message\": \"ℹ️ Cannot evaluate — missing shipping address.\",\n          \"order\": \"\u003Cresource_id>\"\n        }\n        - End.\n\n      - Otherwise, use the order breakdown tool to find all orders belonging to the same customer in the last year . \n        The breakdown should be by city, address and country, using cardinality operator. \n        Pass as a fitler an object like the following (replace with actual values):\n        {\n          \"order\": {\n              \"date_from\": \"\u003C\u003Cnow_minus_1_year>>\",\n              \"date_to\": \"\u003C\u003Cnow>>\",\n              \"date_field\": \"placed_at\"\n          },\n          \"customer\": {\n              \"emails\" : {\n                  \"in\": [\"\u003C\u003Ccustomer_email>>\"]\n              }\n          }\n        } \n\n    5. With the retrieved breakdown (JSON object):\n      - parse the content.text field as a JSON object.\n      - extract the data.shipping_address.city array\n      - Count elements\n\n    6.Fraud detection rule:\n      - If the number of unique cities is less or equal than 5 \n        Respond with:\n        {\n          \"message\": \"✅ Order \u003Cresource_id> looks good. \u003Cnumber_of_unique_cities> different shipping cities in the last year for email \u003Ccustomer_email>.\",\n          \"order\": \"\u003Cresource_id>\"\n        }\n      \n      - If the number of unique cities is 6 or greater:\n        - tag the order as \"potential_fraud\" using the MCP tools specifying \"orders\" as the resource type and the resource_id as the resource id\n        - Respond with:\n        {\n          \"message\": \"🚨 Potential fraud detected for order \u003Cresource_id>. Reason: More than 5 unique shipping cities for email \u003Ccustomer_email>.\",\n          \"order\": \"\u003Cresource_id>\"\n        }\n\n        Constraints:\n        - Do not output reasoning steps.\n        - Always return only a JSON object with \"message\" and \"order\".\n        - No extra text, explanation, or formatting outside the JSON.",{"_modelApiKey":372,"copy":554,"listStyle":374,"darkTheme":11,"buttons":555,"color":370,"indent":11},"\u003Cp>In this case the agent will use our \u003Ca href=\"https:\u002F\u002Fdocs.commercelayer.io\u002Fmetrics\">Metrics API\u003C\u002Fa> tool exposed by our local MCP server (their implementation is not covered in this article). The way they are assigned to the agent is similar to what we saw for the abandoned cart agent.\u003C\u002Fp>\n\n\u003Ch3>Putting everything together\u003C\u002Fh3>\n\n\u003Cp>Now that we looked into all the pieces of our PoC is time to give it a spin and see the results.\u003C\u002Fp>\n\n\u003Cp>Here the output for our abandoned cart agent:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":557,"showLineNumbers":11,"highlightLines":280,"language":487,"size":456},"[2025-10-03 09:48:00] INFO: [1759484880007][30] [SCHEDULER] triggering agent abandonedCartDetectorAgent with params {\"lookback_hours\":24,\"max_orders\":100}\n[2025-10-03 09:48:23] INFO: [1759484903670][30] Response received: ```json\n{\n  \"message\": \"There are 14 pending orders that might be abandoned carts.\",\n  \"orders\": [\n    \"rnYhvglDpE\",\n    \"pyAhVLRjrQ\",\n    \"ykohGVkoXd\",\n    \"nlKhmQkJXQ\",\n    \"oKkhYXABnm\",\n    \"zdJhngmpLa\",\n    \"KaehevQJVK\",\n    \"xzYhpaeklY\",\n    \"QgYhvQQdAl\",\n    \"YWehQBOyjn\",\n    \"eWdhoydxMB\",\n    \"GWrhZzbabv\",\n    \"QgYhvQeGZD\",\n    \"eWdhoybrrA\"\n  ]\n}",{"_modelApiKey":372,"copy":559,"listStyle":374,"darkTheme":11,"buttons":560,"color":370,"indent":11},"\u003Cp>And if we check the order with the \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fcommercelayer\u002Fcommercelayer-cli\">CLI\u003C\u002Fa>, we can see that our agent tagged the order as abandoned:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":562,"showLineNumbers":11,"highlightLines":280,"language":487,"size":456},"~ cl-stream-poc % cl get orders\u002FrnYhvglDpE -i tags -f id tags               \n{\n  id: 'rnYhvglDpE',\n  type: 'orders',\n  tags: [\n    {\n      id: 'JrWXflvMpq',\n      type: 'tags',\n      name: 'abandoned_cart',\n      created_at: '2025-09-24T14:56:05.726Z',\n      updated_at: '2025-09-24T14:56:05.726Z',\n      reference: null,\n      reference_origin: null,\n      metadata: {}\n    }\n  ]\n}",{"_modelApiKey":372,"copy":564,"listStyle":374,"darkTheme":11,"buttons":565,"color":370,"indent":11},"\u003Cp>Let’s see instead the output of the early fraud detection agent:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":567,"showLineNumbers":11,"highlightLines":280,"language":487,"size":456},"[2025-10-03 10:23:16] INFO: [1759486996615][30] [STREAMER] Event data: {\"event\":\"update\",\"resource_type\":\"orders\",\"resource_id\":\"OBnhRYeeQm\",\"organization_id\":\"DnwWkFmMdn\",\"payload\":{\"updated_at\":{\"from\":\"2025-10-03T10:23:04.613Z\",\"to\":\"2025-10-03T10:23:16.400Z\"}},\"ip_address\":\"93.66.65.181\",\"user_agent\":\"node\",\"uuid\":\"0bd1e09342ef4ab29c2e4f698008a005dffb3f32557671d938481e60d1fb0d59\",\"test\":true,\"created_at\":\"2025-10-03T10:23:16.400Z\",\"updated_at\":\"2025-10-03T10:23:16.400Z\",\"who\":{\"application\":{\"id\":\"podBiKmyVN\",\"client_id\":\"e_p0J5QeUuYgkkm97eRJP7w_8QHPNoJYYnxY1dWlgV0\",\"kind\":\"integration\",\"public\":false,\"confidential\":true}}}\n[2025-10-03 10:23:16] INFO: [1759486996615][30] [1759486996415-0][STREAMER] Posting to early-fraud-detector\n[2025-10-03 10:23:23] INFO: [1759487003331][30] [1759486984683-0][STREAMER] Response from early-fraud-detector received: {\"message\":\"🚨 Potential fraud detected for order OBnhRYeeQm. Reason: More than 5 unique shipping cities for email fabriziod@commercelayer.io.\",\"order\":\"OBnhRYeeQm\"}",{"_modelApiKey":372,"copy":569,"listStyle":374,"darkTheme":11,"buttons":570,"color":370,"indent":11},"\u003Cp>Also here if we check the order with the CLI, we can see that the order has been correctly flagged as potential fraud:\u003C\u002Fp>\n",[],{"_modelApiKey":445,"code":572,"showLineNumbers":11,"highlightLines":280,"language":487,"size":456},"~ cl-stream-poc % cl get orders\u002FOBnhRYeeQm -i tags -f id tags \n{\n  id: 'OBnhRYeeQm',\n  type: 'orders',\n  tags: [\n    {\n      id: 'JkkxfeEGPJ',\n      type: 'tags',\n      name: 'potential_fraud',\n      created_at: '2025-09-24T10:24:04.992Z',\n      updated_at: '2025-09-24T10:24:04.992Z',\n      reference: null,\n      reference_origin: null,\n      metadata: {}\n    }\n  ]\n}",{"_modelApiKey":372,"copy":574,"listStyle":374,"darkTheme":11,"buttons":575,"color":370,"indent":11},"\u003Ch3>Conclusion\u003C\u002Fh3>\n\n\u003Cp>This proof of concept was not about building production-ready solutions, but about demonstrating what’s already possible when you combine an \u003Cstrong>API-first commerce platform\u003C\u002Fstrong> like Commerce Layer with \u003Cstrong>agentic workers\u003C\u002Fstrong> powered by modern LLMs. By wiring together real-time events, scheduled tasks, and intelligent agents, we’ve shown how everyday commerce operations — from cart recovery to fraud detection — can be reimagined with far less manual overhead and far greater adaptability.\u003C\u002Fp>\n\n\u003Cp>The real takeaway is that the building blocks are here \u003Cstrong>today\u003C\u002Fstrong>. With tools like \u003Cstrong>Mastra\u003C\u002Fstrong>, \u003Cstrong>MCP\u003C\u002Fstrong>, and \u003Cstrong>streaming APIs\u003C\u002Fstrong>, agents can already operate as autonomous, context-aware assistants within existing commerce stacks. What’s emerging now, with initiatives such as \u003Cstrong>ACP\u003C\u002Fstrong> and \u003Cstrong>A2A\u003C\u002Fstrong>, is the foundation for an open, interoperable ecosystem — where agents can not only act on data, but also \u003Cstrong>collaborate with each other\u003C\u002Fstrong> and with legacy systems like ERPs and CRMs.\u003C\u002Fp>\n\n\u003Cp>Commerce Layer’s API-first architecture naturally fits into this evolution, making it an ideal ground for experimentation and early adoption. As these protocols mature, we’ll move from proofs of concept like this one to fully agentic operations — where human expertise and autonomous agents work side by side to create faster, smarter, and more resilient commerce systems.\u003C\u002Fp>\n",[],[577,578,580,582,584,586,588,590,592,594,596,598,600,602,604,606,608],{"attributes":303,"tag":304,"content":305},{"attributes":579,"tag":309,"content":303},{"property":308,"content":305},{"attributes":581,"tag":309,"content":303},{"name":312,"content":305},{"attributes":583,"tag":309,"content":303},{"name":315,"content":316},{"attributes":585,"tag":309,"content":303},{"property":319,"content":316},{"attributes":587,"tag":309,"content":303},{"name":322,"content":316},{"attributes":589,"tag":309,"content":303},{"property":325,"content":326},{"attributes":591,"tag":309,"content":303},{"property":329,"content":330},{"attributes":593,"tag":309,"content":303},{"property":333,"content":334},{"attributes":595,"tag":309,"content":303},{"name":337,"content":326},{"attributes":597,"tag":309,"content":303},{"property":340,"content":341},{"attributes":599,"tag":309,"content":303},{"property":344,"content":345},{"attributes":601,"tag":309,"content":303},{"property":348,"content":349},{"attributes":603,"tag":309,"content":303},{"property":352,"content":353},{"attributes":605,"tag":309,"content":303},{"property":356,"content":280},{"attributes":607,"tag":309,"content":303},{"name":359,"content":360},{"attributes":609,"tag":309,"content":303},{"name":363,"content":364},[611],{"name":285,"picture":612},{"url":287,"alt":288,"title":288,"width":289,"height":289,"format":290,"focalPoint":613,"customData":614},{"x":292,"y":292},{},1791534732169]