<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Dhyan Raj</title>
    <description>The latest articles on Forem by Dhyan Raj (@dhyan_raj_98e6a5999c8d5ef).</description>
    <link>https://forem.com/dhyan_raj_98e6a5999c8d5ef</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3675576%2F4d17ec9e-d635-494a-bba1-9dd36931585b.jpg</url>
      <title>Forem: Dhyan Raj</title>
      <link>https://forem.com/dhyan_raj_98e6a5999c8d5ef</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dhyan_raj_98e6a5999c8d5ef"/>
    <language>en</language>
    <item>
      <title>Service Mesh for MCP Agents — Without the Sidecar</title>
      <dc:creator>Dhyan Raj</dc:creator>
      <pubDate>Thu, 16 Apr 2026 22:04:17 +0000</pubDate>
      <link>https://forem.com/dhyan_raj_98e6a5999c8d5ef/service-mesh-for-mcp-agents-without-the-sidecar-96h</link>
      <guid>https://forem.com/dhyan_raj_98e6a5999c8d5ef/service-mesh-for-mcp-agents-without-the-sidecar-96h</guid>
      <description>&lt;p&gt;Remember the first time you installed Istio?&lt;/p&gt;

&lt;p&gt;The pitch was beautiful. mTLS everywhere. Automatic retries. Distributed tracing. Traffic shifting with a YAML file. You ran &lt;code&gt;istioctl install&lt;/code&gt;, got a coffee, came back, and discovered every pod had grown a 50MB Envoy companion. Memory usage doubled. Cold starts crawled. Your Helm chart sprouted a &lt;code&gt;proxy.resources.limits&lt;/code&gt; block. And every six months, you'd schedule a maintenance window to upgrade the control plane and pray nothing in the data path broke.&lt;/p&gt;

&lt;p&gt;Service meshes are extraordinary. They're also expensive — in CPU, in mental load, in operational surface area.&lt;/p&gt;

&lt;p&gt;So here's the question we kept asking while building &lt;strong&gt;MCP Mesh&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What if you could have everything a service mesh gives you, but built into the agents themselves — no sidecar, no control plane, no CRDs?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not as a thought experiment. As a thing you can &lt;code&gt;pip install&lt;/code&gt; today.&lt;/p&gt;




&lt;h2&gt;
  
  
  The five jobs of a service mesh
&lt;/h2&gt;

&lt;p&gt;Strip away the marketing and a service mesh does five things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Discovery&lt;/strong&gt; — find the right backend without hardcoding hosts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;mTLS&lt;/strong&gt; — every call mutually authenticated, automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Traffic policy&lt;/strong&gt; — retries, timeouts, circuit breaking, canaries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability&lt;/strong&gt; — every hop traced, every error surfaced.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identity&lt;/strong&gt; — workloads have provable identity that survives across orgs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are real production needs. They didn't go away with AI agents. If anything, they got worse: now you've got Python agents calling TypeScript agents calling Java agents calling Claude. Discovery, mTLS, retries — all the same problems, dressed in fashion.&lt;/p&gt;

&lt;p&gt;So why not just wrap MCP agents in Envoy and ship?&lt;/p&gt;

&lt;p&gt;You can. People do. And then they're back to two binaries per workload, a control plane to babysit, and the joy of debugging "is the sidecar healthy or is the app healthy?"&lt;/p&gt;




&lt;h2&gt;
  
  
  Why sidecars exist
&lt;/h2&gt;

&lt;p&gt;Be fair to the sidecar pattern. It exists for one excellent reason: &lt;strong&gt;the application doesn't know about the mesh, and you don't want to make it know.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have a hundred microservices written by ten teams across five years in three languages, asking each of them to integrate a mesh SDK is a non-starter. The sidecar lets you bolt the mesh on from the outside. It's a retrofit.&lt;/p&gt;

&lt;p&gt;But MCP agents are new code. They're being written &lt;em&gt;now&lt;/em&gt;, on a protocol designed &lt;em&gt;now&lt;/em&gt;, for an ecosystem that's barely two years old. We don't have to retrofit. We can put the mesh &lt;strong&gt;inside&lt;/strong&gt; the agent.&lt;/p&gt;

&lt;p&gt;That's what MCP Mesh does.&lt;/p&gt;




&lt;h2&gt;
  
  
  Registry as facilitator, not proxy
&lt;/h2&gt;

&lt;p&gt;The architecture is one diagram:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────┐     Heartbeat / Topology     ┌──────────┐
│ Agent A │ ──────────────────────────►  │ Registry │
│         │ ◄──────────────────────────  │          │
└─────────┘                              └──────────┘
     │
     │ Direct MCP call (mTLS)
     ▼
┌─────────┐
│ Agent B │
└─────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two things to notice.&lt;/p&gt;

&lt;p&gt;First: &lt;strong&gt;the registry never sits in the data path.&lt;/strong&gt; Agents heartbeat in every five seconds, get back the topology of who provides what, and then call each other directly. The registry is a phone book, not a telephone exchange.&lt;/p&gt;

&lt;p&gt;Second: &lt;strong&gt;if the registry dies, your agents keep talking.&lt;/strong&gt; They've got the topology cached. New agents can't join until it's back, but existing traffic flows uninterrupted. Try that with Pilot down.&lt;/p&gt;

&lt;p&gt;This is the move that makes "no sidecar" possible. You don't need a proxy because the destination is already known to the source. The mesh isn't &lt;em&gt;between&lt;/em&gt; agents; it &lt;strong&gt;is&lt;/strong&gt; the agents.&lt;/p&gt;




&lt;h2&gt;
  
  
  Walking the service-mesh feature list
&lt;/h2&gt;

&lt;p&gt;Let's go down the checklist and show what each one looks like in MCP Mesh.&lt;/p&gt;

