Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
282 changes: 282 additions & 0 deletions MULTI_PROTOCOL_SUPPORT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,282 @@
# Multi-Protocol Support in a2ajava

The a2ajava framework now supports three major agent protocols, making it the most comprehensive agent integration platform available:

1. **A2A (App-to-App)** - Google's JSON-RPC based protocol
2. **MCP (Model Context Protocol)** - LLM communication protocol
3. **ACP (Agent Connect Protocol)** - Cisco's REST-based protocol

## Overview

All three protocols work seamlessly with the same underlying agent implementations using `@Agent` and `@Action` annotations. The framework automatically handles protocol translation and routing.

## Agent Implementation

Create agents using standard annotations that work with all protocols:

```java
@Agent(groupName = "customer support", groupDescription = "actions related to customer support")
public class CustomerSupportAgent {

@Action(description = "Create a support ticket for customer issues")
public String createTicket(String customerName, String issue) {
return "Ticket created for " + customerName + ": " + issue;
}

@Action(description = "Check the status of an existing ticket")
public String checkTicketStatus(String ticketId) {
return "Ticket " + ticketId + " is in progress";
}
}
```

## A2A Protocol Usage

A2A uses JSON-RPC for communication. Here's how to interact with agents:

### Client Example
```java
// A2A JSON-RPC client
JsonRpcController controller = new JsonRpcController(applicationContext);

// Get agent card
AgentCard card = controller.getAgentCard();

// Execute action
Map<String, Object> params = Map.of(
"customerName", "John Doe",
"issue", "Login problem"
);
String result = controller.executeAction("createTicket", params);
```

### JSON-RPC Request
```json
{
"jsonrpc": "2.0",
"method": "createTicket",
"params": {
"customerName": "John Doe",
"issue": "Login problem"
},
"id": 1
}
```

## MCP Protocol Usage

MCP is designed for LLM communication with structured tool calling:

### Client Example
```java
// MCP client
MCPToolsController mcpController = new MCPToolsController(applicationContext);

// List available tools
ListToolsResult tools = mcpController.listTools();

// Call tool
CallToolRequest request = new CallToolRequest();
request.setName("createTicket");
request.setArguments(Map.of(
"customerName", "Jane Smith",
"issue", "Payment issue"
));

CallToolResult result = mcpController.callTool(request);
```

### MCP Tool Call
```json
{
"method": "tools/call",
"params": {
"name": "createTicket",
"arguments": {
"customerName": "Jane Smith",
"issue": "Payment issue"
}
}
}
```

## ACP Protocol Usage

ACP uses REST endpoints for agent interaction:

### Client Example
```java
// ACP REST client
ACPRestController acpController = new ACPRestController(applicationContext);

// Search agents
AgentSearchRequest searchRequest = new AgentSearchRequest();
searchRequest.setQuery("customer support");
List<Agent> agents = acpController.searchAgents(searchRequest).getBody();

// Create stateless run
RunCreateStateless runRequest = new RunCreateStateless();
runRequest.setAgentId(agents.get(0).getAgentId());
runRequest.setInput(Map.of(
"customerName", "Bob Wilson",
"issue", "Account locked"
));

AgentRun run = acpController.createStatelessRun(runRequest).getBody();
```

### REST API Calls
```bash
# Search agents
curl -X POST http://localhost:8080/acp/agents/search \
-H "Content-Type: application/json" \
-d '{"query": "customer support", "limit": 10}'

# Get agent details
curl http://localhost:8080/acp/agents/{agent-id}

# Create stateless run
curl -X POST http://localhost:8080/acp/runs \
-H "Content-Type: application/json" \
-d '{
"agent_id": "550e8400-e29b-41d4-a716-446655440000",
"input": {
"customerName": "Bob Wilson",
"issue": "Account locked"
}
}'
```

## Stateful vs Stateless Execution

### ACP Stateful Execution with Threads
```java
// Create thread for stateful conversation
Map<String, Object> metadata = Map.of("session", "customer-session-123");
Thread thread = acpController.createThread(metadata).getBody();

// Create stateful run
RunCreateStateful statefulRequest = new RunCreateStateful();
statefulRequest.setAgentId(agentId);
statefulRequest.setThreadId(thread.getThreadId());
statefulRequest.setInput(Map.of("customerName", "Alice Brown"));

AgentRun run = acpController.createStatefulRun(
thread.getThreadId(),
statefulRequest
).getBody();
```

### A2A Task-based Execution
```java
// A2A uses Task model for state management
Task task = new Task();
task.setId("task-123");
task.setSessionId("session-456");

// Execute with task context
controller.executeWithTask(task, "createTicket", params);
```

