Why?

 

 

 

Well, actually, one of my customers is pretty advanced, has deployed many commercial agents, and is looking for help with orchestrating those agents. I had been reading about Model Context Protocol (MCP)  and A2A recently, and it was time to get my hands on A2A. (Oh, you can find my simple MCP repo here) Also, the Python samples provided at the A2A repo did not all work for me. Plus, chicken safety 🙂

Why is the A2A Protocol useful?

Traditional REST APIs are great, but they lack the structured messaging, correlation tracking, and service discovery features that modern distributed systems need. A2A protocol brings:

  • Structured Messaging: Every message includes version info, timestamps, sender/recipient details, and correlation IDs
  • Built-in Traceability: Request-response correlation makes debugging and monitoring easier
  • Service Discovery: Clients can automatically discover what services are available and how to use them
  • Error Handling: Standardized error responses that machines can parse and react to

By implementing A2A for something as simple as chicken food safety, I could investigate these helpful concepts and understand the benefits of A2A.

 

How?

The technical architecture

My A2A experiment consists of three main components:

1. The A2A Server

Built with Python, the server implements the A2A protocol in JSON:

def create_a2a_response(request_msg, success=True, result=None, error=None):
    """Create a standard A2A JSON response message"""
    response = {
        "version": "1.0",
        "id": str(uuid.uuid4()),
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "type": "response",
        "correlation_id": request_msg.get("id"),
        # ... sender/recipient info
        "payload": {
            "success": success,
            "service": "chicken_food_safety_check"
        }
    }
    return response

The server maintains a simple database of 50+ foods categorized as safe, unsafe, or unknown for chickens. From grains like corn and wheat to dangerous items like chocolate and raw beans.

2. The A2A Client

The client uses a standard A2A JSON format for requests and responses:

def create_a2a_request(self, food_item):
    """Create a standard A2A JSON request message"""
    return {
        "version": "1.0",
        "id": str(uuid.uuid4()),
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "type": "request",
        "sender": {
            "agent_id": self.client_id,
            "name": self.client_name,
            "version": self.version
        },
        "payload": {
            "service": "chicken_food_safety_check",
            "food_item": food_item
        }
    }

3. Service discovery and health monitoring

Service discovery is one of the major values of A2A, as well as service health. These can be queried from the server using standard A2A endpoints: 

  • Service Discovery (/a2a/discovery): Lists available services and their schemas
  • Health Checks (/health): Monitors service status
  • Logging: Tracks all A2A interactions for debugging

Using UV for Python Management

 

UV is a python management tool that is new for me and makes creating virtual environments and installing dependencies easier than other python tools. Using UV for project setup and execution is simple:

uv sync
uv run a2a-server  # Start the server
uv run a2a-client --food "corn"  # Test a food item

A2A message flow example

Here's what happens when you ask "Is corn safe for chickens?":

  1. Client Request: Formats an A2A message with unique ID, timestamp, and food item
  2. Server Validation: Validates A2A message format and required fields
  3. Database Lookup: Checks corn against the food safety database
  4. A2A Response: Returns structured response with correlation ID linking back to the request
  5. Client Processing: Validates response and displays user-friendly result

What?

What was built

The final system is an A2A implementation that:

  • Validates Food Safety: Checks 50+ foods against a veterinary-compiled database
  • Implements A2A Protocol: Full compliance with message formatting, correlation IDs, and service discovery
  • Provides Multiple Interfaces: Interactive CLI, single-query mode, and raw HTTP API
  • Includes Observability: Health checks, service discovery, and logging
  • Supports Integration: RESTful endpoints that any system can consume

Interaction methods

For Chicken "Tenders" (aka Humans):

# Interactive mode - ask about any food
uv run a2a-client
Enter food item: chocolate
❌ Food Safety Check Result:
Status: UNSAFE
Message: chocolate is NOT safe for chickens and should be avoided.

For Developers or other Agents:

# Discover available services via http
$ curl http://localhost:8080/a2a/discovery | jq
{
  "services": [
    {
      "description": "Check if a food item is safe for chickens",
      "endpoint": "/a2a/chicken-food-safety",
      "input_schema": {
        "properties": {
          "food_item": {
            "description": "Name of the food item to check",
            "type": "string"
          }
        },
        "required": [
          "food_item"
        ],
        "type": "object"
      },
      "method": "POST",
      "name": "chicken_food_safety_check"
    }
  ]
}
# Make A2A requests via http
curl -X POST http://localhost:8080/a2a/chicken-food-safety \
  -H "Content-Type: application/json" \
  -d '{
    "version": "1.0",
    "id": "test-001",
    "timestamp": "2025-08-28T12:00:00Z",
    "type": "request",
    "sender": {
      "agent_id": "curl-client",
      "name": "Curl Client",
      "version": "1.0"
    },
    "payload": {
      "service": "chicken_food_safety_check",
      "food_item": "avocado"
    }
  }' | jq
  

{
  "correlation_id": "test-001",
  "id": "6ce1aa4a-f475-48fa-8807-881c35d6c718",
  "payload": {
    "result": {
      "food_item": "avocado",
    }
  }' | jq
  

{
  "correlation_id": "test-001",
  "id": "6ce1aa4a-f475-48fa-8807-881c35d6c718",
  "payload": {
    "result": {
      "food_item": "avocado",
      "is_safe": false,
      "message": "avocado is NOT safe for chickens and should be avoided.",
      "status": "unsafe"
    },
    "service": "chicken_food_safety_check",
    "success": true
  },
  "recipient": {
    "agent_id": "curl-client",
    "name": "Curl Client",
    "version": "1.0"
  },
  "sender": {
    "agent_id": "chicken-food-safety-service",
    "name": "Chicken Food Safety Service",
    "version": "1.0"
  },
  "timestamp": "2025-08-28T22:23:22.469331+00:00",
  "type": "response",
  "version": "1.0"
}

Thank you

Thank you for reading this post on how I learned A2A with a fun, meaningful example. I hope you found it educational and that it saved you some time.

The complete source code, documentation, and setup instructions are available on my GitHub repo. 

I welcome your feedback.