&lt;h3&gt;
  
  
  Discovery → declare what you need, get it injected
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@mesh.tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;capability&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;plan_trip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;dependencies&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;capability&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;weather&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tags&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;+claude&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;capability&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hotels&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;capability&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;flights&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;plan_trip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dates&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;weather&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mesh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;McpMeshTool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;hotels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;mesh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;McpMeshTool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;flights&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mesh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;McpMeshTool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;forecast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;dates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;hotels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;dates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;routes&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;flights&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;dates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;TripPlan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forecast&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No service host. No port. No DNS lookup. You declared what you need; the mesh handed you a callable. &lt;strong&gt;The proxy is in the function signature.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When a new &lt;code&gt;weather&lt;/code&gt; provider comes online — better, faster, cheaper — your call goes there on the next heartbeat tick. Zero deploy. Zero code change.&lt;/p&gt;

&lt;h3&gt;
  
  
  mTLS → one flag
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;meshctl start &lt;span class="nt"&gt;--registry-only&lt;/span&gt; &lt;span class="nt"&gt;--tls-auto&lt;/span&gt;
meshctl start my_agent.py &lt;span class="nt"&gt;--tls-auto&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That generates a mini-CA, issues certs to every agent, and turns on mutual TLS for every call. In production, swap the file provider for SPIRE or Vault:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;MCP_MESH_TLS_PROVIDER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;spire
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;MCP_MESH_SPIRE_SOCKET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/run/spire/agent/sockets/agent.sock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SPIFFE-aware out of the box. URI SANs, not DNS SANs. Private keys live in &lt;code&gt;/dev/shm&lt;/code&gt; so they never touch disk. No Citadel install. No mesh-wide rollout. Each agent picks up its identity at startup and uses its language's native TLS stack — &lt;code&gt;httpx&lt;/code&gt; in Python, &lt;code&gt;tls&lt;/code&gt; in Node, &lt;code&gt;SSLContext&lt;/code&gt; in Java.&lt;/p&gt;

&lt;p&gt;The mesh isn't a layer below your app. It's a few lines inside it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-org trust → entities, not federation
&lt;/h3&gt;

&lt;p&gt;In a real enterprise mesh you've got two orgs that need to talk. Service mesh answer: federation, trust bundles, multi-cluster. MCP Mesh answer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;meshctl entity register &lt;span class="s2"&gt;"partner-corp"&lt;/span&gt; &lt;span class="nt"&gt;--ca-cert&lt;/span&gt; /path/to/ca.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Done. Their agents are now trusted peers in your mesh.&lt;/p&gt;

&lt;h3&gt;
  
  
  Traffic policy → kwargs, not VirtualService
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@mesh.tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;dependencies&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;slow_service&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;dependency_kwargs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;slow_service&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;timeout&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;retry_count&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;streaming&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;session_required&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;my_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slow_service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mesh&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;McpMeshTool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;slow_service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's your &lt;code&gt;DestinationRule&lt;/code&gt;. In Python. Type-checkable. Diff-reviewable. Lives next to the code that uses it.&lt;/p&gt;

&lt;p&gt;Want canaries? Tags do that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;dependencies&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;capability&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;math&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tags&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;addition&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;python&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;typescript&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]]},&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try the Python provider first; if not available, fall back to TypeScript. That's a shadow deploy, a canary, and a fallback policy in one tag expression.&lt;/p&gt;

&lt;h3&gt;
  
  
  Header propagation → one env var
&lt;/h3&gt;

&lt;p&gt;Auth tokens, tenant IDs, correlation headers — they need to flow end-to-end through the call chain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;MCP_MESH_PROPAGATE_HEADERS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;authorization,x-tenant-id,x-request-id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set it on every agent. Inbound headers matching the allowlist get captured into request-scoped context (Python uses &lt;code&gt;contextvars&lt;/code&gt; for async safety) and re-injected into every downstream call automatically. No middleware. No Envoy filter. No code in your tool functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Observability → one flag and a Helm chart
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;MCP_MESH_DISTRIBUTED_TRACING_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true
&lt;/span&gt;helm &lt;span class="nb"&gt;install &lt;/span&gt;mcp-core oci://ghcr.io/dhyansraj/mcp-mesh/mcp-mesh-core &lt;span class="nt"&gt;--version&lt;/span&gt; 1.3.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That ships you a Tempo backend, a Grafana with dashboards pre-loaded, OTLP wired up between every agent. Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;meshctl trace abc123def456

└─ plan_trip &lt;span class="o"&gt;(&lt;/span&gt;trip-planner&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;245ms] ✓
   ├─ weather &lt;span class="o"&gt;(&lt;/span&gt;claude-weather&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;120ms] ✓
   │  └─ llm:claude &lt;span class="o"&gt;(&lt;/span&gt;claude-provider&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;98ms] ✓
   ├─ hotels &lt;span class="o"&gt;(&lt;/span&gt;gpt-hotels&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;80ms] ✓
   └─ flights &lt;span class="o"&gt;(&lt;/span&gt;flight-agent&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;40ms] ✓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every hop. Every agent. Every LLM call. From your terminal.&lt;/p&gt;




&lt;h2&gt;
  
  
  The thing service meshes can't do
&lt;/h2&gt;

&lt;p&gt;Here's where MCP Mesh stops looking like Istio and starts looking like something new.&lt;/p&gt;

&lt;p&gt;A service mesh routes &lt;strong&gt;traffic&lt;/strong&gt;. Bytes from one socket to another. Your code still has to know there's an HTTP client in there, construct a URL, parse a response, deserialize JSON, handle the error envelope.&lt;/p&gt;

