Agent-to-Agent (A2A) Protocol: A Comprehensive Beginner's Guide

Neo CruzNeo Cruz
37 min read

Welcome to your comprehensive introduction to the A2A Protocol! Whether you're a developer, product manager, or AI enthusiast, this guide will walk you through everything you need to know about Agent-to-Agent communication.

In this guide, you'll learn:

  • What the A2A Protocol is and why it matters
  • How A2A enables seamless collaboration between AI agents
  • The technical architecture behind A2A
  • How to build your first A2A-compatible application
  • Real-world applications and integration patterns

No advanced technical knowledge required - just a basic understanding of what AI assistants are and an interest in how they can work together more effectively.

Let's dive in!

Introduction

What is A2A? Think of it as a Universal Translator for AI Agents

Illustration showing A2A protocol connecting different AI agents speaking different languages

Imagine you've hired three assistants: one speaks only English, one speaks only Chinese, and one speaks only Spanish. They all have amazing skills, but they can't work together because they can't communicate. That's exactly the problem with today's AI agents - they're built by different companies, using different frameworks, and they simply don't understand each other.

Enter the Agent2Agent (A2A) protocol - it's like giving each of these assistants a universal translator! Launched by Google with partners like Atlassian, Salesforce, and MongoDB, A2A creates a common language that allows AI agents to talk to each other, regardless of who made them or how they were built.

Before A2A: "I need data from the sales system, but my customer service agent can't talk to my analytics agent!"

After A2A: "My customer service agent automatically asked my analytics agent for sales data, and they worked together to solve my problem!"

Why Should You Care? Real-World Magic Happens When Agents Collaborate

Think about these everyday scenarios:

Planning a Trip: Without A2A, you might need to manually coordinate between your calendar agent, travel booking agent, and budget tracking agent. With A2A, you just say "Plan my vacation to Hawaii," and they work together - checking your available dates, finding flights within your budget, and scheduling everything automatically.

Customer Support: When a customer has a complex problem, A2A lets your chatbot agent seamlessly connect with your technical diagnostics agent and your order processing agent - creating a smooth experience instead of bouncing the customer between different systems.

Software Development: A requirements-gathering agent could automatically share specifications with a code-writing agent, which then collaborates with a testing agent - dramatically speeding up development time.

The real power of A2A isn't just connecting agents - it's creating entirely new possibilities that weren't feasible before. It's like how the internet wasn't just about connecting computers, but enabling entirely new types of applications.

Who Needs This Guide? (Spoiler: Probably You!)

This guide is perfect for:

  • Curious Beginners: "I keep hearing about AI agents - what happens when they work together?"
  • Developers: "I want my application to talk to other AI systems without building custom integrations"
  • Product Managers: "How can we make our AI product work with the broader ecosystem?"
  • Business Leaders: "What technology should we invest in to future-proof our AI strategy?"

No PhD required! We'll break down A2A into simple concepts with practical examples. By the end, you'll understand how this technology works and how it can solve real problems.

Let's start with the basics: what exactly are these "agents," and why do they need a special protocol to communicate?

Understanding A2A Core Concepts

What Are Agents? Think "Digital Employees" with Superpowers

Visualization of AI agents as digital employees with various superpowers and specializations

AI agents are like digital employees that can work 24/7 without coffee breaks! Unlike regular software that just follows fixed instructions, agents can:

  • Make decisions on their own: "The user asked for flight options - let me check three airlines and pick the best deals."
  • Remember previous interactions: "Last time we talked, you preferred window seats, so I'll prioritize those."
  • Adapt to new information: "I see there's a weather alert in Chicago, let me suggest alternate routes."
  • Specialize in specific tasks: Just like human specialists, some agents are amazing at scheduling, others at analyzing data, and others at creative writing.

In today's world, we use agents all the time without realizing it - when your music app suggests songs you might like, when your email automatically categorizes messages, or when your smart home adjusts the temperature before you arrive.

But here's the problem: most agents are like solo performers rather than band members. They're great at their individual tasks but terrible at collaborating with other agents. That's where A2A comes in!

A2A Protocol: The Rulebook for Agent Conversations

Think of A2A as the "rulebook" that standardizes how agents talk to each other. It's similar to how HTTP standardized how web browsers and servers communicate, enabling the entire web as we know it.

Here's what A2A does through some simple examples:

  • Helps agents introduce themselves: "Hi, I'm a Calendar Agent. I can check availability, schedule meetings, and send reminders."

  • Defines how they ask for things: "Hey Translation Agent, could you please convert this English text to Japanese? It's a business proposal."

  • Structures their responses: "Sure! Here's the Japanese translation in text format. I've also attached an audio pronunciation guide."

  • Handles complex back-and-forth: "I need more context about this medical term before I can translate it accurately."

The beauty of A2A is that it works for any communication style - text messages, structured data (like forms and tables), file exchanges, or even audio/video streams - all while maintaining security so agents only share what they're supposed to.

A2A Terminology Made Simple

Let's break down the key A2A concepts with everyday metaphors:

Agent Card: The Digital Business Card

{
  "name": "TravelBuddy",
  "description": "I help plan trips and book flights",
  "capabilities": ["flight_search", "hotel_booking", "itinerary_planning"]
}

Every A2A agent has an "Agent Card" (a special file at a standard web address) - like a digital business card that tells other agents: "Here's who I am, what I can do, and how to contact me." This is how agents discover each other and understand who can help with what.

Task: A Job Ticket

When you want an agent to do something, you create a "Task" - similar to submitting a job ticket to a help desk. Each task has a unique ID and goes through different states:

  • Submitted: "I've just asked the travel agent to find flights to Tokyo"
  • Working: "The agent is searching for the best options"
  • Input-Required: "The agent needs to know my preferred airlines"
  • Completed: "The agent found three great flight options"
  • Failed: "The agent couldn't complete the search because the dates were invalid"

Message: The Conversation Turn

Each message is like a turn in a conversation, clearly marked as coming from either the "user" (client) or the "agent" (server):

User: "Can you help me find flights to Tokyo next month?" Agent: "I'd be happy to help! Which dates are you considering?"

Part: The Content Pieces

Messages contain "Parts" - the actual content being shared. This could be:

  • TextPart: Simple text like "I'd like to book a window seat"
  • FilePart: A file such as a PDF of your boarding pass
  • DataPart: Structured data like a flight search form with fields for destination, dates, and preferences