## Protocol Comparison

| Feature | A2A | MCP | ACP |
|---------|-----|-----|-----|
| Transport | JSON-RPC | JSON-RPC | REST |
| State Management | Task-based | Stateless | Thread-based |
| Agent Discovery | AgentCard | Tool listing | Agent search |
| Streaming | Yes | Yes | Yes |
| Authentication | Custom | Custom | REST standard |
| Use Case | App integration | LLM tools | Enterprise agents |

## Configuration

### Spring Boot Configuration
```java
@Configuration
public class MultiProtocolConfig {

@Bean
public JsonRpcController a2aController(ApplicationContext context) {
return new SpringAwareJSONRpcController(context);
}

@Bean
public MCPToolsController mcpController(ApplicationContext context) {
return new SpringAwareMCPToolsController(context);
}

@Bean
public ACPRestController acpController(ApplicationContext context) {
return new SpringAwareACPController(context);
}
}
```

### Application Properties
```properties
# Enable all protocols
a2a.enabled=true
mcp.enabled=true
acp.enabled=true

# Protocol-specific settings
acp.base-url=http://localhost:8080/acp
a2a.jsonrpc.endpoint=/jsonrpc
mcp.tools.endpoint=/mcp
```

## Testing All Protocols

The framework includes comprehensive tests for all protocols:

```java
@Test
void testMultiProtocolIntegration() {
// Test A2A
String a2aResult = a2aController.executeAction("createTicket", params);

// Test MCP
CallToolResult mcpResult = mcpController.callTool(mcpRequest);

// Test ACP
AgentRun acpResult = acpController.createStatelessRun(acpRequest).getBody();

// All should produce equivalent results
assertThat(a2aResult).contains("Ticket created");
assertThat(mcpResult.getContent()).contains("Ticket created");
assertThat(acpResult.getStatus()).isEqualTo(AgentRun.RunStatus.success);
}
```

## Best Practices

1. **Single Agent Implementation**: Write agents once using `@Agent`/`@Action` annotations
2. **Protocol Selection**: Choose protocol based on client needs:
- A2A for app-to-app integration
- MCP for LLM tool calling
- ACP for enterprise REST APIs
3. **State Management**: Use appropriate state models for each protocol
4. **Error Handling**: Implement consistent error handling across protocols
5. **Testing**: Test agents with all three protocols to ensure compatibility

## Migration Guide

### From A2A-only to Multi-Protocol

1. Add ACP and MCP dependencies to `pom.xml`
2. Configure additional controllers in Spring
3. Existing `@Agent`/`@Action` code works unchanged
4. Add protocol-specific endpoints as needed

### Protocol-Specific Considerations

- **A2A**: Maintains backward compatibility
- **MCP**: Requires tool schema definitions
- **ACP**: Needs REST endpoint configuration

## Conclusion

The a2ajava framework's multi-protocol support enables seamless agent integration across different ecosystems. Whether you're building LLM tools, enterprise APIs, or app integrations, a single agent implementation works across all three major protocols.

For more examples and detailed API documentation, see the individual protocol documentation in the `/docs` directory.
16 changes: 8 additions & 8 deletions README.MD
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Java Implementation of Google's A2A Protocol: Connecting the Agentverse

This project provides a Java implementation for both an A2A (Agent-to-Agent) server and client.
**A2A is an open protocol developed by Google** to standardize how AI agents communicate and exchange information, fostering a vibrant ecosystem of interoperable AI. This api also supports building MCP Servers in Java with use of simple annotations. Imagine a world where diverse AI agents, built with different tools and by different creators, can seamlessly collaborate to solve complex problems - that's the vision A2A is bringing to life. This implementation demonstrates how to set up this communication in Java, using the Spring Framework, with a focus on sending and retrieving tasks.
a2ajava is a Swiss Army knife for building agentic applications. It is multi-protocol — works seamlessly with both A2A (Agent-to-Agent) and MCP (Model Context Protocol). It is multi-language — supports Java, Kotlin, and Groovy. It is multi-platform — compatible with Gemini, OpenAI, Claude, and Grok. It is multi-client — includes A2A and MCP clients with connectors in Java, Node, and Python. It offers multi-integration — out-of-the-box support for Selenium, human-in-the-loop workflows, and multi-LLM voting for consensus-based decision making. Agents built using the A2A protocol with a2ajava run seamlessly on MCP as well, ensuring maximum interoperability across platforms.
This project provides a Java implementation for A2A (Agent-to-Agent), MCP (Model Context Protocol), and ACP (Agent Connect Protocol) servers and clients.
**A2A is an open protocol developed by Google** to standardize how AI agents communicate and exchange information, fostering a vibrant ecosystem of interoperable AI. This api also supports building MCP Servers and ACP agents in Java with use of simple annotations. Imagine a world where diverse AI agents, built with different tools and by different creators, can seamlessly collaborate to solve complex problems - that's the vision these protocols are bringing to life. This implementation demonstrates how to set up this communication in Java, using the Spring Framework, with a focus on sending and retrieving tasks.
a2ajava is a Swiss Army knife for building agentic applications. It is multi-protocol — works seamlessly with A2A (Agent-to-Agent), MCP (Model Context Protocol), and ACP (Agent Connect Protocol). It is multi-language — supports Java, Kotlin, and Groovy. It is multi-platform — compatible with Gemini, OpenAI, Claude, and Grok. It is multi-client — includes A2A, MCP, and ACP clients with connectors in Java, Node, and Python. It offers multi-integration — out-of-the-box support for Selenium, human-in-the-loop workflows, and multi-LLM voting for consensus-based decision making. Agents built using any protocol with a2ajava run seamlessly on all three protocols, ensuring maximum interoperability across platforms.