&lt;p&gt;MCP Mesh routes &lt;strong&gt;function calls&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;forecast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;dates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That &lt;code&gt;weather&lt;/code&gt; is a Python callable. It happens to live in another process, on another machine, written in another language, possibly powered by an LLM. You can't tell from the code. &lt;strong&gt;You don't have to.&lt;/strong&gt; The mesh handed you a function. You called it. The result came back typed.&lt;/p&gt;

&lt;p&gt;We call this &lt;strong&gt;DDDI — Distributed Dynamic Dependency Injection.&lt;/strong&gt; Spring gave us DI on a single JVM. Guice gave it to us in fewer lines. MCP Mesh gives it to us across the network, across runtimes, across language boundaries.&lt;/p&gt;

&lt;p&gt;The proxy is in your function signature. That's the move.&lt;/p&gt;

&lt;p&gt;And it composes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;weather&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reasoning_weather&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wants_explanation&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;api_weather&lt;/span&gt;
&lt;span class="n"&gt;forecast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a routing decision in Python. In an &lt;code&gt;if&lt;/code&gt;. Not a &lt;code&gt;VirtualService&lt;/code&gt;. Not a percentage split in YAML. The full power of your language, applied to traffic shaping.&lt;/p&gt;




&lt;h2&gt;
  
  
  "But it only meshes MCP agents…"
&lt;/h2&gt;

&lt;p&gt;That's where the skeptic leans in. &lt;em&gt;Sure, sure, but I've got Postgres, a REST API, a vector DB, and a legacy SOAP service. Your shiny mesh doesn't help me with any of those.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Hold up.&lt;/p&gt;

&lt;p&gt;MCP isn't a wire format for AI gimmicks. MCP is a tool protocol with &lt;strong&gt;typed schemas, streaming, structured errors, and bidirectional communication built in.&lt;/strong&gt; Wrap your Postgres in an MCP tool — it's now a mesh participant. Wrap your REST API — same. Your RAG pipeline, your S3 bucket, your billing system — every one of those is one &lt;code&gt;@mesh.tool&lt;/code&gt; away from being a first-class member of the mesh, with mTLS, retries, tracing, and discovery, for free.&lt;/p&gt;

&lt;p&gt;And here's the kicker: &lt;strong&gt;MCP is arguably a better default than REST for new internal services.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Schemas, without dragging OpenAPI tooling along.&lt;/li&gt;
&lt;li&gt;Streaming, without SSE plumbing.&lt;/li&gt;
&lt;li&gt;Tool discovery, without a Swagger portal.&lt;/li&gt;
&lt;li&gt;Bidirectional, without WebSocket gymnastics.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're building a new internal API in 2026, you should at least &lt;em&gt;consider&lt;/em&gt; exposing it over MCP. The ergonomics are better. The schemas are first-class. The tooling is finally catching up. This isn't AI hype — this is what REST should have evolved into a decade ago.&lt;/p&gt;

&lt;p&gt;But say you're not ready to MCP-ify everything. The proxy layer in MCP Mesh — &lt;code&gt;EnhancedUnifiedMCPProxy&lt;/code&gt; — already abstracts transport from semantics. Adding a REST adapter is an architectural extension, not a rewrite. gRPC, the same. The mesh isn't tied to MCP. &lt;strong&gt;MCP is just the first protocol it speaks.&lt;/strong&gt; Multi-protocol mesh isn't a roadmap dream — it's an extension point sitting in the codebase right now.&lt;/p&gt;

&lt;p&gt;This isn't a narrow tool for a niche protocol. &lt;strong&gt;This is a paradigm shift in how distributed systems get composed&lt;/strong&gt;, and MCP happens to be the protocol that made the shift cheap enough to ship.&lt;/p&gt;




&lt;h2&gt;
  
  
  So here's the punchline
&lt;/h2&gt;

&lt;p&gt;For the K8s crowd: you can have a mesh without the proxy tax. mTLS, discovery, retries, tracing, identity — all of it — delivered in-process, debuggable in your own language, with no second binary per pod.&lt;/p&gt;

&lt;p&gt;For the application developer: you can call a remote agent like a local function, in any of three languages, with the proxy &lt;em&gt;in your function signature.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For the platform team: you get a control plane that fits in one binary, scales to thousands of agents, and stays out of the data path.&lt;/p&gt;

&lt;p&gt;For everyone: the mesh isn't bolted on. It &lt;strong&gt;is&lt;/strong&gt; the agents.&lt;/p&gt;

&lt;p&gt;If you searched &lt;strong&gt;"service mesh for MCP agents"&lt;/strong&gt; and ended up here — congratulations. You found the only one.&lt;/p&gt;

&lt;p&gt;And it doesn't have a sidecar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @mcpmesh/cli
meshctl scaffold
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Welcome to the mesh.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://mcp-mesh.ai/" rel="noopener noreferrer"&gt;&lt;strong&gt;Docs&lt;/strong&gt;&lt;/a&gt; · &lt;a href="https://github.com/dhyansraj/mcp-mesh" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/a&gt; · &lt;a href="https://discord.gg/KDFDREphWn" rel="noopener noreferrer"&gt;&lt;strong&gt;Discord&lt;/strong&gt;&lt;/a&gt; · &lt;a href="https://www.youtube.com/@MCPMesh" rel="noopener noreferrer"&gt;&lt;strong&gt;YouTube&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>servicemesh</category>
      <category>mcp</category>
      <category>devops</category>
    </item>
    <item>
      <title>MCP Mesh: 5 Ways It Simplifies Multi-Agent AI Deployment on Kubernetes</title>
      <dc:creator>Dhyan Raj</dc:creator>
      <pubDate>Sat, 03 Jan 2026 21:20:55 +0000</pubDate>
      <link>https://forem.com/dhyan_raj_98e6a5999c8d5ef/mcp-mesh-5-ways-it-simplifies-multi-agent-ai-deployment-on-kubernetes-1mi3</link>
      <guid>https://forem.com/dhyan_raj_98e6a5999c8d5ef/mcp-mesh-5-ways-it-simplifies-multi-agent-ai-deployment-on-kubernetes-1mi3</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; MCP Mesh is distributed infrastructure that feels like writing regular Python functions. No YAML. No config drift. Same code runs local, Docker, and Kubernetes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Deploying multi-agent AI systems on Kubernetes shouldn't require a PhD in YAML. Yet here we are - drowning in Deployments, Services, ConfigMaps, Ingresses, and Service Meshes just to get agents talking to each other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if deploying AI agents to Kubernetes was as simple as:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;meshctl scaffold &lt;span class="nt"&gt;--name&lt;/span&gt; my-agent &lt;span class="nt"&gt;--agent-type&lt;/span&gt; tool
