Re-architecting for the Agentic AI Future
Ten years ago, software development teams adopted a new trend: companies were breaking their large applications into smaller, independent services, an emerging pattern now known as microservices. The idea was simple: instead of one giant application, build many small services that work together. Each team could develop and deploy their piece independently. It seemed perfect.
But as companies added more services, a new problem emerged. How do you manage communication between hundreds of services? Where is each service located? How do you balance the load? What happens when a service fails? These questions, trivially solved within a single application, now require solutions across an entire network.
The Java community pioneered early solutions. Frameworks like Spring Cloud introduced tools such as Eureka for finding services and OpenFeign for calling them. Developers no longer needed to remember specific network addresses. They could simply reference a service by name, like “payment-service”, and the framework handled the rest.
This pattern proved so valuable that it evolved beyond Java. When containers became popular, the concept transformed into what we now call a service mesh. Tools like Istio and Linkerd moved service management completely outside the application code. They created an infrastructure layer that handled reliability, security, and traffic management automatically.

The service mesh fundamentally changed how we think about connecting services. Instead of hardcoding IP addresses and ports, developers referenced services by their functional purpose. The mesh infrastructure took care of everything else: finding the service, routing traffic, handling failures, and managing security. This abstraction was revolutionary. It separated what a service does from how to reach it.
MCP: The Rise of AI Agents
Today, we are witnessing another transformation. Generative AI and intelligent agents are changing how systems work together. The difference is profound.
In traditional service mesh architecture, developers manually orchestrate workflows. They decide which services to call and in what order. A developer writes code that says: “First, validate the user. Then, check the inventory. Finally, process the payment.” Every step is explicitly programmed.
AI agents operate differently. They can reason about what a user wants (intent detection) and autonomously decide how to accomplish it. They don’t follow a predefined script. Instead, they understand intent and compose solutions dynamically.
This shift creates a major distinction. Service mesh focuses on functionality, i.e. what technical operations a service provides. AI agents, however, need to understand capabilities, what business goals a system can achieve, what outcomes it guarantees, and what constraints it operates under.
Consider payment processing. In traditional architecture, a developer explicitly calls specific methods: PaymentService.creditCard() or PaymentService.directDebit(). The developer chooses the implementation.
With AI agents, the approach changes. An agent doesn’t care about implementation details. It queries a registry for agents that have the capability to “accept payment from users.” The registry returns all available options: credit card, direct debit, digital wallet, or cryptocurrency. The agent then selects the most appropriate method based on context, user preference, and business rules.

Enter the Capability Mesh
This evolution demands a new architectural paradigm: the Capability Mesh. In this model, capabilities, not services, become the primary building blocks. Agents reference each other not by technical names or network endpoints, but by the capabilities they provide.
The architecture combines several elements. Self-Contained Systems (SCS) provide the foundation, independent systems that own their data and UI. The Model Context Protocol (MCP) replaces traditional REST APIs with semantic descriptions that emphasize intent and outcomes. MCP registries maintain catalogs of available capabilities. MCP gateways act as control planes, managing how agents discover and access capabilities.
The infrastructure is already emerging. MCP is reimagining how we describe system capabilities. Agent orchestrators like Claude and GPT are learning to autonomously compose capabilities into workflows. The technical pieces exist. What we need now is a fundamental shift in how we think about distributed systems.

Why Self-Contained Agents Matter
The Capability Mesh builds on Self-Contained Systems for three important reasons. First, these systems emphasize idempotency. This means an operation produces the same result whether it runs once or multiple times. In a world where agents might retry actions or execute them in unexpected sequences, this predictability is essential.
Second, Self-Contained Systems enforce strict isolation. Services do not communicate directly with each other. They operate independently. This isolation gives agents true autonomy. Each capability stands alone. An agent can combine capabilities freely without worrying about hidden connections or unexpected interactions between services.
Third, these systems favor integration at a higher level, not within the service logic itself. Empirically Self-Contained Systems, encourage integration at UI Level and not in-between the Services meaning that services do not coordinate with each other internally. The same happens in Capability Mesh Architecture, as integration does not happen within the agents but instead, coordination happens through the orchestrator. This design places responsibility exactly where it belongs: with the intelligent agent that understands what the user wants and can decide how capabilities should work together.
These three principles transform services from connected components into independent capabilities. Agents can discover them, understand them, and compose them autonomously. This foundation makes the Capability Mesh possible.

The Challenge of Non-Determinism
This new architecture introduces a significant challenge: non-determinism. Traditional systems are predictable: you call a service, you get a result. You can trace every step. With AI agents, unpredictability is inherent. Large Language Models don’t always produce the same output for the same input. Agent decisions can vary based on subtle context changes.
This unpredictability worries many organizations. The common response is to require “human in the loop”, having people review and approve every significant agent action. While this improves safety, it defeats the purpose of autonomous agents. If humans must approve every decision, we’ve simply created a more expensive and slow version of traditional automation.
Policy as Code: The Real Solution
The answer lies in a different approach: policy as code. Instead of reviewing individual actions, we define deterministic boundaries that govern agent behavior. We establish rules that specify what agents can and cannot do, what side effects are acceptable, and what constraints must always be honored.
Think of it like city planning. We don’t approve of every individual’s daily route. Instead, we build roads, traffic lights, and signs that guide everyone safely to their destinations. We set speed limits, define right-of-way rules, and establish zones where certain activities are prohibited. The system provides freedom within defined boundaries.
Policy as code works similarly. We create computational guardrails that prevent undesired agent behaviors before they occur. These policies are deterministic and enforceable. They don’t rely on catching mistakes after the fact; they prevent mistakes from happening.
This shifts the human role from “human in the loop” to “human on the loop.” People are no longer decision-makers for every action. Instead, they become architects and governors. They design the landscape of capabilities, establish the policies that guide agent behavior, and supervise the overall system. They define what success means and where the boundaries lie, then let agents execute autonomously within those constraints.
This is preventive risk management, not mitigative. We don’t wait for problems to occur and then fix them. We design the system to prevent problems in the first place.

A Fundamental Shift
The transition from Service Mesh to Capability Mesh represents more than a technical upgrade. It requires a new mindset about how we build distributed systems. We must move from thinking about services and functions to thinking about capabilities and outcomes. From manual orchestration to policy-driven governance. From human approval of every action to human design of the decision space.
Agents navigate situations that are far more complex than what developers managed in the service mesh era. But the opportunity is equally profound: systems that can understand intent, compose solutions dynamically, and operate autonomously within well-defined boundaries.
The future of distributed systems is not defined by simply removing humans or by forcing them into a “human-in-the-loop” approval process, which is often an insufficient, slow, and expensive form of risk mitigation. The solution lies in a more fundamental architectural shift: designing systems for inherent autonomy and resilience. This transition elevates the role of the developer and designer from manually orchestrating workflows to strategically governing the system’s operational boundaries. By defining deterministic policies, we ensure that agents can operate autonomously and dynamically, yet only within guardrails that prevent undesirable actions. This focus on governance over execution is the defining change of the Capability Mesh.

This article is part of the JAVAPRO special magazine issue:
Java in the Age of AI
Explore how AI is transforming the way we build, secure, and operate software with Java.
From AI agents and new architectural patterns to security, data, and team dynamics—this edition brings together real-world insights for building intelligent, production-ready systems.
Discover the edition →