# How to Set Up the A2A Protocol in OmniRoute: Complete Configuration Guide

> Learn how to set up the A2A protocol in OmniRoute with this complete configuration guide. Enable A2A, restart the server, and expose the JSON-RPC endpoint to get started.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: how-to-guide
- Published: 2026-08-01

---

**To set up the A2A protocol in OmniRoute, export `OMNIROUTE_A2A_ENABLED=true`, restart the server, and expose the JSON‑RPC endpoint at `/a2a` alongside the Agent Card at [`/.well-known/agent.json`](https://github.com/diegosouzapw/OmniRoute/blob/main//.well-known/agent.json).**

OmniRoute (v3.8.50) ships with a built-in **Agent-to-Agent (A2A)** server that implements JSON‑RPC 2.0 with optional SSE streaming. This guide walks through enabling the protocol, configuring the task manager, and invoking built-in skills using the actual source implementation from the `diegosouzapw/OmniRoute` repository.

## Enable the A2A Server

The A2A endpoint is disabled by default. Activation requires a single environment variable and a process restart.

### Set the Environment Variable

Export `OMNIROUTE_A2A_ENABLED` and set it to `true` or `1`:

```bash
export OMNIROUTE_A2A_ENABLED=true

```

Or add it to your `.env` file:

```dotenv

# .env

OMNIROUTE_A2A_ENABLED=true

```

According to [`src/lib/a2a/README.md`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/a2a/README.md), this flag controls the **Endpoints → A2A** toggle and is read at startup by both the HTTP API layer and the A2A server initializer.

### Restart OmniRoute

After setting the flag, restart the process (or run `npm run dev` again) to load the configuration. Once active, the server exposes:
- [`/.well-known/agent.json`](https://github.com/diegosouzapw/OmniRoute/blob/main//.well-known/agent.json) — Public Agent Card (cached 1 hour)
- `/a2a` — Primary JSON‑RPC 2.0 entry point
- `/api/a2a/status` — Human-readable status dashboard

## Understand the Core Components

The A2A implementation in `src/lib/a2a/` consists of four key modules:

| Component | File | Purpose |
|-----------|------|---------|
| **Task Manager** | [`src/lib/a2a/taskManager.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/a2a/taskManager.ts) | Holds tasks in memory, enforces TTL (default 5 minutes), and purges expired entries every 60 seconds via the `A2ATaskManager` class. |
| **Task Execution** | [`src/lib/a2a/taskExecution.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/a2a/taskExecution.ts) | Dispatches incoming JSON‑RPC methods to registered handlers using the `A2A_SKILL_HANDLERS` registry. |
| **Streaming** | [`src/lib/a2a/streaming.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/a2a/streaming.ts) | Optional SSE layer that mirrors JSON‑RPC responses for long-running tasks. |
| **Skills** | `src/lib/a2a/skills/*.ts` | Six built-in skills: `smart-routing`, `quota-management`, `provider-discovery`, `cost-analysis`, `health-report`, and `list-capabilities`. |

## Access the A2A Endpoints

Once enabled, interact with the server via standard HTTP requests or the bundled CLI.

### Retrieve the Agent Card

The Agent Card describes capabilities and requires no authentication:

```bash
curl https://localhost:20128/.well-known/agent.json

```

### Invoke a Built-in Skill

Send a JSON‑RPC 2.0 POST request to `/a2a`. For example, calling `list-capabilities`:

```bash
curl -X POST https://localhost:20128/a2a \
  -H "Content-Type: application/json" \
  -d '{
        "jsonrpc":"2.0",
        "id":1,
        "method":"list-capabilities",
        "params":{}
      }'

```

### Check Status via CLI

OmniRoute provides a convenience command defined in [`docs/reference/CLI-TOOLS.md`](https://github.com/diegosouzapw/OmniRoute/blob/main/docs/reference/CLI-TOOLS.md) (line 656):

```bash
omniroute a2a status

```

This displays the Agent Card, current task statistics, and whether the A2A server is active.

## Register Custom Skills (Optional)

To extend functionality beyond the six defaults, register custom handlers in [`src/lib/a2a/taskExecution.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/a2a/taskExecution.ts).

### Create a Skill Handler

Create a new file in [`src/lib/a2a/skills/mySkill.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/a2a/skills/mySkill.ts):

```typescript
// src/lib/a2a/skills/mySkill.ts
export async function mySkill(task) {
  const result = await processTask(task.params);
  return { success: true, data: result };
}

```

### Register the Handler

Import and add the function to the `A2A_SKILL_HANDLERS` object in [`src/lib/a2a/taskExecution.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/a2a/taskExecution.ts):

```typescript
import { mySkill } from './skills/mySkill';

export const A2A_SKILL_HANDLERS = {
  smartRouting: /* existing */,
  quotaManagement: /* existing */,
  // ... other built-ins ...
  mySkill, // Your custom skill
};

```

Restart the server. The new skill is immediately addressable via JSON‑RPC using the method name `mySkill`.

## Tune the Task Manager (Advanced)

For long-running workflows (e.g., code generation pipelines), adjust the default TTL in [`src/lib/a2a/taskManager.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/a2a/taskManager.ts).

### Override Default TTL

The `A2ATaskManager` class accepts a custom TTL in minutes:

```typescript
import { A2ATaskManager } from './taskManager';

// Set TTL to 15 minutes instead of default 5
const manager = new A2ATaskManager(15);

```

The cleanup interval remains fixed at 60 seconds, but extending the TTL prevents premature eviction of stateful tasks.

## Summary

- **Enable A2A** by setting `OMNIROUTE_A2A_ENABLED=true` and restarting OmniRoute.
- **Core components** live in `src/lib/a2a/` and include the `A2ATaskManager`, `A2A_SKILL_HANDLERS` registry, and streaming utilities.
- **Built-in endpoints** include [`/.well-known/agent.json`](https://github.com/diegosouzapw/OmniRoute/blob/main//.well-known/agent.json) (Agent Card) and `/a2a` (JSON‑RPC).
- **Extend functionality** by adding handlers to `A2A_SKILL_HANDLERS` in [`taskExecution.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/taskExecution.ts).
- **Monitor** the server using `omniroute a2a status` or the `/api/a2a/status` REST endpoint.
- **Adjust task lifecycle** by instantiating `A2ATaskManager` with a custom TTL for long-running agents.

## Frequently Asked Questions

### What is the A2A protocol in OmniRoute?

The **A2A (Agent-to-Agent) protocol** in OmniRoute is a JSON‑RPC 2.0 server implementation that allows external AI agents to discover capabilities via an Agent Card and delegate tasks through structured RPC calls. It supports synchronous responses and optional SSE streaming for long-running operations, as defined in [`src/lib/a2a/README.md`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/a2a/README.md).

### How do I verify that the A2A server is running?

Check the human-readable status endpoint at `/api/a2a/status` or run the CLI command `omniroute a2a status`. Both return the current activation state, task statistics, and a cached copy of the Agent Card. You can also verify by fetching [`/.well-known/agent.json`](https://github.com/diegosouzapw/OmniRoute/blob/main//.well-known/agent.json) directly via curl.

### Can I disable authentication for the A2A endpoints?

The [`/.well-known/agent.json`](https://github.com/diegosouzapw/OmniRoute/blob/main//.well-known/agent.json) endpoint is public by design and requires no authentication. The `/a2a` JSON‑RPC endpoint follows the same authentication rules as the rest of the OmniRoute HTTP API (configured via the standard OmniRoute auth middleware), but the A2A implementation itself does not enforce additional auth layers beyond what the host HTTP stack provides.

### How do I handle long-running tasks in A2A?

Increase the task TTL by creating a custom `A2ATaskManager` instance with a higher timeout value (e.g., `new A2ATaskManager(15)` for 15 minutes). For real-time updates, connect to the SSE stream defined in [`src/lib/a2a/streaming.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/a2a/streaming.ts), which mirrors JSON‑RPC responses as server-sent events while the task remains active in the manager.