helm &lt;span class="nb"&gt;install &lt;/span&gt;my-agent oci://ghcr.io/dhyansraj/mcp-mesh/mcp-mesh-agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MCP Mesh transforms the Model Context Protocol (MCP) into an enterprise-grade distributed system. Here are 5 ways it simplifies multi-agent AI deployment.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Decorators Replace YAML - Configure in Code, Not Files
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;Traditional Kubernetes deployments require extensive YAML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# kubernetes deployment.yaml (abbreviated - real one is 50+ lines)&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;datetime-service&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;datetime&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;datetime-service:v1&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9000&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;datetime-service&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The MCP Mesh Way
&lt;/h3&gt;

&lt;p&gt;Configuration lives in decorators, right next to your code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;mesh&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastmcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastMCP&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastMCP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DateTime Service&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@app.tool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nd"&gt;@mesh.tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;capability&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_datetime&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;datetime&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_datetime&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y-%m-%d %H:%M:%S&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@mesh.agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;datetime-agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;9000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DateTimeAgent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="c1"&gt;# No main(). No server setup. No registration code.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a complete, production-ready distributed agent. Deploy it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;meshctl scaffold &lt;span class="nt"&gt;--name&lt;/span&gt; datetime-agent &lt;span class="nt"&gt;--agent-type&lt;/span&gt; tool
helm &lt;span class="nb"&gt;install &lt;/span&gt;datetime-agent oci://ghcr.io/dhyansraj/mcp-mesh/mcp-mesh-agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configuration lives with the code it describes&lt;/li&gt;
&lt;li&gt;No drift between code and config&lt;/li&gt;
&lt;li&gt;IDE autocomplete and type checking&lt;/li&gt;
&lt;li&gt;Refactoring tools work&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Same Code Runs Locally, in Docker, and on Kubernetes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;Most frameworks force a one-way street: local → Docker → Kubernetes. Going back to debug locally means recreating your entire stack.&lt;/p&gt;

&lt;h3&gt;
  
  
  The MCP Mesh Way
&lt;/h3&gt;

&lt;p&gt;The same code runs everywhere - without modification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────────────────────┐
│                    Your Agent Code                   │
│                                                      │
│  @mesh.tool(capability="payment", tags=["tools"])    │
│  def process_payment(amount: float) -&amp;gt; str:          │
│      ...                                             │
└──────────────────────────────────────────────────────┘
                          │
          ┌───────────────┼───────────────┐
          ▼               ▼               ▼
     ┌────────┐     ┌──────────┐    ┌─────────┐
     │ Local  │     │  Docker  │    │   K8s   │
     │        │     │ Compose  │    │         │
     └────────┘     └──────────┘    └─────────┘

     meshctl       docker          helm install
     start         compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;But it goes further - it's bidirectional:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most frameworks force you forward (local → Docker → K8s). Going back is painful.&lt;/p&gt;

&lt;p&gt;MCP Mesh allows movement in any direction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Local ↔ Docker ↔ K8s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Real scenario:&lt;/strong&gt; You have 5 agents running in Docker Compose. You want to debug one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Stop just that agent in compose&lt;/span&gt;
docker compose stop payment-agent

&lt;span class="c"&gt;# Run it locally with debugger attached&lt;/span&gt;
meshctl start payment-agent/main.py &lt;span class="nt"&gt;--debug&lt;/span&gt;

&lt;span class="c"&gt;# It joins the same mesh, works with Docker agents&lt;/span&gt;
&lt;span class="c"&gt;# Fix the bug, test it live, then promote back to compose&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No config changes. The mesh doesn't care where agents run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"But what about hardcoded ports?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You might see a decorator like this and wonder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@mesh.agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;payment-agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http_port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;9000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Hardcoded port?
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't I need different ports in different environments? Doesn't this require code changes?&lt;/p&gt;

