Package org.a2aproject.sdk.server.apps.quarkus


package org.a2aproject.sdk.server.apps.quarkus
Quarkus JSON-RPC reference implementation for the A2A protocol.

This package provides a production-ready JSON-RPC 2.0 server implementation built on Quarkus and Vert.x Web, demonstrating best practices for A2A protocol integration.

Architecture

 HTTP Request (JSON-RPC 2.0)
     ↓
 A2AServerRoutes (@Singleton)
     ├─ Parse JSON-RPC request
     ├─ Create ServerCallContext (via CallContextFactory)
     ├─ Route to JSONRPCHandler
     └─ Return JSON or SSE stream
         ↓
 JSONRPCHandler (transport layer)
     ↓
 DefaultRequestHandler (server-common)
     ↓
 AgentExecutor (your implementation)
 

Core Components

JSON-RPC Endpoint

Main Endpoint: POST /[tenant]

Agent Card: GET /.well-known/agent-card.json

Request Format


 POST /
 Content-Type: application/json

 {
   "jsonrpc": "2.0",
   "id": "req-123",
   "method": "sendMessage",
   "params": {
     "message": {
       "parts": [{"text": "Hello"}]
     }
   }
 }
 

Response Formats

Non-Streaming (JSON):


 HTTP/1.1 200 OK
 Content-Type: application/json

 {
   "jsonrpc": "2.0",
   "id": "req-123",
   "result": {
     "task": { ... }
   }
 }
 

Streaming (SSE):


 HTTP/1.1 200 OK
 Content-Type: text/event-stream

 id: 0
 data: {"jsonrpc":"2.0","id":"req-123","result":{...}}

 id: 1
 data: {"jsonrpc":"2.0","id":"req-123","result":{...}}
 

Error Response:


 HTTP/1.1 200 OK
 Content-Type: application/json

 {
   "jsonrpc": "2.0",
   "id": "req-123",
   "error": {
     "code": -32602,
     "message": "Invalid params"
   }
 }
 

Supported Methods

  • sendMessage - Send message (blocking)
  • sendStreamingMessage - Send message (streaming SSE)
  • subscribeToTask - Subscribe to task events (streaming SSE)
  • getTask - Get task by ID
  • listTasks - List tasks with filtering
  • cancelTask - Cancel task execution
  • getTaskPushNotificationConfig - Get push notification config
  • setTaskPushNotificationConfig - Create push notification config
  • listTaskPushNotificationConfigs - List push notification configs
  • deleteTaskPushNotificationConfig - Delete push notification config
  • getExtendedAgentCard - Get extended agent card

Multi-Tenancy

Tenant identification from request path:

  • POST / → empty tenant
  • POST /tenant1 → tenant "tenant1"
  • POST /org/team → tenant "org/team"

Customization

Custom Context Creation:

Provide a CDI bean implementing CallContextFactory:


 @ApplicationScoped
 public class CustomCallContextFactory implements CallContextFactory {
     @Override
     public ServerCallContext build(RoutingContext rc) {
         // Extract user from Quarkus security context
         User user = (rc.user() == null) ? UnauthenticatedUser.INSTANCE :
             new AuthenticatedUser(rc.user().subject());

         // Extract custom data from routing context
         Map<String, Object> state = new HashMap<>();
         state.put("organization", rc.request().getHeader("X-Org-ID"));

         // Extract A2A protocol version from header
         String version = rc.request().getHeader(A2AHeaders.X_A2A_VERSION);

         // Extract requested extensions from header
         List<String> extensionHeaders = rc.request().headers().getAll(A2AHeaders.X_A2A_EXTENSIONS);
         Set<String> extensions = A2AExtensions.getRequestedExtensions(extensionHeaders);

         return new ServerCallContext(user, state, extensions, version);
     }
 }
 

Configuration

No JSON-RPC-specific configuration required. Standard Quarkus HTTP configuration applies:

 quarkus.http.port=9999
 quarkus.http.host=0.0.0.0
 

Authentication

Uses Quarkus Security with @Authenticated annotation on routes. Configure authentication in application.properties:

 quarkus.security.users.embedded.enabled=true
 quarkus.security.users.embedded.plain-text=true
 quarkus.security.users.embedded.users.alice=password
 
See Also: