December 12, 2025 in platform, architecture by Nicolas Payneau, Dimitri Tombroff7 minutes
Fred now supports A2A agents alongside MCP agents. Developers can deploy standalone, language-agnostic agents and register them in Fred as first-class citizens. A new agentic bridge handles protocol translation, streaming adaptation, UI rendering, and security integration—unlocking industrial-grade agent development.
Fred started as an opinionated, production-ready agentic platform: UI, orchestration, security, observability, and a strong knowledge backbone out of the box. But until recently, agents themselves mostly lived inside the Fred backend, written in Python and wired through MCP.
That model works well for experimentation—but it limits how far teams can go when agents become business-critical, real-time, or regulated.
This release changes that boundary. Fred now supports A2A-standard agents as first-class citizens, enabling teams to build agents in Java, Rust, Go, Python—or anything else, deploy them independently, and plug them into Fred with no loss of UI, streaming, or security guarantees.
Agent frameworks have matured quickly, but most remain optimized for Python-only development, single-process execution, and experimental or exploratory use cases. That is adequate for research, but less so when latency, memory determinism, and security isolation matter, or when teams need to use established stacks such as Spring Boot, Rust async runtimes, and Go services. In short, industrial agents need industrial architecture.
Fred’s agentic backend is a Python-centric application leveraging LangChain/LangGraph. It already does its best with async execution and scales horizontally, but it is expected to scale even better with A2A agents running as standalone services. Here is a look at its current architecture:
%%{init: {"themeVariables": {"fontSize": "16px"}}}%%
flowchart LR
%% =========================
%% BEFORE: Agents are inside the Agentic Backend (Python-bound)
%% =========================
subgraph UI["🧑 React UI"]
UChat["Chat UI"]
UAdmin["Agent Hub (Create/Edit)"]
end
subgraph AB["🧠 Fred Agentic Backend"]
Fred["Fred Orchestrator"]
PyAgents["Python Agents\n"]
Tools["Tool Access\n(MCP + REST)"]
end
subgraph KF["📚 Knowledge Flow"]
KFApi["Docs/Data APIs"]
Stores["Vector + Tabular Stores"]
MCP["MCP Server"]
end
MCP3P["3rd-Party MCP Servers"]
UChat -->|"WebSocket + REST"| Fred
UAdmin -->|"Agent config (internal only)"| PyAgents
Fred -->|"delegates"| PyAgents
PyAgents -->|"tool calls"| Tools
Tools --> MCP
Tools --> MCP3P
Tools --> KFApi
KFApi --> Stores
%% Visual emphasis
style UI fill:#EAF2FF,stroke:#3B4A6B,stroke-width:1.2px
style AB fill:#FFEFE0,stroke:#7A4A21,stroke-width:1.2px
style KF fill:#E9FFE9,stroke:#2E6B2E,stroke-width:1.2px
style Fred fill:#FFD9B3,stroke:#7A4A21,stroke-width:1.4px
style PyAgents fill:#FFF2CC,stroke:#6B5A1F,stroke-width:1.4px
style Tools fill:#FFF7E6,stroke:#7A4A21,stroke-dasharray: 4 3
style MCP fill:#E6F7FF,stroke:#1C6B8A,stroke-width:1.2px
style MCP3P fill:#E6F7FF,stroke:#1C6B8A,stroke-width:1.2px,stroke-dasharray: 5 3
style KFApi fill:#DFF6DF,stroke:#2E6B2E,stroke-width:1.2px
style Stores fill:#F4FFF4,stroke:#2E6B2E,stroke-dasharray: 5 4
The introduction of A2A agents is already a major step toward a more robust architecture, as the following diagram shows.
Agent-to-Agent (A2A) is treated in Fred as a protocol boundary, not a convenience API. An A2A agent is a standalone service deployed independently (often as its own Kubernetes pod), implemented in any language, and exposing a standard A2A interface (agent card, message send, streaming). Fred does not embed that agent. Instead, it connects to it.
flowchart LR
%% =========================
%% AFTER: A2A agents are external services, first-class in Fred
%% =========================
subgraph UI["🧑 React UI"]
UChat["Chat UI\n(streaming + rich rendering)"]
UAdmin["Agent Hub\n(register external A2A agents)"]
end
subgraph AB["🧠 Fred Agentic Backend"]
Fred["Fred Orchestrator"]
Registry["A2A Agent Registry\n(URL + auth)"]
end
subgraph A2A["🧩 External A2A Agents\n"]
AgentJava["Java / Spring Boot\nAgent"]
AgentRust["Rust\nAgent"]
AgentGo["Go\nAgent"]
AgentPy["Python\nAgent "]
end
%% User interactions
UChat -->|"WebSocket + REST"| Fred
UAdmin -->|"register A2A agent"| Registry
Registry -->|"available agents"| Fred
%% A2A connectivity
Fred -->|"A2A"| AgentJava
Fred -->|"A2A"| AgentRust
Fred -->|"A2A"| AgentGo
Fred -->|"A2A"| AgentPy
%% Visual emphasis
style UI fill:#EAF2FF,stroke:#3B4A6B,stroke-width:1.2px
style AB fill:#FFEFE0,stroke:#7A4A21,stroke-width:1.2px
style A2A fill:#F2ECFF,stroke:#4B3B7A,stroke-width:1.2px
style Fred fill:#FFD9B3,stroke:#7A4A21,stroke-width:1.4px
style Registry fill:#FFE1BF,stroke:#7A4A21,stroke-width:1.3px
style AgentJava fill:#EFE6FF,stroke:#4B3B7A,stroke-width:1.2px
style AgentRust fill:#EFE6FF,stroke:#4B3B7A,stroke-width:1.2px
style AgentGo fill:#EFE6FF,stroke:#4B3B7A,stroke-width:1.2px
style AgentPy fill:#EFE6FF,stroke:#4B3B7A,stroke-width:1.2px
Fred initially supported MCP agents that are dynamically assembled, tool-driven, and hosted inside Fred. The backend now also includes an A2A bridge that allows users to create external, standalone, protocol-driven agents in the UI. When a user creates an A2A agent, Fred registers the remote A2A endpoint, instantiates an internal proxy agent, and routes user interactions through that proxy. From the UI’s perspective, this agent behaves like any other.
A design constraint was that A2A agents should not degrade the Fred UI experience. The bridge receives A2A streaming messages, incremental outputs, final responses, and structured artifacts, and translates them into Fred’s internal message model. This preserves live streaming, message grouping, structured rendering, source blocks with metadata, and consistent history replay.
External A2A agents run in separate processes and can be deployed in their own Kubernetes namespaces. Each agent can join SSO independently (for example via Keycloak) and enforce its own authorization rules; Fred does not impersonate the agent and instead integrates with it. This supports clear trust boundaries, least-privilege access, auditable cross-agent calls, and independent lifecycle management, which are important in regulated environments.
The A2A bridge removes a single-runtime constraint and allows teams to implement agents in different languages and ecosystems based on operational needs. For example, Rust can be used for low-latency workflows, Java or Spring Boot for integration with existing enterprise systems, Go for network-heavy or concurrent services, and Python where iteration speed is important. Regardless of implementation, these agents can consume Fred’s Knowledge Flow APIs (documents, vectors, SQL-like tabular access), expose results through A2A, and appear in the Fred UI as first-class agents.
Knowledge Flow predates A2A and remains an independent set of services for documents, vectors, tabular data, and content delivery. It exposes these capabilities through REST and MCP APIs, so any A2A agent can use standard REST or MCP libraries to access them. This allows external agents to benefit from Knowledge Flow services without requiring a shared runtime. Two common examples are retrieval-augmented generation and content delivery: an agent can use Knowledge Flow to retrieve documents for a report, and then publish the report so the user can download it later. These patterns are useful but nontrivial to implement consistently without platform support.
flowchart LR
A2A["A2A Agent"]
subgraph KF["Knowledge Flow Services"]
Vectors["Vectors"]
SQL["SQL"]
Content["Content"]
Tags["Tags"]
Graph["Graph"]
Supervision["Supervision"]
Connectors["Connectors"]
end
subgraph Enterprise["Enterprise Services"]
ERP["ERP / CRM"]
Data["Data Warehouses"]
IdP["Internal APIs"]
end
subgraph Public["Public Online Services"]
SaaS["SaaS APIs"]
Web["Public Web"]
end
A2A -->|"REST / MCP"| KF
A2A -->|"REST / gRPC"| Enterprise
A2A -->|"HTTPS"| Public
%% Visual emphasis
style A2A fill:#F2ECFF,stroke:#4B3B7A,stroke-width:1.2px
style KF fill:#E9FFE9,stroke:#2E6B2E,stroke-width:1.2px
style Enterprise fill:#EAF2FF,stroke:#3B4A6B,stroke-width:1.2px
style Public fill:#FFF4E5,stroke:#8A5A2E,stroke-width:1.2px
style Vectors fill:#F4FFF4,stroke:#2E6B2E,stroke-width:1px
style SQL fill:#F4FFF4,stroke:#2E6B2E,stroke-width:1px
style Content fill:#F4FFF4,stroke:#2E6B2E,stroke-width:1px
style Tags fill:#F4FFF4,stroke:#2E6B2E,stroke-width:1px
style Graph fill:#F4FFF4,stroke:#2E6B2E,stroke-width:1px
style Supervision fill:#F4FFF4,stroke:#2E6B2E,stroke-width:1px
style Connectors fill:#F4FFF4,stroke:#2E6B2E,stroke-width:1px
style ERP fill:#F4F8FF,stroke:#3B4A6B,stroke-width:1px
style Data fill:#F4F8FF,stroke:#3B4A6B,stroke-width:1px
style IdP fill:#F4F8FF,stroke:#3B4A6B,stroke-width:1px
style SaaS fill:#FFF8EF,stroke:#8A5A2E,stroke-width:1px
style Web fill:#FFF8EF,stroke:#8A5A2E,stroke-width:1px
This section provides a short example to make the bridge concrete and to support the accompanying demo. The goal is to expose an agent card, handle the JSON-RPC message/send call, and connect it to Spring AI for model responses.
An A2A agent publishes a small JSON agent card at /.well-known/agent-card.json that describes the agent and its endpoint. The primary JSON-RPC method is message/send for a single response, with optional streaming via message/stream. The endpoints are standard HTTP, so the structure resembles other service-to-service APIs in Spring Boot.
Below is a minimal slice from a Spring Boot app. It returns the agent card and routes message/send requests to Spring AI. The intent is to show the integration without additional abstraction.
@RestController
class A2aController {
private final AgentService agentService;
A2aController(AgentService agentService) {
this.agentService = agentService;
}
@GetMapping(path = "/.well-known/agent-card.json")
AgentCard agentCard() {
return new AgentCard(
"0.3.0",
"Java A2A OpenAI Agent",
"http://localhost:9999/",
"JSONRPC"
);
}
@PostMapping(path = "/", consumes = "application/json", produces = "application/json")
Mono<JsonRpc.Response> messageSend(@RequestBody JsonRpc.Request req) {
String answer = agentService.ask(extractText(req));
return Mono.just(JsonRpc.Response.ok(req.id(), answer));
}
}And the service is essentially a one-liner around Spring AI’s ChatClient:
@Service
class AgentService {
private final ChatClient chat;
AgentService(ChatClient.Builder builder) {
this.chat = builder.build();
}
String ask(String userText) {
return chat.prompt().user(userText).call().content();
}
}This illustrates the core wiring: A2A provides the interoperable contract, and Spring AI handles the model call through the standard Spring programming model.
For teams that already use Spring, the example relies on familiar controllers, dependency injection, and configuration. Existing production practices for security, tracing, and deployment can remain in place. Spring AI also abstracts the model client so the implementation is not tied to a single provider.
This post shows how adding A2A alongside MCP opens a wider design space: agents can be orchestrated across runtimes, security boundaries can be tested in realistic deployments, and streaming UX remains consistent. With a fully deployable, open-source stack, Fred makes it practical to explore these topics end-to-end on cloud or on-premises infrastructure, and to do so collaboratively with the community.