&lt;p&gt;No. MCP Mesh decorators define &lt;em&gt;defaults&lt;/em&gt;. Environment variables override them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# In Kubernetes, the Helm chart sets:&lt;/span&gt;
&lt;span class="nv"&gt;MCP_MESH_HTTP_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8080  &lt;span class="c"&gt;# Overrides the decorator's http_port=9000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code stays the same. The environment controls runtime behavior. Run &lt;code&gt;meshctl man env&lt;/code&gt; to see all overridable settings - your decorators are sensible defaults, not hardcoded constraints.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Dynamic Dependency Injection Across the Network
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;Spring revolutionized Java with dependency injection - but it's static and limited to a single JVM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Autowired&lt;/span&gt;
&lt;span class="nd"&gt;@Qualifier&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"stripe"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nc"&gt;PaymentService&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Wired at startup, fixed forever&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MCP Mesh takes DI further - distributed and dynamic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@mesh.llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;capability&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;payment&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tags&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;+stripe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}],&lt;/span&gt;
    &lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;capability&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;llm&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  &lt;span class="c1"&gt;# Discovered at runtime
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c1"&gt;# Can change if topology changes
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Spring DI&lt;/th&gt;
&lt;th&gt;MCP Mesh DI&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Scope&lt;/td&gt;
&lt;td&gt;Single JVM&lt;/td&gt;
&lt;td&gt;Distributed network&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;When&lt;/td&gt;
&lt;td&gt;Startup&lt;/td&gt;
&lt;td&gt;Runtime (continuous)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wiring&lt;/td&gt;
&lt;td&gt;Static&lt;/td&gt;
&lt;td&gt;Dynamic, adapts to topology&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Missing dependency&lt;/td&gt;
&lt;td&gt;App fails to start&lt;/td&gt;
&lt;td&gt;Graceful degradation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hot swap&lt;/td&gt;
&lt;td&gt;Needs restart&lt;/td&gt;
&lt;td&gt;Automatic via heartbeat&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;MCP Mesh is essentially:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spring DI (dependency injection)&lt;/li&gt;
&lt;li&gt;Eureka (service discovery)&lt;/li&gt;
&lt;li&gt;Ribbon (load balancing)&lt;/li&gt;
&lt;li&gt;Hystrix (circuit breaker)&lt;/li&gt;
&lt;li&gt;Config Server (configuration)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...collapsed into simple decorators.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Mock Services Without Config Changes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;Traditional microservices testing requires mocking infrastructure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# WireMock config, environment variables, test profiles...&lt;/span&gt;
&lt;span class="s"&gt;payment.service.url=${PAYMENT_URL:http://localhost:8080}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The MCP Mesh Way
&lt;/h3&gt;

&lt;p&gt;MCP Mesh uses tags for environment switching:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Production agent
&lt;/span&gt;&lt;span class="nd"&gt;@mesh.tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;capability&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;payment&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;payment&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;production&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;real_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;stripe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Local fake (different agent, same capability)
&lt;/span&gt;&lt;span class="nd"&gt;@mesh.tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;capability&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;payment&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;payment&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;  &lt;span class="c1"&gt;# No production
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fake_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FAKE_TXN_123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;# Always succeeds
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Consumer code - never changes
&lt;/span&gt;&lt;span class="nd"&gt;@mesh.llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tags&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;payment&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;+production&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Environment&lt;/th&gt;
&lt;th&gt;What Gets Discovered&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Local (dev alone)&lt;/td&gt;
&lt;td&gt;Local fake (only one with "payment" tag)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dev (team)&lt;/td&gt;
&lt;td&gt;Real dev service (has production)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Production&lt;/td&gt;
&lt;td&gt;Production service (has production)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Same consumer code. Zero configuration changes. Tags control wiring.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Team Development Without Blocking
&lt;/h2&gt;

&lt;p&gt;Traditional microservices:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer A (order-service):
  - Needs payment-service (Developer B is building it)
  - Options:
    1. Wait for B → blocked
    2. Mock with WireMock → maintain mock config
    3. Use shared dev env → "who broke dev?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MCP Mesh:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer A:
  - Creates fake payment tool locally (5 lines of Python)
  - Works on order-service against fake
  - When B's real service is ready, A's code automatically uses it
  - No changes to A's code, no coordination needed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mesh becomes a &lt;strong&gt;dependency injection container at runtime&lt;/strong&gt; - capabilities are interfaces, agents are implementations.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Observability From Day One - Including Local Dev
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;Production observability is solved - deploy Grafana, Jaeger, configure exporters. But what about local development? When you're debugging 5 agents on your laptop, you're flying blind. Traditional frameworks offer no tracing until you deploy to an environment with observability infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  The MCP Mesh Way
&lt;/h3&gt;

&lt;p&gt;MCP Mesh brings distributed tracing to local development - the same &lt;code&gt;meshctl&lt;/code&gt; commands work everywhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;meshctl call assistant &lt;span class="nt"&gt;--trace&lt;/span&gt; &lt;span class="s1"&gt;'{"input": "What time is it and when is the next daylight savings change?"}'&lt;/span&gt;

&lt;span class="c"&gt;# Output:&lt;/span&gt;
Trace ID: 46d869487656fc6eb7f2e1d10e8ce307
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;meshctl trace 46d869487656fc6eb7f2e1d10e8ce307

&lt;span class="c"&gt;# Output:&lt;/span&gt;
├─ assistant &lt;span class="o"&gt;(&lt;/span&gt;assistant&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;2ms]
├─ openai_provider &lt;span class="o"&gt;(&lt;/span&gt;openai-provider&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;1573ms]
├─ get_datetime &lt;span class="o"&gt;(&lt;/span&gt;datetime-agent&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;0ms]
├─ web_search &lt;span class="o"&gt;(&lt;/span&gt;search-agent&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;1669ms]
└─ openai_provider &lt;span class="o"&gt;(&lt;/span&gt;openai-provider&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;4104ms]

Summary: 5 spans across 4 agents | 7.75s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Works everywhere:&lt;/strong&gt; Local dev, Docker Compose, or production Kubernetes - same commands, same output. Point &lt;code&gt;meshctl&lt;/code&gt; at your K8s cluster and trace production requests with the same workflow.&lt;/p&gt;

&lt;p&gt;In production, MCP Mesh exports to Grafana/Jaeger like any other system. The difference? You get the same observability on day one of development, not after deploying infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Graceful Degradation
&lt;/h2&gt;

&lt;p&gt;What happens when the registry crashes?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kubernetes + Istio:&lt;/strong&gt; Service discovery fails, cascading failures, pages at 3am.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP Mesh:&lt;/strong&gt; Agents continue working with cached topology. They keep trying to reconnect, but don't fail. When registry comes back, they sync.&lt;/p&gt;

&lt;p&gt;The registry is a coordination point, not a single point of failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  KISS Score: 8.5/10
&lt;/h2&gt;

&lt;p&gt;For a distributed system framework with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Service discovery&lt;/li&gt;
&lt;li&gt;Dependency injection&lt;/li&gt;
&lt;li&gt;Load balancing&lt;/li&gt;
&lt;li&gt;Circuit breakers&lt;/li&gt;
&lt;li&gt;Distributed tracing&lt;/li&gt;
&lt;li&gt;Graceful degradation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...that you can learn in an afternoon, that's remarkable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @mcpmesh/cli 

&lt;span class="c"&gt;# Scaffold an agent&lt;/span&gt;
meshctl scaffold &lt;span class="nt"&gt;--name&lt;/span&gt; my-agent &lt;span class="nt"&gt;--agent-type&lt;/span&gt; tool

&lt;span class="c"&gt;# Run it&lt;/span&gt;
meshctl start my-agent/main.py

&lt;span class="c"&gt;# Generate Docker Compose for all agents&lt;/span&gt;
meshctl scaffold &lt;span class="nt"&gt;--compose&lt;/span&gt; &lt;span class="nt"&gt;--observability&lt;/span&gt;

&lt;span class="c"&gt;# Deploy to Kubernetes&lt;/span&gt;
helm &lt;span class="nb"&gt;install &lt;/span&gt;my-agent oci://ghcr.io/dhyansraj/mcp-mesh/mcp-mesh-agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;MCP Mesh proves that distributed systems don't have to feel distributed. These 5 design choices make the difference:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Decorators over YAML&lt;/strong&gt; - Configuration lives with your code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Same code everywhere&lt;/strong&gt; - Bidirectional portability across environments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic DI&lt;/strong&gt; - Spring-style dependency injection for distributed systems&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tags for switching&lt;/strong&gt; - Mock services without config changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability from day one&lt;/strong&gt; - Distributed tracing in local dev, not just production&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result? A framework where the common case is trivial and the hard case is possible.&lt;/p&gt;

&lt;p&gt;The best infrastructure is the infrastructure you don't notice. MCP Mesh gets out of your way and lets you build.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;MCP Mesh is open source: &lt;a href="https://github.com/dhyansraj/mcp-mesh" rel="noopener noreferrer"&gt;github.com/dhyansraj/mcp-mesh&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>kubernetes</category>
      <category>tooling</category>
    </item>
    <item>
      <title>How Our AI Hiring Platform Gets Smarter Without Code Changes</title>
      <dc:creator>Dhyan Raj</dc:creator>
      <pubDate>Thu, 25 Dec 2025 03:38:37 +0000</pubDate>
      <link>https://forem.com/dhyan_raj_98e6a5999c8d5ef/how-our-ai-hiring-platform-gets-smarter-without-code-changes-1kg3</link>
      <guid>https://forem.com/dhyan_raj_98e6a5999c8d5ef/how-our-ai-hiring-platform-gets-smarter-without-code-changes-1kg3</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Last month, our AI hiring platform could only process PDF resumes.&lt;/p&gt;

&lt;p&gt;This week, it handles PDFs, Word documents, and scanned images with OCR.&lt;/p&gt;

&lt;p&gt;We didn't change a single line of code in our resume processing agent. We just deployed new extractors to the cluster — and the LLM-powered agent started using them automatically.&lt;/p&gt;

&lt;p&gt;This is what building on MCP Mesh feels like.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Platform
&lt;/h3&gt;

&lt;p&gt;We built a multi-agent hiring platform on Kubernetes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────────────────┐
│                         MCP Mesh Registry                               │
│                  (Discovery + Topology + Health)                        │
└─────────────────────────────────────────────────────────────────────────┘
       ▲              ▲                ▲              ▲              ▲
       │              │                │              │              │
  ┌────┴────┐   ┌─────┴─────┐   ┌──────┴──────┐  ┌────┴────┐   ┌─────┴─────┐
  │  Resume │   │    Job    │   │  Interview  │  │ Scoring │   │    LLM    │
  │  Agent  │   │  Matcher  │   │    Agent    │  │  Agent  │   │ Providers │
  │ (LLM)   │   │           │   │   (LLM)     │  │  (LLM)  │   │           │
  └────┬────┘   └───────────┘   └─────────────┘  └─────────┘   └───────────┘
       │
       │ dynamically discovers extractors
       ▼
  ┌───────────────────────────────────────────────────────────────────┐
  │                   Extractor Tools                                 │
  │  ┌─────────┐   ┌─────────┐   ┌─────────┐   ┌─────────┐            │
  │  │   PDF   │   │   DOC   │   │  Image  │   │ Future  │            │
  │  │Extractor│   │Extractor│   │  (OCR)  │   │   ...   │            │
  │  └─────────┘   └─────────┘   └─────────┘   └─────────┘            │
  │       tags: [extractor, pdf]  [extractor, doc]  [extractor, ocr]  │
  └───────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key insight: agents powered by &lt;code&gt;@mesh.llm&lt;/code&gt; don't have hardcoded dependencies. They discover tools at runtime — and intelligently choose which ones to use.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Resume Agent
&lt;/h3&gt;

&lt;p&gt;Here's the core of our resume processing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@mesh.llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;capability&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;llm&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tags&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;+claude&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;
    &lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tags&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;extractor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}],&lt;/span&gt;  &lt;span class="c1"&gt;# Discover all extractors