Imagine ordering a pizza - you could send a TextPart ("large pepperoni pizza"), a FilePart (image of the pizza you want), or a DataPart (a structured form with all your specifications).

A2A Server & Client: The Conversation Participants

In any A2A interaction, there are two roles:

  • A2A Server: An agent that can respond to requests (like a customer service agent at a desk)
  • A2A Client: An application or agent that initiates requests (like a customer approaching the desk)

Sometimes an agent can play both roles - asking other agents for help while also responding to requests from others.

Now that you understand the building blocks of A2A, let's see how they fit together to create seamless agent communication!

A2A Protocol Technical Architecture

Technical diagram showing the A2A protocol architecture with server and client components

Client-Server Model: Like Ordering at a Restaurant

The A2A protocol uses a client-server model that's similar to how you interact with a restaurant:

  1. A2A Server (The Restaurant): This is the agent that provides services. Like a restaurant kitchen, the server:

    • Takes orders (processes requests)
    • Prepares meals (executes tasks)
    • Serves food (delivers responses)
    • Handles special requests (manages exceptions)

    For example, a language translation agent would be an A2A Server that accepts text and returns translations.

  2. A2A Client (The Customer): This is the application or agent that requests services. Like a restaurant customer, the client:

    • Reads the menu (discovers the server's capabilities)
    • Places orders (sends requests)
    • Waits for food (processes responses)
    • May ask questions about the meal (sends follow-up messages)

    A travel booking application that needs to translate hotel descriptions would be an A2A Client.

The beauty of this model is its flexibility - just like some people can be both restaurant owners and customers at different times, an agent can be both a client and a server. Your calendar agent might act as a server when your email agent asks it for your availability, but then act as a client when it asks your maps agent for travel time estimates.

Communication Flow: A Typical A2A Conversation

Let's walk through a real-world example: You ask your personal assistant agent to book you a haircut.

  1. Discovery: Your assistant agent needs to find a suitable booking agent

    Assistant: "I need to book a haircut. Let me see which booking agent can help."
    [Looks up a salon booking agent's Agent Card at salon-booker.example.com/.well-known/agent.json]
    "Great! This booking agent can schedule appointments and knows about haircuts."
    
  2. Task Initialization: Your assistant starts the conversation with the booking agent

    Assistant → Booking Agent: 
    "Task ID: abc123
     Message: I need to book a haircut for my user on Friday afternoon."
    
  3. Processing: The booking agent works on your request

    [Booking agent checks salon availability]
    Booking Agent: "Status: working" 
    [A few seconds later...]
    
  4. Interaction: The booking agent needs more information

    Booking Agent → Assistant:
    "Status: input-required
     Message: I have availability at 2:00 PM or 4:30 PM on Friday. Which would you prefer?"
    
    Assistant → Booking Agent:
    "2:00 PM would be perfect."
    
  5. Completion: The booking agent finalizes the appointment

    Booking Agent → Assistant:
    "Status: completed
     Message: Appointment confirmed for Friday at 2:00 PM with Mario at Supercuts on Main Street.
     Artifact: [calendar_event.ics]"
    

In real applications, this entire conversation happens in milliseconds through API calls, but the structure remains the same - discover, initialize, process, interact (if needed), and complete.

Communication Modes: Many Ways to Talk

A2A supports different ways for agents to communicate, similar to how humans use various methods based on what we're sharing:

  1. Text-Based Communication: The simplest form

    "Can you summarize this article for me?"
    

    This is like having a text message conversation - straightforward and perfect for simple requests and responses.

  2. Structured Data Exchange: For more complex information

    {
      "flightSearch": {
        "departure": "SFO",
        "destination": "JFK",
        "date": "2025-06-15",
        "passengers": 2
      }
    }
    

    This is like filling out a form at the doctor's office - structured, specific, and designed to collect exactly the information needed.

  3. File Sharing: For documents, images, audio, etc.

    "Here's my resume for formatting review" + [resume.pdf]
    

    This is like handing someone a physical document or photo - you're sharing a complete file that can be opened, edited, or stored.

  4. Audio/Video Streaming: For rich media interactions

    [Live audio stream of a customer describing a technical problem]
    

    This is like a phone call or video chat - real-time, continuous sharing of media.

The power of A2A is that these different modes can be mixed and matched within the same conversation. For example, a customer support agent might:

  1. Receive a text description of a problem
  2. Request a photo of the error message (file)
  3. Send back a structured form to collect system information
  4. Initiate a voice call for complex troubleshooting

This flexibility makes A2A suitable for everything from simple chatbots to sophisticated multi-modal interactions that combine text, data, files, and streaming media.

Now that you understand how A2A conversations work, let's dive into building your first A2A application!

Getting Started: Building Your First A2A Application

Setting Up Your A2A Workshop: What You'll Need

Think of building an A2A application like setting up a workshop - you need the right tools before you start creating. Here's your shopping list:

Essential Tools:

✓ Python 3.8+ (our building material)
✓ FastAPI (for creating endpoints quickly)
✓ Requests library (for making HTTP calls)
✓ UUID library (for generating unique IDs)
✓ SSE library (for streaming support)

Quick Setup Guide:

Creating your workshop is as simple as three commands:

# Step 1: Create a dedicated workspace
python -m venv a2a-workshop
source a2a-workshop/bin/activate  # On Windows: a2a-workshop\Scripts\activate

# Step 2: Install your tools
pip install fastapi uvicorn requests uuid sseclient-py

# Step 3: Get reference materials (optional but helpful)
git clone https://github.com/google/A2A.git

Now your workshop is ready! Let's build something.

Building Your First A2A Agent: The Echo Server

We'll start with something simple - an agent that echoes back whatever you send it. Think of it as the "Hello World" of A2A - not very useful on its own but perfect for learning the basics.

Step 1: Create Your Agent's Business Card

First, let's create your agent's "business card" (Agent Card) so others know what it can do:

// agent.json
{
  "schema_version": "1.0.0",
  "name": "Echo Agent",
  "description": "I repeat what you say, like a friendly cave",
  "versions": [
    {
      "version": "1.0.0",
      "endpoint": "http://localhost:8000/a2a",
      "supports_streaming": true,
      "auth": { "type": "none" }
    }
  ],
  "contact_email": "you@example.com"
}

This is like putting a sign on your storefront - it tells other agents who you are and how to talk to you.

Step 2: Build Your Agent's Brain

Now let's create a simple server that receives messages and echoes them back:

# echo_server.py
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from sse_starlette.sse import EventSourceResponse
import uuid
import json
import asyncio
from datetime import datetime

app = FastAPI()

# Serve your business card at the standard location
@app.get("/.well-known/agent.json")
async def get_agent_card():
    with open("agent.json") as f:
        return json.load(f)

# Handle regular (non-streaming) requests
@app.post("/a2a/tasks/send")
async def tasks_send(request: Request):
    # Get the task details from the request
    data = await request.json()
    task_id = data.get("task_id", str(uuid.uuid4()))

    # Find the user's message
    user_message = next((m for m in data.get("messages", []) 
                        if m.get("role") == "user"), None)

    if not user_message:
        return JSONResponse(status_code=400, content={"error": "No user message found"})

    # Extract text from the message parts
    parts = user_message.get("parts", [])
    text_parts = [p.get("text") for p in parts if p.get("type") == "text"]

    # Create our echo response
    echo_text = f"Echo: {' '.join(text_parts)}"

    # Return the completed task with our response
    return {
        "task_id": task_id,
        "status": "completed",
        "created_time": datetime.utcnow().isoformat(),
        "updated_time": datetime.utcnow().isoformat(),
        "messages": [
            {
                "role": "agent",
                "parts": [{"type": "text", "text": echo_text}]
            }
        ]
    }

# Start your server
if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

This is the core functionality - your Echo Agent now knows how to listen and respond!

Step 3: Open for Business

Let's run your Echo Agent:

python echo_server.py

Congratulations! Your A2A server is now running on http://localhost:8000. It's ready to receive and process tasks from any A2A client.

Creating Your First A2A Client: Talking to Your Echo Server

Now we need a client to talk to our server. Think of this as building a remote control for your new device:

# echo_client.py
import requests
import uuid

class SimpleA2AClient:
    def __init__(self, server_url):
        self.server_url = server_url

    def discover_agent(self):
        """Get the agent's business card"""
        response = requests.get(f"{self.server_url}/.well-known/agent.json")
        response.raise_for_status()
        return response.json()

    def send_message(self, text):
        """Send a message to the agent and get the response"""
        # Create a unique ID for this task
        task_id = str(uuid.uuid4())

        # Prepare our request in A2A format
        payload = {
            "task_id": task_id,
            "messages": [
                {
                    "role": "user",
                    "parts": [
                        {
                            "type": "text",
                            "text": text
                        }
                    ]
                }
            ]
        }

        # Send the request to the agent
        endpoint = f"{self.server_url}/a2a/tasks/send"
        response = requests.post(endpoint, json=payload)
        response.raise_for_status()

        # Return the full response
        return response.json()

# Let's try it out!
if __name__ == "__main__":
    # Create our client
    client = SimpleA2AClient("http://localhost:8000")

    # Check out the agent's capabilities
    agent_card = client.discover_agent()
    print(f"Found agent: {agent_card['name']}")

    # Send a message
    message = input("Type a message to send: ")
    response = client.send_message(message)

    # Extract and display the agent's response
    agent_message = response.get("messages", [{}])[0]
    agent_parts = agent_message.get("parts", [{}])
    response_text = agent_parts[0].get("text", "No response") if agent_parts else "No parts"

    print(f"\nAgent response: {response_text}")

Seeing Your A2A Creation in Action

Now let's see our client and server talk to each other:

  1. Make sure your Echo Server is running in one terminal
  2. In another terminal, run the client:
    python echo_client.py
    
  3. Type a message when prompted

You should see something like:

Found agent: Echo Agent
Type a message to send: Hello, A2A world!

Agent response: Echo: Hello, A2A world!

🎉 Congratulations! You've successfully:

  • Created an A2A-compatible agent
  • Written a client that can discover and communicate with any A2A agent
  • Completed your first A2A conversation

From Echo to Everywhere: Next Steps

This simple example demonstrates the core A2A pattern, but real-world applications do much more:

  • Add real intelligence - Connect your agent to LLMs, databases, or APIs
  • Implement streaming - Use the tasks/sendSubscribe endpoint for real-time updates
  • Enable authentication - Add security for production environments
  • Create multi-agent workflows - Make your client talk to multiple agents to solve complex problems

The A2A Protocol provides a standardized way for these advanced features to work seamlessly together, just like our simple Echo example but with more powerful capabilities.

Now that you've got the basics down, let's explore how to use the core features of A2A to build truly useful agents!

Core Features Explained

Agent Card: The Capability Discovery Mechanism

At the heart of A2A's interoperability is the Agent Card, a standardized metadata file that enables automatic discovery of agent capabilities. The Agent Card is typically hosted at a well-known URL (/.well-known/agent.json) and provides essential information about the agent:

{
  "schema_version": "1.0.0",
  "name": "Example Agent",
  "description": "An agent that demonstrates A2A capabilities",
  "versions": [
    {
      "version": "1.0.0",
      "endpoint": "https://example.com/a2a",
      "supports_streaming": true,
      "supports_push_notifications": true,
      "auth": {
        "type": "bearer"
      }
    }
  ],
  "contact_email": "support@example.com"
}

The Agent Card serves several critical functions:

  1. Capability Advertisement: It declares what the agent can do, including support for streaming and push notifications.

  2. Versioning Support: The versions array allows agents to evolve while maintaining backward compatibility.

  3. Authentication Information: The auth field indicates what authentication mechanisms are required.

  4. Contact Information: Provides ways to reach the agent's developers or support team.

By standardizing this discovery mechanism, A2A eliminates the need for manual configuration when connecting agents, enabling more dynamic and flexible multi-agent systems.

Task Lifecycle Management

Tasks in A2A follow a well-defined lifecycle with specific states and transitions:

  1. Submitted: The initial state when a task is first sent to an agent.

  2. Working: The agent is actively processing the task.

  3. Input-Required: The agent needs additional information to complete the task.

  4. Completed: The task has been successfully completed.

  5. Failed: The task could not be completed due to an error.

  6. Canceled: The task was explicitly canceled by the client.

These states enable clear tracking of task progress and support complex workflows that may involve multiple interactions. The lifecycle management is handled through the following key methods:

  • tasks/send: For synchronous task processing
  • tasks/sendSubscribe: For streaming task processing
  • tasks/cancel: To explicitly cancel an in-progress task

Task IDs are client-generated UUIDs that remain consistent throughout the lifecycle, allowing for reliable tracking and management of tasks even in distributed systems.

Message Format and Content Types

Messages in A2A are structured to support rich, multimodal interactions. Each message contains:

  1. Role: Indicates whether the message is from the "user" (client) or the "agent" (server).

  2. Parts: Contains the actual content of the message in various formats.

The Parts system is particularly flexible, supporting:

  • TextPart: For plain text content

    {
      "type": "text",
      "text": "Hello, how can I help you today?"
    }
    
  • FilePart: For binary content like images or documents

    {
      "type": "file",
      "mime_type": "image/png",
      "file_name": "diagram.png",
      "data": "base64encodedstring..."
    }
    
  • DataPart: For structured JSON data like forms

    {
      "type": "data",
      "mime_type": "application/json",
      "data": {
        "form_id": "booking",
        "fields": {
          "name": "John Doe",
          "date": "2025-05-15"
        }
      }
    }
    

This flexible message format allows agents to exchange information in the most appropriate format for each use case, whether that's simple text, structured data, or rich multimedia content.

Streaming and Real-Time Communication

For long-running tasks or scenarios where immediate feedback is valuable, A2A supports streaming through Server-Sent Events (SSE). This feature enables:

  1. Progressive Responses: Agents can provide partial results as they become available.

  2. Status Updates: Clients receive real-time updates about task status changes.

  3. Interactive Experiences: Users can see the agent "thinking" through complex problems.

To enable streaming, a client sends a request to the tasks/sendSubscribe endpoint and processes the SSE stream. Each event in the stream can be one of two types:

  • TaskStatusUpdateEvent: Provides updates about the task's status

    {
      "event": "task_status_update",
      "data": {
        "task_id": "123e4567-e89b-12d3-a456-426614174000",
        "status": "working",
        "updated_time": "2025-04-10T15:30:45Z"
      }
    }
    
  • TaskArtifactUpdateEvent: Delivers artifacts as they are generated

    {
      "event": "task_artifact_update",
      "data": {
        "task_id": "123e4567-e89b-12d3-a456-426614174000",
        "artifact_id": "987e6543-e21b-34d5-c678-642042365000",
        "parts": [
          {
            "type": "text",
            "text": "Initial analysis results..."
          }
        ]
      }
    }
    

Streaming is particularly valuable for agents that perform time-consuming operations like research, analysis, or content generation, as it keeps users engaged and informed throughout the process.

Push Notification Mechanism

For scenarios where clients can't maintain a persistent connection, A2A provides a push notification mechanism. This allows servers to proactively inform clients about task updates by sending HTTP requests to a client-provided webhook URL.

To set up push notifications, a client calls the tasks/pushNotification/set method with its webhook URL:

{
  "webhook_url": "https://client.example.com/a2a/webhook",
  "events": ["task_status_update", "task_artifact_update"]
}

The server then sends notifications to this URL when relevant events occur. Each notification includes:

  1. Event Type: Indicates what happened (status update, artifact update).

  2. Task Information: Details about the task and its current state.

  3. Payload: The relevant data associated with the event.

Push notifications are particularly useful for:

  • Mobile applications that may go into background mode
  • Distributed systems where different components need to be notified of task progress
  • Long-running tasks that might exceed typical connection timeouts

Together, these core features provide a robust foundation for building sophisticated, interoperable agent systems that can communicate effectively regardless of their underlying implementation or hosting environment.

Advanced Features and Applications

Multi-Agent Collaboration Patterns

One of the most powerful aspects of A2A is its ability to enable sophisticated multi-agent collaboration patterns. These patterns unlock new possibilities for complex problem-solving and workflow automation:

  1. Agent Orchestration: A "controller" agent coordinates multiple specialized agents to complete a complex task. For example, a project management agent might delegate subtasks to research, writing, and design agents, then assemble their outputs into a final deliverable.

  2. Chain of Thought: Agents pass information sequentially, with each agent adding value or transforming the data before passing it to the next agent. This pattern is useful for multi-step processing workflows, such as data extraction → analysis → visualization.

  3. Consensus Building: Multiple agents work on the same problem independently, then compare results to reach a consensus. This pattern can improve accuracy and reduce bias in decision-making processes.

  4. Competitive Evaluation: Several agents propose solutions to a problem, and another agent evaluates and selects the best solution. This pattern can lead to more innovative outcomes by considering diverse approaches.

  5. Hierarchical Problem Solving: Complex problems are broken down into subtasks, delegated to specialized agents, and then results are aggregated and synthesized. This mirrors human organizational structures and allows for efficient division of labor.

To implement these patterns, developers can use A2A's task management capabilities to track dependencies between tasks and ensure proper sequencing of agent interactions. The protocol's flexibility in message formats also supports rich information exchange between collaborating agents.

Security and Access Control

Enterprise deployments require robust security and access control mechanisms. A2A addresses these needs through several features:

  1. Authentication Options:

    • None: For public agents or development environments
    • Bearer Token: For API key or OAuth2 token-based authentication
    • Basic Authentication: Username/password authentication
    • Custom: Support for specialized authentication schemes
  2. Role-Based Access Control: Agents can implement RBAC to restrict access to certain capabilities based on the authenticated user's permissions.

  3. Request Validation: Checking request integrity and authenticity using signatures or other validation mechanisms.

  4. Rate Limiting: Protecting against abuse by limiting the number of requests from a client.

  5. Data Protection: Applying appropriate encryption for sensitive data in transit and at rest.

To implement these security features, developers typically combine A2A's built-in authentication support with additional middleware in their server implementation:

@app.middleware("http")
async def validate_authentication(request: Request, call_next):
    # Extract and validate authentication token
    auth_header = request.headers.get("Authorization")
    if not auth_header or not auth_header.startswith("Bearer "):
        return JSONResponse(
            status_code=401,
            content={"detail": "Invalid or missing authentication token"}
        )

    token = auth_header.split(" ")[1]
    if not validate_token(token):
        return JSONResponse(
            status_code=403,
            content={"detail": "Unauthorized access"}
        )

    # Continue with the request
    response = await call_next(request)
    return response

Enterprise Deployment Considerations

When deploying A2A in enterprise environments, several additional considerations come into play:

  1. Scalability:

    • Implementing load balancing for high-traffic agents
    • Using horizontal scaling to handle increased demand
    • Leveraging caching for frequently accessed resources
  2. High Availability:

    • Deploying redundant instances across availability zones
    • Implementing health checks and automatic failover
    • Designing for graceful degradation during outages
  3. Monitoring and Observability:

    • Logging all agent interactions for audit purposes
    • Implementing metrics collection for performance analysis
    • Setting up alerting for error conditions
  4. Data Governance:

    • Establishing data retention and deletion policies
    • Implementing data classification and handling procedures
    • Ensuring compliance with relevant regulations (GDPR, HIPAA, etc.)
  5. Integration with Enterprise Systems:

    • Connecting to identity providers and SSO systems
    • Integrating with existing APIs and services
    • Aligning with corporate security policies

A typical enterprise deployment architecture might include:

  • A Kubernetes cluster for hosting agent services
  • API gateway for managing authentication and rate limiting
  • Prometheus and Grafana for monitoring
  • Elastic Stack for log management
  • CI/CD pipeline for automated deployment

Performance Optimization Strategies

For high-performance A2A implementations, consider these optimization strategies:

  1. Efficient Task Processing:

    • Implement asynchronous handling of requests
    • Use task queues for managing workload
    • Prioritize tasks based on urgency or importance
  2. Caching Mechanisms:

    • Cache Agent Cards to reduce discovery overhead
    • Store frequent responses for rapid retrieval
    • Implement intelligent prefetching for likely next steps
  3. Connection Management:

    • Use connection pooling for HTTP requests
    • Implement keep-alive connections when possible
    • Optimize timeout settings based on task characteristics
  4. Resource Allocation:

    • Scale computational resources based on task complexity
    • Implement graceful degradation under high load
    • Use resource quotas to prevent monopolization
  5. Efficient Data Handling:

    • Compress large payloads
    • Use pagination for large result sets
    • Implement partial updates for streaming responses

Here's an example of implementing a caching layer for Agent Cards:

from functools import lru_cache
import requests
import time

@lru_cache(maxsize=100)
def get_agent_card(agent_url, max_age=3600):
    """Fetch and cache agent card with expiration"""
    response = requests.get(f"{agent_url}/.well-known/agent.json")
    response.raise_for_status()

    # Store the card with its fetch time
    return {
        "card": response.json(),
        "fetch_time": time.time()
    }

def get_agent_card_with_refresh(agent_url):
    """Get agent card with automatic refresh if expired"""
    cached = get_agent_card(agent_url)

    # Check if the cache is expired
    if time.time() - cached["fetch_time"] > 3600:
        # Clear just this entry from the cache
        get_agent_card.cache_clear()
        cached = get_agent_card(agent_url)

    return cached["card"]

By implementing these advanced features and following these best practices, you can build A2A-compatible agents that are secure, scalable, and performant enough for enterprise deployment.

Integration Case Studies

Agent Developer Kit (ADK): Google's Enterprise Solution

Google's Agent Developer Kit (ADK) has first-class support for A2A, making it simple to create enterprise-ready agents that can communicate with the broader AI ecosystem.

from google.cloud.adk import Agent
from google.cloud.adk.a2a import A2AServer

# Create a standard ADK agent
agent = Agent(
    name="Customer Support Agent",
    description="Helps solve technical issues and answer product questions"
)

# Add A2A capabilities with just one line
a2a_server = A2AServer(agent)

# Handle A2A tasks with simple decorators
@a2a_server.task_handler
async def handle_support_request(task):
    # Extract the customer's question
    message_text = task.get_message_text()

    # Check if we need help from a specialized agent
    if "billing" in message_text.lower():
        # Use A2A to consult with the billing agent
        billing_response = await agent.a2a_client.send_task(
            "billing-agent.example.com",
            f"Customer has a billing question: {message_text}"
        )
        response = f"Our billing department says: {billing_response}"
    else:
        # Handle the question directly
        response = await agent.generate_text(
            f"How to answer: {message_text}"
        )

    # Return the completed task
    return task.complete(response)

# Start the agent with both ADK and A2A capabilities
agent.start()

ADK handles the complex parts of A2A automatically:

  • Generates and serves the Agent Card with proper versioning
  • Integrates with Google Cloud authentication
  • Implements streaming with proper error handling
  • Manages task state transitions correctly
  • Provides both client and server capabilities

This makes ADK ideal for enterprise deployments where security, scalability, and reliability are critical.

CrewAI: Orchestrating Specialized Agents

CrewAI is a framework designed specifically for coordinating teams of agents. Its A2A connector turns these teams into interconnected networks where each agent can leverage others' specialized skills.

from crewai import Agent, Task, Crew
from crewai.a2a import A2AConnector

# Create specialized agents with different expertise
researcher = Agent(
    name="Research Specialist",
    description="Expert at finding and analyzing information",
    llm=OpenAI(model="gpt-4"),
    tools=[web_search, document_retrieval]
)

writer = Agent(
    name="Content Creator",
    description="Skilled at crafting engaging articles",
    llm=Anthropic(model="claude-3-opus"),
    tools=[text_editor, grammar_checker]
)

designer = Agent(
    name="Visual Designer",
    description="Creates compelling images and layouts",
    llm=OpenAI(model="gpt-4-vision"),
    tools=[image_generator, layout_tool]
)

# Connect these agents through the A2A protocol
a2a_connector = A2AConnector()
a2a_connector.register_agent(researcher)
a2a_connector.register_agent(writer)
a2a_connector.register_agent(designer)

# Create tasks with dependencies that will use A2A for communication
research_task = Task(
    description="Research the latest AI developments in healthcare",
    agent=researcher
)

writing_task = Task(
    description="Write an article based on the research findings",
    agent=writer,
    dependencies=[research_task]  # This creates an A2A connection
)

design_task = Task(
    description="Create illustrations and layout for the article",
    agent=designer,
    dependencies=[writing_task]  # Another A2A connection
)

# Assemble the crew and run the workflow
crew = Crew(
    agents=[researcher, writer, designer],
    tasks=[research_task, writing_task, design_task],
    connector=a2a_connector
)

# Execute the entire workflow with a single command
final_output = crew.run()

What makes CrewAI's A2A integration powerful:

  • Automatic task dependency tracking: Outputs from one agent become inputs to another
  • Seamless artifact passing: Research documents, article drafts, and design files flow between agents
  • Standardized communication: All agents speak the same language regardless of their underlying models
  • Parallel and sequential execution: Complex workflows with multiple paths can be easily defined
  • Status monitoring: Track progress of each agent's tasks in real-time

This approach is perfect for content creation, research workflows, and any process that involves multiple specialized steps.

LangGraph: Visual Flow Programming for Agents

LangGraph lets you build agent systems using a visual graph-based approach. Its A2A integration allows nodes in your graph to represent external agents that communicate via the A2A protocol.

from langgraph.graph import StateGraph
from langgraph.a2a import A2ANode, A2AEdge

# Create a graph to process insurance claims
graph = StateGraph()

# Connect to external A2A-compatible agents as nodes
document_extractor = A2ANode("https://document-extractor.example.com")
fraud_detector = A2ANode("https://fraud-detection.example.com")
claims_processor = A2ANode("https://claims-processor.example.com")
payment_system = A2ANode("https://payment-system.example.com")
notification_service = A2ANode("https://notification.example.com")

# Add nodes to the graph
graph.add_node("extract_claim_data", document_extractor)
graph.add_node("detect_fraud", fraud_detector)
graph.add_node("process_claim", claims_processor)
graph.add_node("issue_payment", payment_system)
graph.add_node("notify_customer", notification_service)

# Define the workflow with conditional logic
graph.add_edge("extract_claim_data", "detect_fraud", A2AEdge())

# Add conditional routing based on fraud detection results
def route_after_fraud_check(state):
    if state.get("fraud_detected"):
        return "notify_customer"  # Rejected path
    else:
        return "process_claim"  # Approval path

graph.add_conditional_edges("detect_fraud", route_after_fraud_check)
graph.add_edge("process_claim", "issue_payment", A2AEdge())
graph.add_edge("issue_payment", "notify_customer", A2AEdge())

# Compile and run the graph
compiled_graph = graph.compile()
result = compiled_graph.run({
    "input": "Claim form for auto accident on June 15, 2025",
    "attachments": ["accident_report.pdf", "repair_estimate.pdf"]
})

LangGraph's A2A integration provides:

  • Visual workflow design: Create complex agent systems with an intuitive graph interface
  • Dynamic discovery: Agents can be added or replaced without changing the overall workflow
  • Consistent error handling: Standard patterns for managing failures across the graph
  • Progress tracking: Monitor the exact state of each task as it flows through the system
  • Conditional branching: Create intelligent workflows that adapt based on agent outputs

This approach is ideal for building sophisticated business processes like customer service workflows, approval systems, and multi-stage data processing pipelines.

Choosing the Right Framework for Your Needs

Each framework offers different advantages depending on your specific requirements:

  • ADK: Best for enterprise deployments requiring robust security and Google Cloud integration
  • CrewAI: Ideal for orchestrating multiple specialized agents in complex workflows
  • LangGraph: Perfect for visual design of agent systems with branching logic

The beauty of the A2A protocol is that agents built with any of these frameworks can communicate with each other seamlessly, allowing you to choose the best tool for each component of your system while maintaining interoperability across the entire ecosystem.

Troubleshooting and Best Practices

Common Issues and Solutions

When working with A2A, developers may encounter several common issues. Here's how to diagnose and resolve them:

1. Connection and Discovery Problems

Issue: Agent cannot discover or connect to another agent.

Potential Causes and Solutions:

  • Invalid Agent Card URL: Ensure the Agent Card is accessible at the well-known location (/.well-known/agent.json)
  • CORS Restrictions: Add appropriate CORS headers if agents are on different domains
  • Network Connectivity: Check firewall settings and network access between agents
  • Incorrect Endpoint URL: Verify the endpoint URL in the Agent Card is correct and accessible

Debugging Steps:

# Test Agent Card accessibility
curl -i https://agent.example.com/.well-known/agent.json

# Test endpoint accessibility
curl -i https://agent.example.com/a2a/tasks/send -H "Content-Type: application/json" -d '{"task_id": "test"}'

2. Authentication Failures

Issue: Requests fail with 401 or 403 status codes.

Potential Causes and Solutions:

  • Missing or Invalid Token: Ensure authentication tokens are included and valid
  • Token Expiration: Check if the token has expired and needs refreshing
  • Insufficient Permissions: Verify the token has appropriate permissions
  • Mismatched Auth Type: Ensure client and server agree on authentication method

Debugging Example:

# Test authentication with explicit token
import requests

response = requests.get(
    "https://agent.example.com/.well-known/agent.json",
    headers={"Authorization": "Bearer YOUR_TOKEN"}
)

print(f"Status: {response.status_code}")
print(f"Response: {response.text}")

3. Task State Management Issues

Issue: Tasks get stuck in an unexpected state or don't progress.

Potential Causes and Solutions:

  • Missing State Transitions: Ensure the server properly updates task states
  • Task ID Conflicts: Verify task IDs are unique for each new task
  • Incomplete Task Objects: Check that all required fields are present in task objects
  • Client-Side Timeout: Adjust client timeout settings for long-running tasks

Debugging Approach:

# Log all task state transitions
def track_task_state(task_id, old_state, new_state):
    print(f"Task {task_id}: {old_state} -> {new_state}")

# Implement this tracking in your task processing logic

4. Streaming and SSE Problems

Issue: Server-Sent Events (SSE) streaming is not working.

Potential Causes and Solutions:

  • Improper Content Type: Ensure the server sends Content-Type: text/event-stream
  • Buffering Issues: Disable response buffering in your server framework
  • Connection Timeouts: Configure long polling or keepalive settings
  • Event Format Errors: Verify events follow the correct SSE format

Example Fix for FastAPI:

from fastapi import FastAPI, Request
from sse_starlette.sse import EventSourceResponse
import asyncio

app = FastAPI()

@app.post("/a2a/tasks/sendSubscribe")
async def tasks_send_subscribe(request: Request):
    # Disable response buffering
    request.app.middleware_stack = None

    async def event_generator():
        try:
            # Send properly formatted SSE events
            yield {
                "event": "task_status_update",
                "data": '{"task_id": "123", "status": "working"}'
            }
            await asyncio.sleep(1)
            yield {
                "event": "task_status_update",
                "data": '{"task_id": "123", "status": "completed"}'
            }
        except Exception as e:
            print(f"Streaming error: {e}")

    return EventSourceResponse(
        event_generator(),
        media_type="text/event-stream"
    )

Debugging Tools and Techniques

To effectively troubleshoot A2A implementations, consider these debugging tools and techniques:

  1. HTTP Inspection Tools:

    • Postman: For testing API endpoints and inspecting responses
    • Charles Proxy or Fiddler: For analyzing HTTP traffic between agents
    • Browser DevTools: For monitoring network activity in web-based agents
  2. Logging Strategies:

    • Log all A2A requests and responses with correlation IDs
    • Add detailed timing information to track performance bottlenecks
    • Use structured logging for easier analysis and filtering

    Example logging configuration:

    import logging
    import json
    import time
    
    def setup_a2a_logging():
        logger = logging.getLogger("a2a")
        logger.setLevel(logging.DEBUG)
    
        # Create a file handler
        handler = logging.FileHandler("a2a.log")
    
        # Create a formatter that includes timestamps and correlation IDs
        formatter = logging.Formatter('%(asctime)s [%(correlation_id)s] %(levelname)s: %(message)s')
        handler.setFormatter(formatter)
    
        logger.addHandler(handler)
        return logger
    
    # Usage
    logger = setup_a2a_logging()
    
    def log_request(method, url, payload, correlation_id):
        logger.debug(
            "A2A Request",
            extra={
                "correlation_id": correlation_id,
                "method": method,
                "url": url,
                "payload": json.dumps(payload)
            }
        )
    
  3. Task Visualization:

    • Create dashboards to visualize task states and transitions
    • Implement a task explorer tool for examining task details
    • Generate sequence diagrams for complex multi-agent workflows
  4. Mock Servers and Clients:

    • Develop mock A2A servers for testing client implementations
    • Create simulated clients for load testing server implementations
    • Use record/replay capabilities to reproduce issues

    Example mock server:

    from fastapi import FastAPI
    import json
    
    app = FastAPI()
    
    @app.get("/.well-known/agent.json")
    async def get_agent_card():
        return {
            "schema_version": "1.0.0",
            "name": "Mock A2A Agent",
            "versions": [{"version": "1.0.0", "endpoint": "/a2a"}]
        }
    
    @app.post("/a2a/tasks/send")
    async def tasks_send(request: dict):
        # Always return a successful response with echo
        task_id = request.get("task_id", "unknown")
        return {
            "task_id": task_id,
            "status": "completed",
            "messages": [{"role": "agent", "parts": [{"type": "text", "text": "Mock response"}]}]
        }
    

Performance Monitoring and Optimization

To ensure your A2A implementation performs well at scale, implement these monitoring and optimization strategies:

  1. Key Metrics to Track:

    • Request Latency: Time to process each request
    • Task Completion Time: End-to-end time for task processing
    • Error Rates: Percentage of failed requests or tasks
    • Throughput: Number of tasks processed per minute
    • Resource Utilization: CPU, memory, network usage
  2. Optimization Techniques:

    • Implement connection pooling for HTTP clients
    • Use asynchronous processing for I/O-bound operations
    • Apply appropriate caching strategies for frequently accessed data
    • Optimize JSON serialization/deserialization
    • Implement compression for large payloads
  3. Scaling Strategies:

    • Horizontal scaling with load balancing for high-traffic agents
    • Auto-scaling based on traffic patterns and resource utilization
    • Prioritization mechanisms for important or time-sensitive tasks
    • Rate limiting to prevent resource exhaustion

Security Best Practices

Security is crucial for A2A implementations, especially in enterprise environments. Follow these best practices:

  1. Authentication and Authorization:

    • Use strong authentication mechanisms (OAuth2, JWT)
    • Implement fine-grained access control based on user identity
    • Rotate credentials regularly
    • Apply the principle of least privilege
  2. Data Protection:

    • Encrypt sensitive data in transit using TLS
    • Apply appropriate encryption for stored data
    • Implement data masking for sensitive information
    • Establish clear data retention and deletion policies
  3. Request Validation:

    • Validate all incoming requests against the A2A schema
    • Implement rate limiting to prevent abuse
    • Use API keys with appropriate scopes
    • Monitor for unusual activity patterns
  4. Audit and Compliance:

    • Log all agent interactions for audit purposes
    • Implement non-repudiation mechanisms
    • Ensure compliance with relevant regulations
    • Conduct regular security assessments

By following these troubleshooting guidelines and best practices, you can build reliable, secure, and performant A2A implementations that work effectively in production environments. Regular monitoring, optimization, and security reviews will help maintain the quality of your A2A-enabled agents over time.

A2A vs MCP: What's the Difference?

Complementary Highways in the AI Ecosystem

A2A and MCP protocols working together - MCP handles model-application communication while A2A enables agent-to-agent collaboration

A2A and MCP are not competing standards, but complementary protocols designed to solve different challenges in the AI world. Think of them as specialized highways in a smart city transportation system, each serving a specific type of traffic but working together to create a complete network.

MCP: The Highway Between Models and Applications

Model Context Protocol (MCP) focuses on standardizing how AI models and applications communicate:

  • Created by: Anthropic (the makers of Claude)
  • Main purpose: Standardizing context representation between models and applications
  • Real-world analogy: Like a specialized translator that helps you communicate clearly with a single foreign expert

MCP solves the challenge of structured context exchange by:

  • Providing standardized formats for sending information to AI models
  • Creating consistent patterns for accessing external tools and resources
  • Standardizing how models can reference documents and data
  • Maintaining attribution of information sources

For example, when you ask Claude to "analyze @quarterly-report.pdf and summarize the key findings," MCP provides the framework for how that document is represented to the model and how Claude can properly attribute information from it.

A2A: The Highway Between Different AI Agents

Agent-to-Agent (A2A) Protocol addresses an entirely different challenge - enabling communication between multiple AI assistants:

  • Created by: Google and 50+ tech partners
  • Main purpose: Enabling interoperability between different AI assistants and systems
  • Real-world analogy: Like a universal conference call system that allows experts from different organizations to collaborate

A2A solves the challenge of agent collaboration by:

  • Creating standardized task management between agents
  • Establishing discovery mechanisms so agents can find each other
  • Defining clear communication patterns and message formats
  • Supporting consistent interaction flows across different implementations

For example, when your personal assistant needs to "create a detailed travel itinerary," it might use A2A to delegate specialized tasks to a flight booking agent, hotel recommendation agent, and local activity planning agent.

Key Technical Differences

AspectMCPA2A
Primary focusModel-to-application context exchangeAgent-to-agent communication
Technical implementationJSON-RPC with client-server architectureREST API with task-based workflows
State managementContext-oriented with prompt managementTask-oriented with explicit lifecycle states
Content handlingRich context representation with attributionMessage-based with multi-part content
Discovery mechanismApplication-defined capabilitiesAgent Cards for capability advertisement

How They Work Together: Building Blocks, Not Alternatives

The official A2A documentation emphasizes that these protocols are designed to work together. Here's how:

  1. MCP enhances individual A2A agents:

    • A specialized A2A agent might use MCP internally to interact with its AI model
    • MCP helps the agent maintain context and access resources
    • A2A then allows this enhanced agent to collaborate with other agents
  2. Complementary responsibilities:

    • MCP excels at structured context management and tool access for a single AI
    • A2A excels at coordinating multiple specialized AIs toward a common goal

Think of it like building a team of experts:

  • MCP equips each individual expert with reference materials and tools
  • A2A gives them a shared language to collaborate effectively

Practical Example: Working Together

Flow diagram showing how A2A and MCP work together in a general system

Imagine you're building an AI system to analyze a company's financial health:

  1. Your main assistant receives the request: "Analyze our company's financial situation"

  2. Using A2A, it coordinates with specialized agents:

    • Financial data agent: "Retrieve the latest quarterly reports"
    • Market analysis agent: "Assess industry trends"
    • Risk assessment agent: "Identify potential financial risks"
  3. Each specialized agent uses MCP internally to:

    • Maintain context about their specific domain
    • Access relevant databases and documents
    • Use specialized tools for calculations and analysis
    • Preserve attribution of information sources
  4. Through A2A, the agents share their findings and collaborate on the final analysis

  5. Your main assistant presents a comprehensive financial assessment, leveraging both the collaboration capabilities of A2A and the context richness of MCP

When to Use Each Protocol

Based on the official documentation, here's when to focus on each protocol:

Consider MCP when you need:

  • Rich context management for a single AI assistant
  • Structured document and data representation
  • Tool access for an individual AI application
  • Source attribution and citation tracking

Consider A2A when you need:

  • Multiple specialized agents working together
  • Cross-vendor AI system communication
  • Standardized agent discovery and task management
  • Complex workflows involving multiple AI components

Consider both when:

  • Building comprehensive AI systems with both individual capabilities and collaboration needs
  • Creating enterprise solutions that require both depth (MCP) and breadth (A2A)
  • Designing scalable agent architectures that can grow over time

As the AI ecosystem matures, expect to see increasing integration between these complementary protocols, with many applications leveraging both to create more capable, interoperable systems.

Frequently Asked Questions About A2A

Is A2A free to use?

A: Yes! A2A is an open protocol, and its specifications are freely available. You can implement A2A in your applications without licensing fees. However, you may incur costs for the underlying infrastructure needed to host and run A2A-compatible agents.

Who created A2A and why?

A: A2A was developed by Google in collaboration with over 50 partners, including major tech companies and AI startups. It was created to solve the "agent isolation" problem - the inability of AI assistants from different vendors to communicate and collaborate effectively.

Do I need special hardware to implement A2A?

A: No. A2A is a software protocol that runs on standard computing infrastructure. Any system capable of running HTTP services can implement A2A. It works on cloud servers, on-premises systems, and even on consumer-grade hardware for development purposes.

How secure is A2A?

A: A2A includes built-in security features like authentication mechanisms, but the overall security depends on implementation. The protocol supports various authentication methods (none, bearer token, basic auth, custom) to fit different security requirements. For production systems, you should implement appropriate authentication, encryption, and access controls.

Can I connect A2A to existing systems?

A: Yes! A2A was designed with integration in mind. You can wrap existing AI systems, APIs, and services with A2A-compatible interfaces, allowing them to participate in agent-to-agent communications. The protocol's flexibility lets you start small and expand your A2A implementation over time.

What programming languages can I use with A2A?

A: A2A is language-agnostic. Official sample implementations are available in Python, JavaScript, and Go, but you can implement the protocol in any programming language that supports HTTP communications and JSON processing.

Is A2A suitable for enterprise use?

A: Absolutely. A2A was designed with enterprise requirements in mind, including security, scalability, and integration capabilities. Many large organizations are already implementing A2A for internal agent coordination and to connect their AI systems with external partners.

Will A2A become an industry standard?

A: A2A has strong momentum to become a widely adopted standard. With backing from Google and 50+ partners including major tech companies, and its focus on solving a critical interoperability problem, A2A is positioned to become a key standard in the AI ecosystem. Its open nature and vendor-neutral approach further increase its chances of broad adoption.

Appendix

A2A API Reference

For complete details on the A2A API, refer to the official specification at A2A specification. Key API endpoints include:

  1. Task Management:

    • tasks/send: Send a task for synchronous processing
    • tasks/sendSubscribe: Send a task and subscribe to streaming updates
    • tasks/cancel: Cancel an in-progress task
    • tasks/get: Retrieve the current state of a task
  2. Push Notifications:

    • tasks/pushNotification/set: Configure push notification settings
    • tasks/pushNotification/test: Test push notification configuration

Sample Code Repository

Explore the following sample code repositories to see A2A in action:

  1. Reference Implementations:

  2. Demo Applications:

These additional resources can help you work with the A2A protocol:

  1. Documentation:

  2. Tools:

  3. Related Projects:

Glossary

  • Agent: An autonomous AI application that can perform tasks on behalf of users.
  • Agent Card: A JSON metadata file describing an agent's capabilities and endpoints.
  • A2A Client: An application or agent that sends requests to an A2A server.
  • A2A Server: An agent that implements the A2A protocol and processes requests.
  • Artifact: An output generated by an agent during task processing.
  • DataPart: A structured JSON content part within a message.
  • FilePart: A binary content part within a message, such as an image or document.
  • Message: A communication between the client and agent, containing one or more parts.
  • Part: The basic content unit within messages and artifacts.
  • Push Notification: A mechanism for servers to proactively notify clients about task updates.
  • Server-Sent Events (SSE): A technology for streaming updates from server to client.
  • Streaming: Real-time delivery of task updates and intermediate results.
  • Task: The fundamental unit of work in A2A, with a defined lifecycle.
  • Task ID: A unique identifier for a task, generated by the client.
  • TextPart: A plain text content part within a message.

📌 Originally published on Toolworthy.ai – your go-to resource for AI tools and protocols.

0
Subscribe to my newsletter

Read articles from Neo Cruz directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Neo Cruz
Neo Cruz