[![Need More Info? Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/vishalmysore/a2ajava) [![codecov](https://codecov.io/gh/vishalmysore/a2ajava/graph/badge.svg?token=HieisRv0xC)](https://codecov.io/gh/vishalmysore/a2ajava)
<a target="_blank" href="https://sonarcloud.io/summary/new_code?id=vishalmysore_a2ajava"><img src="https://sonarcloud.io/api/project_badges/measure?project=vishalmysore_a2ajava&metric=alert_status"/></a>
Expand Down Expand Up @@ -75,15 +75,15 @@ Live demos have been deployed on hugginface you are welcome to try them out. Or
## Whats so special about A2AJava library?

You can simple annotate your classes with @Agent and @Action and build a server. The library will take care of the rest. You can also use this library to build a client to send and receive messages from the server. The library is built on top of Spring Boot and uses Jackson for JSON serialization/deserialization. The library is designed to be easy to use and extend, so you can build your own agents quickly and easily.
ALl methods annotated with @Action are exposed as A2A tasks and also MCP tools you dont need to do anything .
All methods annotated with @Action are exposed as A2A tasks, MCP tools, and ACP runs - you don't need to do anything extra.
Infuse AI in any running application

You can convert you entire springboot based application into a2a and mcp compliant agent by using these 4 annotations:
You can convert your entire springboot based application into A2A, MCP, and ACP compliant agent by using these 4 annotations:

```java

1 @EnableAgent - converts your springboot application into an A2A agent
2 @EnabaleAgentSecurity- adds security features to your agent
1 @EnableAgent - converts your springboot application into an A2A/MCP/ACP agent
2 @EnableAgentSecurity - adds security features to your agent
3 @Agent(groupName = "", groupDescription = "") - creates an agent group
4 @Action(description = "") - creates an action within the agent group

Expand Down Expand Up @@ -257,7 +257,7 @@ Contributions are welcome! Please feel free to submit a Pull Request. For major

* The A2A and MCP protocol is an evolving standard, and this implementation may need to be updated as the protocols matures. Always refer to the official A2A documentation for the latest specifications and best practices.
* This implementation is not affiliated with or endorsed by Google or Anthropic. It is my independent effort to demonstrate the A2A and MCP protocol in Java.
* Unit test coverage needs to be enhanced , will be working on it
* Unit test coverage needs to be enhanced , will be working on it



Expand Down
35 changes: 30 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
</scm>

<properties>
<maven.compiler.source>18</maven.compiler.source>
<maven.compiler.target>18</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<langchain4j.version>0.29.1</langchain4j.version>
<slf4j.version>2.0.16</slf4j.version>
Expand Down Expand Up @@ -200,6 +200,19 @@
<version>5.0.0</version> <!-- Replace with the latest version -->
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.2.0</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>3.2.0</version>
<scope>test</scope>
</dependency>

</dependencies>

Expand Down Expand Up @@ -253,14 +266,26 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>18</source>
<target>18</target>
<source>17</source>
<target>17</target>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>

</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M9</version>
<configuration>
<includes>
<include>**/*Test.java</include>
<include>**/*Tests.java</include>
</includes>
</configuration>
</plugin>


<plugin>
Expand Down Expand Up @@ -339,4 +364,4 @@
</plugins>
</build>

</project>
</project>
Loading
Loading