&lt;/span&gt;    &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;You process uploaded resumes.

    Available tools let you extract text from different file formats.
    Choose the appropriate extractor based on the file type.
    Then analyze the extracted text and return structured candidate data.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_iterations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@mesh.tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;capability&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;process_resume&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;resume&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ai&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_resume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;file_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MeshLlmAgent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;CandidateProfile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Process this &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;file_type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; resume: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The magic is in &lt;code&gt;filter=[{"tags": ["extractor"]}]&lt;/code&gt;. The LLM sees every tool tagged with "extractor" — and decides which one to call based on the file type.&lt;/p&gt;

&lt;h3&gt;
  
  
  Day 1: PDF Only
&lt;/h3&gt;

&lt;p&gt;When we launched, we had one extractor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# pdf_extractor.py
&lt;/span&gt;&lt;span class="nd"&gt;@mesh.tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;capability&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;extract_pdf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;extractor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pdf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Extract text content from PDF files&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extract_pdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ExtractedText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# PDF extraction logic
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ExtractedText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{...})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Resume Agent's LLM sees: &lt;code&gt;Available tools: [extract_pdf]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;User uploads &lt;code&gt;resume.pdf&lt;/code&gt; → LLM reasons: "This is a PDF, I'll use extract_pdf" → Extracts text → Returns structured profile.&lt;/p&gt;

