PHPackages                             neuron-core/a2a - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. neuron-core/a2a

ActiveLibrary

neuron-core/a2a
===============

A2A server.

1.0.0(6mo ago)41.2k↓33.3%3[1 issues](https://github.com/neuron-core/a2a/issues)MITPHPPHP ^8.1CI passing

Since Oct 21Pushed 6mo agoCompare

[ Source](https://github.com/neuron-core/a2a)[ Packagist](https://packagist.org/packages/neuron-core/a2a)[ RSS](/packages/neuron-core-a2a/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (7)Versions (3)Used By (0)

A2A PHP Server
==============

[](#a2a-php-server)

A framework-agnostic PHP implementation of the **A2A (Agent-to-Agent) Protocol** that enables AI agents to communicate and collaborate across different platforms, frameworks, and organizations.

Table of Contents
-----------------

[](#table-of-contents)

- [Introduction](#introduction)
- [Features](#features)
- [Quick Start](#quick-start)
    - [Standalone Usage](#standalone-usage)
    - [Laravel Integration](#laravel-integration)
- [Core Concepts](#core-concepts)
- [API Reference](#api-reference)
- [Advanced Usage](#advanced-usage)

---

Introduction
------------

[](#introduction)

The **A2A (Agent-to-Agent) Protocol** is an open standard that enables seamless communication and collaboration between AI agents. It provides a common language for agents built using diverse frameworks and by different vendors, fostering interoperability and breaking down silos.

**Official Specification:**

### What This Library Provides

[](#what-this-library-provides)

- ✅ **Complete A2A Protocol Implementation** - JSON-RPC 2.0 over HTTP
- ✅ **Multi-Agent Architecture**-Host multiple specialized agents in one application

---

Features
--------

[](#features)

### Supported A2A Methods

[](#supported-a2a-methods)

- ✅ `message/send` - Send messages and receive agent responses
- ✅ `tasks/get` - Retrieve a specific task by ID
- ✅ `tasks/list` - List tasks with filtering and pagination
- ✅ `tasks/cancel` - Cancel a running task
- ✅ `agent/getAuthenticatedExtendedCard` - Get agent capabilities

### Framework Support

[](#framework-support)

- ✅ \*\*Laravel—\*\*Full integration with Artisan commands and routes
- ✅ **Standalone** - Framework-agnostic HTTP interfaces
- 🔄 \*\*Other Frameworks—\*\*Easy to add adapters (Symfony, Slim, etc.)

---

Quick Start
-----------

[](#quick-start)

### Standalone Usage

[](#standalone-usage)

#### 1. Create Your Agent Server

[](#1-create-your-agent-server)

You can create your own server class extending `NeuronCore\A2A\A2AServer`. This class provides the main entry point to expose your AI agent to the world. You need to implement two components to create a server:

- Task Repository - Store and retrieve tasks
- Message Handler - Handle messages and return task results

```
use NeuronCore\A2A\Server\A2AServer;
use NeuronCore\A2A\Contract\TaskRepositoryInterface;
use NeuronCore\A2A\Contract\MessageHandlerInterface;
use NeuronCore\A2A\Model\AgentCard\AgentCard;

class MyAIAgent extends A2AServer
{
    protected function taskRepository(): TaskRepositoryInterface
    {
        return new MyTaskRepository();
    }

    protected function messageHandler(): MessageHandlerInterface
    {
        return new MyMessageHandler();
    }

    protected function agentCard(): AgentCard
    {
        return new AgentCard(
            protocolVersion: '0.3.0',
            name: 'My AI Agent',
            description: 'A specialized AI agent for data analysis',
            url: 'https://example.com/a2a',
            preferredTransport: 'JSONRPC',
            version: '1.0.0',
            provider: new AgentProvider(
                organization: 'My Company',
                url: 'https://mycompany.com'
            ),
            skills: [
                new AgentSkill(
                    id: 'analysis',
                    name: 'Data Analysis',
                    description: 'Analyze datasets',
                    tags: ['data', 'analytics'],
                    examples: ['Analyze sales data'],
                    inputModes: ['text/plain'],
                    outputModes: ['text/plain']
                )
            ]
        );
    }
}
```

#### 2. Implement Task Repository

[](#2-implement-task-repository)

```
use NeuronCore\A2A\Contract\TaskRepositoryInterface;
use NeuronCore\A2A\Model\Task;

class MyTaskRepository implements TaskRepositoryInterface
{
    public function save(Task $task): void
    {
        // Save to database, Redis, etc.
    }

    public function find(string $taskId): ?Task
    {
        // Retrieve from storage
    }

    public function findAll(array $filters = [], ?int $limit = null, ?int $offset = null): array
    {
        // Query with filters
    }

    public function count(array $filters = []): int
    {
        // Count tasks
    }

    public function generateTaskId(): string
    {
        return uniqid('task_', true);
    }

    public function generateContextId(): string
    {
        return uniqid('context_', true);
    }
}
```

#### 3. Implement Message Handler (Your AI Logic)

[](#3-implement-message-handler-your-ai-logic)

The message handler is responsible for handling incoming messages and returning task results. It's the place where you execute your AI Agent and return the results.

```
use NeuronAI\Agent;
use NeuronAI\Chat\Messages\UserMessage;
use NeuronCore\A2A\Contract\MessageHandlerInterface;
use NeuronCore\A2A\Model\Task;
use NeuronCore\A2A\Model\Message;
use NeuronCore\A2A\Model\Part\TextPart;
use NeuronCore\A2A\Model\Artifact;
use NeuronCore\A2A\Model\TaskStatus;
use NeuronCore\A2A\Enum\TaskState;

class MyMessageHandler implements MessageHandlerInterface
{
    public function handle(Task $task, array $messages): Task
    {
        $history = array_merge($task->history ?? [], $messages);

        // Extract user message
        $userText = $this->extractText($messages[0]);

        $aiResponse = Agent::make()
            ->setProvider(...)
            ->chat(new UserMessage($userText))
            ->getContent();

        // Create an agent response
        $agentMessage = new Message(
            role: 'agent',
            parts: [new TextPart($aiResponse)]
        );

        $history[] = $agentMessage;

        // Return a completed task
        return new Task(
            id: $task->id,
            contextId: $task->contextId,
            status: new TaskStatus(
                state: TaskState::COMPLETED,
                message: new TextPart('Task completed')
            ),
            history: $history,
        );
    }

    protected function extractText(Message $message): string
    {
        $text = '';
        foreach ($message->parts as $part) {
            if ($part instanceof TextPart) {
                $text .= $part->text;
            }
        }
        return $text;
    }
}
```

#### 4. Use the Server

[](#4-use-the-server)

```
use NeuronCore\A2A\JsonRpc\JsonRpcRequest;

// Create a server instance
$server = new MyAIAgent();

// Handle JSON-RPC request
$request = JsonRpcRequest::fromArray([
    'jsonrpc' => '2.0',
    'id' => 1,
    'method' => 'message/send',
    'params' => [
        'messages' => [
            [
                'role' => 'user',
                'parts' => [
                    ['kind' => 'text', 'text' => 'Hello!']
                ]
            ]
        ]
    ]
]);

$response = $server->handleRequest($request);
echo json_encode($response->toArray());
```

**See `examples/a2a.php` for a complete working example.**

---

### Laravel Integration

[](#laravel-integration)

Laravel gets first-class support with Artisan commands, service providers, and routing helpers.

#### 1. Register Service Provider

[](#1-register-service-provider)

In `config/app.php` or `bootstrap/providers.php` based on your project structure:

```
'providers' => [
    // ...
    NeuronCore\A2A\Laravel\A2AServiceProvider::class,
],
```

#### 2. Generate an Agent server

[](#2-generate-an-agent-server)

```
php artisan make:a2a DataAnalyst
```

**This generates:**

- `app/A2A/DataAnalystServer.php` - Main server
- `app/A2A/DataAnalystTaskRepository.php` - Task storage
- `app/A2A/DataAnalystMessageHandler.php` - AI logic

You must implement the Task Repository and Message Handler.

#### 4. Register Routes

[](#4-register-routes)

In `routes/api.php`:

```
use NeuronCore\A2A\Laravel\A2A;
use App\A2A\DataAnalystServer;

A2A::route('/a2a/data-analyst', DataAnalystServer::class)
    ->middleware(['auth:api']);
```

**Done!** Your agent is live at:

- `POST /a2a/data-analyst` - JSON-RPC endpoint
- `GET /a2a/data-analyst/.well-known/agent-card.json` - Agent card

#### Multiple Agents

[](#multiple-agents)

Create and register as many agents as needed:

```
php artisan make:a2a DataAnalyst
php artisan make:a2a Translator
php artisan make:a2a CodeGenerator
```

```
// routes/api.php
A2A::route('/a2a/data-analyst', DataAnalystServer::class);
A2A::route('/a2a/translator', TranslatorServer::class);
A2A::route('/a2a/code-generator', CodeGeneratorServer::class);
```

Each agent is completely independent with its own:

- Task repository
- Message handler (AI logic)
- Middleware configuration

---

Core Concepts
-------------

[](#core-concepts)

### Message Structure

[](#message-structure)

Messages follow the A2A protocol:

```
new Message(
    role: 'user',  // or 'agent'
    parts: [
        new TextPart('Hello'),
        new FilePart($file, 'image/png'),
        new DataPart(['key' => 'value'], 'application/json')
    ]
)
```

### Agent Card

[](#agent-card)

The agent card is a JSON manifest that describes:

- Agent identity (name, description, version)
- Provider information
- Available skills with examples
- Input/output formats
- Authentication requirements
- Protocol capabilities

### Task Context

[](#task-context)

Tasks can be grouped by `contextId` for conversation continuity:

- Multiple tasks can share the same context
- Use `tasks/list` with `contextId` filter to retrieve related tasks
- Useful for multi-turn conversations

---

API Reference
-------------

[](#api-reference)

### A2AServer Abstract Class

[](#a2aserver-abstract-class)

**Abstract Methods:**

```
abstract protected function taskRepository(): TaskRepositoryInterface;
abstract protected function messageHandler(): MessageHandlerInterface;
abstract protected function agentCard(): AgentCard;
```

**Public Methods:**

```
public function handleRequest(JsonRpcRequest $request): JsonRpcResponse|JsonRpcError;
public function getAgentCard(): array;
```

### TaskRepositoryInterface

[](#taskrepositoryinterface)

```
interface TaskRepositoryInterface
{
    public function save(Task $task): void;
    public function find(string $taskId): ?Task;
    public function findAll(array $filters = [], ?int $limit = null, ?int $offset = null): array;
    public function count(array $filters = []): int;
    public function generateTaskId(): string;
    public function generateContextId(): string;
}
```

### MessageHandlerInterface

[](#messagehandlerinterface)

```
interface MessageHandlerInterface
{
    public function handle(Task $task, array $messages): Task;
}
```

---

Advanced Usage
--------------

[](#advanced-usage)

### Custom Task Repository

[](#custom-task-repository)

Use Eloquent, Redis, File, or any storage backend:

```
class EloquentTaskRepository implements TaskRepositoryInterface
{
    public function save(Task $task): void
    {
        TaskModel::updateOrCreate(
            ['id' => $task->id],
            ['data' => serialize($task)]
        );
    }

    public function find(string $taskId): ?Task
    {
        $model = TaskModel::find($taskId);
        return $model ? unserialize($model->data) : null;
    }
}
```

### Authentication &amp; Middleware

[](#authentication--middleware)

Laravel example with custom middleware:

```
A2A::route('/a2a/premium-agent', DataAnalystAgent::class)
    ->middleware(['auth:api']);
```

### File Attachments

[](#file-attachments)

Handle file uploads in messages:

```
use NeuronCore\A2A\Model\Part\FilePart;
use NeuronCore\A2A\Model\File\FileWithBytes;
use NeuronCore\A2A\Model\File\FileWithUri;

// Embedded file
$filePart = new FilePart(
    file: new FileWithBytes(
        bytes: base64_encode($fileContents),
        fileName: 'document.pdf',
        mimeType: 'application/pdf'
    ),
    mimeType: 'application/pdf'
);

// File by URL
$filePart = new FilePart(
    file: new FileWithUri(
        uri: 'https://example.com/file.pdf',
        fileName: 'document.pdf',
        mimeType: 'application/pdf'
    ),
    mimeType: 'application/pdf'
);
```

### Structured Data

[](#structured-data)

Send and receive structured JSON data:

```
use NeuronCore\A2A\Model\Part\DataPart;

$dataPart = new DataPart(
    data: [
        'results' => [
            ['name' => 'Alice', 'score' => 95],
            ['name' => 'Bob', 'score' => 87]
        ],
        'total' => 2
    ],
    mimeType: 'application/json'
);
```

---

Contributing
------------

[](#contributing)

When contributing to this project:

- Use modern PHP 8.1+ features
- Maintain interface-driven design
- Write minimal, clean code
- Focus on simplicity and clarity

---

License
-------

[](#license)

MIT License—See LICENSE file for details

###  Health Score

38

—

LowBetter than 85% of packages

Maintenance60

Regular maintenance activity

Popularity26

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

209d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/320345fbe48c7cff2b3a25992c8207e959ae7817fb2fb97bb176dc6e559aacf5?d=identicon)[valerione](/maintainers/valerione)

---

Top Contributors

[![ilvalerione](https://avatars.githubusercontent.com/u/13559278?v=4)](https://github.com/ilvalerione "ilvalerione (16 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Rector

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/neuron-core-a2a/health.svg)

```
[![Health](https://phpackages.com/badges/neuron-core-a2a/health.svg)](https://phpackages.com/packages/neuron-core-a2a)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