&lt;h3&gt;
  
  
  Day 30: Adding Word Support
&lt;/h3&gt;

&lt;p&gt;Product wants Word document support. We write a new extractor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# doc_extractor.py
&lt;/span&gt;&lt;span class="nd"&gt;@mesh.tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;capability&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;extract_doc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;extractor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;doc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;docx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Extract text content from Word documents (.doc, .docx)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extract_doc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ExtractedText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Word extraction logic
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ExtractedText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{...})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deploy to Kubernetes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm &lt;span class="nb"&gt;install &lt;/span&gt;doc-extractor oci://ghcr.io/dhyansraj/mcp-mesh/mcp-mesh-agent &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--version&lt;/span&gt; 0.7.12 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; mcp-mesh &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; doc-extractor/helm-values.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Within 10 seconds&lt;/strong&gt;, the Resume Agent's LLM sees: &lt;code&gt;Available tools: [extract_pdf, extract_doc]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;User uploads &lt;code&gt;resume.docx&lt;/code&gt; → LLM reasons: "This is a Word document, I'll use extract_doc" → Works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No code change to the Resume Agent. No restart. No config update.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Day 60: Image OCR for Scanned Resumes
&lt;/h3&gt;

&lt;p&gt;HR reports that some candidates upload scanned PDFs or photos of their resumes. We add OCR:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# image_extractor.py
&lt;/span&gt;&lt;span class="nd"&gt;@mesh.tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;capability&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;extract_image_ocr&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;extractor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ocr&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;scan&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Extract text from images or scanned documents using OCR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extract_image_ocr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ExtractedText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# OCR logic (Tesseract, Cloud Vision, etc.)
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ExtractedText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;confidence&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.92&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{...})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm &lt;span class="nb"&gt;install &lt;/span&gt;image-extractor oci://ghcr.io/dhyansraj/mcp-mesh/mcp-mesh-agent &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--version&lt;/span&gt; 0.7.12 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; mcp-mesh &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; image-extractor/helm-values.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Resume Agent's LLM now sees: &lt;code&gt;Available tools: [extract_pdf, extract_doc, extract_image_ocr]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;User uploads &lt;code&gt;resume_scan.jpg&lt;/code&gt; → LLM reasons: "This is an image, I'll use extract_image_ocr" → Works.&lt;/p&gt;

&lt;p&gt;But here's where it gets interesting. User uploads a PDF that's actually a scanned image (no selectable text). The LLM:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Tries &lt;code&gt;extract_pdf&lt;/code&gt; → Gets empty/garbled text&lt;/li&gt;
&lt;li&gt;Reasons: "The PDF extraction returned garbage. This might be a scanned document."&lt;/li&gt;
&lt;li&gt;Calls &lt;code&gt;extract_image_ocr&lt;/code&gt; on the same file → Gets clean text&lt;/li&gt;
&lt;li&gt;Returns structured profile&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The agent got smarter. It learned a new recovery strategy without anyone writing that logic.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We didn't tell the Resume Agent about OCR. We didn't update its prompts. We just deployed an extractor with good tags and a clear description — and the LLM figured out when to use it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why This Works
&lt;/h3&gt;

&lt;p&gt;Traditional microservices require explicit wiring:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Traditional approach - hardcoded routing
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_resume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;file_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pdf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;call_pdf_service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;file_type&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;doc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;docx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;call_doc_service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;file_type&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;jpg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;png&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;call_ocr_service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;UnsupportedFormatError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# ...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every new format requires code changes, redeployment, and testing.&lt;/p&gt;

&lt;p&gt;MCP Mesh with &lt;code&gt;@mesh.llm&lt;/code&gt; inverts this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tools self-describe&lt;/strong&gt; — Each extractor has tags and descriptions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLM discovers tools&lt;/strong&gt; — &lt;code&gt;filter=[{"tags": ["extractor"]}]&lt;/code&gt; broadcasts intent&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLM reasons about tools&lt;/strong&gt; — Chooses based on context, not hardcoded rules&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mesh handles routing&lt;/strong&gt; — Tool calls go to the right agent automatically&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Resume Agent's code stays frozen. The platform's capabilities expand with each helm install.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Enterprise Reality
&lt;/h3&gt;

&lt;p&gt;This isn't a toy demo. It's running in production:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Traditional&lt;/th&gt;
&lt;th&gt;MCP Mesh&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Adding new file format&lt;/td&gt;
&lt;td&gt;Code change + deploy + test&lt;/td&gt;
&lt;td&gt;helm install&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Config files for routing&lt;/td&gt;
&lt;td&gt;Per-service&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recovery logic for edge cases&lt;/td&gt;
&lt;td&gt;Manual if/else&lt;/td&gt;
&lt;td&gt;LLM figures it out&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time to add capability&lt;/td&gt;
&lt;td&gt;Hours/days&lt;/td&gt;
&lt;td&gt;Minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Infrastructure&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# One-time cluster setup&lt;/span&gt;
helm &lt;span class="nb"&gt;install &lt;/span&gt;mcp-core oci://ghcr.io/dhyansraj/mcp-mesh/mcp-mesh-core &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--version&lt;/span&gt; 0.7.12 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; mcp-mesh &lt;span class="nt"&gt;--create-namespace&lt;/span&gt;

&lt;span class="c"&gt;# Deploys: Registry + PostgreSQL + Redis + Tempo + Grafana&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same agent code runs locally (&lt;code&gt;meshctl start&lt;/code&gt;), in Docker Compose, and in Kubernetes. Only the infrastructure changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the LLM Sees
&lt;/h3&gt;

&lt;p&gt;When the Resume Agent's LLM runs, it receives a tool list like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tools"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"extract_pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Extract text content from PDF files"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"extractor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pdf"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"input_schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"file_path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"extract_doc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Extract text content from Word documents (.doc, .docx)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"extractor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"doc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"docx"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"input_schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"file_path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"extract_image_ocr"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Extract text from images or scanned documents using OCR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"extractor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ocr"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scan"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"input_schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"file_path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The LLM reads descriptions, understands capabilities, and makes intelligent choices. Add a new tool? It appears in this list within seconds.&lt;/p&gt;

&lt;h3&gt;
  
  
  LLM Failover (Bonus)
&lt;/h3&gt;

&lt;p&gt;We run two LLM providers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm &lt;span class="nb"&gt;install &lt;/span&gt;claude-provider oci://ghcr.io/dhyansraj/mcp-mesh/mcp-mesh-agent &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; claude-provider/helm-values.yaml &lt;span class="nt"&gt;-n&lt;/span&gt; mcp-mesh

helm &lt;span class="nb"&gt;install &lt;/span&gt;openai-provider oci://ghcr.io/dhyansraj/mcp-mesh/mcp-mesh-agent &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; openai-provider/helm-values.yaml &lt;span class="nt"&gt;-n&lt;/span&gt; mcp-mesh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Resume Agent's &lt;code&gt;provider={"capability": "llm", "tags": ["+claude"]}&lt;/code&gt; prefers Claude.&lt;/p&gt;

&lt;p&gt;When Claude's API goes down:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Mesh detects unhealthy (missed heartbeats)&lt;/li&gt;
&lt;li&gt;Topology updates&lt;/li&gt;
&lt;li&gt;Next request routes to OpenAI&lt;/li&gt;
&lt;li&gt;When Claude recovers, traffic returns&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Zero failover code. It's how the mesh works.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's Next
&lt;/h3&gt;

&lt;p&gt;This article showed &lt;strong&gt;what&lt;/strong&gt; we built — an AI platform that genuinely gets smarter as you add capabilities.&lt;/p&gt;

&lt;p&gt;The next article explains &lt;strong&gt;why&lt;/strong&gt; we chose MCP over REST as the foundation — and why that choice matters more than you might think.&lt;/p&gt;

&lt;p&gt;👉 [Next: MCP vs REST — Why MCP is the better microservice protocol]&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dhyansraj/mcp-mesh" rel="noopener noreferrer"&gt;MCP Mesh on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dhyansraj.github.io/mcp-mesh/" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/EkExIyK7ees" rel="noopener noreferrer"&gt;Video: LLM agents using new tools without code changes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>microservices</category>
      <category>architecture</category>
    </item>
    <item>
      <title>MCP Mesh: A Distributed Runtime for AI Agents with Auto-Discovery</title>
      <dc:creator>Dhyan Raj</dc:creator>
      <pubDate>Tue, 23 Dec 2025 17:23:08 +0000</pubDate>
      <link>https://forem.com/dhyan_raj_98e6a5999c8d5ef/mcp-mesh-a-distributed-runtime-for-ai-agents-with-auto-discovery-1pi</link>
      <guid>https://forem.com/dhyan_raj_98e6a5999c8d5ef/mcp-mesh-a-distributed-runtime-for-ai-agents-with-auto-discovery-1pi</guid>
      <description>&lt;p&gt;I've been building MCP Mesh for the past 5 months — a distributed-first runtime for AI agents built on MCP protocol.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Most agent frameworks assume monolithic deployment and manual wiring. You define agents, manually connect them, and hope it scales.&lt;/p&gt;

&lt;p&gt;MCP Mesh takes a different approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes It Different
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Distributed from day one&lt;/strong&gt; — Agents are microservices, not threads in a monolith&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-discovery&lt;/strong&gt; — Agents register with a mesh registry and find each other by capability tags&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency injection&lt;/strong&gt; — Declare what your agent needs, the mesh provides it at runtime&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deterministic behavior&lt;/strong&gt; — Despite being distributed, agent interactions are predictable&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLM failover&lt;/strong&gt; — Switch providers without code changes, just registry config&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native MCP&lt;/strong&gt; — Built on the protocol, not wrapped around it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Observability is built in (Grafana + Tempo), and it's Kubernetes-ready with Helm charts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;📖 Docs: &lt;a href="https://dhyansraj.github.io/mcp-mesh/" rel="noopener noreferrer"&gt;https://dhyansraj.github.io/mcp-mesh/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🎥 Video tutorials (34 min total): &lt;a href="https://www.youtube.com/watch?v=GpCB5OARtfM" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=GpCB5OARtfM&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 GitHub: &lt;a href="https://github.com/dhyansraj/mcp-mesh" rel="noopener noreferrer"&gt;https://github.com/dhyansraj/mcp-mesh&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Would love feedback from anyone building agent systems. What problems are you hitting that current frameworks aren't solving?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>mcp</category>
      <category>kubernetes</category>
    </item>
  </channel>
</rss>
