A2A Protocol

Agent-to-Agent

Llama a Claix desde otro agente con JSON-RPC, una Agent Card y las mismas skills que la API REST.

A2A Protocol

Claix como agente A2A

Endpoint

A2Ahttps://claix.dev/a2a

Claix expone un agente Agent-to-Agent (A2A) para que otros agentes lo invoquen con JSON-RPC 2.0, sin pasar por MCP ni reescribir la API REST. Reutiliza las mismas operaciones de extracción, consulta y schemas. Las skills se generan desde openapi.yaml.

Endpoint del protocolo: https://claix.dev/a2a. Agent Card pública: https://claix.dev/.well-known/agent.json (también en https://claix.dev/.well-known/agent-card.json).

1. Rutas públicas

MétodoRutaQué hace
GET/.well-known/agent.jsonAgent Card (descubrimiento). Sin API key.
GET/.well-known/agent-card.jsonMisma Agent Card (path del SDK oficial @a2a-js/sdk).
POST/a2aJSON-RPC 2.0 del protocolo A2A. Requiere API key.

Conecta el inspector o el cliente A2A al origen del sitio (https://claix.dev), no a /a2a, para que resuelva la Agent Card en /.well-known/. El campo url / supportedInterfaces de la card apunta a https://claix.dev/a2a.

2. Autenticación y límites

En cada POST /a2a envía la misma API key que en REST:

x-api-key: <TU_API_KEY>

Alternativa: Authorization: Bearer <TU_API_KEY>. Sin clave: JSON-RPC -32001 y HTTP 401. Clave inválida o cuenta inactiva: el mismo código. Límite: 60 peticiones por minuto por API key (HTTP 429, Retry-After).

La Agent Card es pública. Los mensajes, DataParts y cualquier card de un agente llamante se tratan como entrada no fiable y se validan antes de ejecutar nada.

3. Agent Card

La card declara name: Claix, la URL JSON-RPC, capabilities.pushNotifications: true, streaming: false y las 20 skills. El esquema de entrada de cada skill (parámetros OpenAPI, con file_base64 / file_path en lugar del file multipart) vive en la extensión https://claix.dev/a2a/extensions/openapi-skills.

Si el OpenAPI cambia, regenera las skills con npm run a2a:skills. No las edites a mano.

4. Cómo usarlo

  1. Descarga la Agent Card y elige una skill por id.
  2. Envía POST https://claix.dev/a2a con method: "message/send".
  3. Si ya tienes parámetros tipados, usa un DataPart JSON con "skill": "<id>". Se ejecuta de forma determinista, sin modelo de lenguaje.
  4. Si solo tienes texto ambiguo, usa un TextPart. Gemini 3.6 Flash elige la skill y los argumentos a partir de los mismos esquemas.
  5. Reutiliza el mismo contextId en mensajes siguientes para mantener el hilo (tabla conversaciones).

Métodos JSON-RPC habituales:

MétodoUso
message/sendCrear o continuar una tarea.
tasks/getConsultar el estado de una tarea ya creada.
tasks/cancelCancelar una tarea en curso.
tasks/pushNotificationConfig/setRegistrar el webhook para el resultado de tareas largas.

No hay message/stream / SSE. Las tareas largas no dejan la conexión abierta.

5. DataPart vs TextPart

EntradaComportamiento
DataPart con skill conocidaEnruta directo a la operación interna (misma lógica que la REST).
DataPart sin skillTarea input-required: indica el id de skill a usar.
skill desconocida o parámetro corruptoJSON-RPC -32602 Invalid params, con el campo y el motivo.
Falta un dato recuperable (space_id, schema_id, archivo…)Estado input-required, no error. El agente llamante puede completar el dato.
TextPart en lenguaje naturalGemini 3.6 Flash elige skill + parámetros. Único punto con LLM de enrutado.

Ejemplo DataPart: {"skill":"extract-pdf","schema_id":"<uuid>","file_base64":"<base64>"}. El archivo multipart de la REST se envía aquí como file_base64 o file_path (URL https pública).

6. Estados de tarea y formatos de respuesta

Una llamada correcta a message/send devuelve JSON-RPC result con un objeto Task (id, contextId, status.state, artefactos).

EstadoCuándo
completedTarea rápida resuelta en la misma respuesta (get-document, query-document, list/create/delete schema, space o document).
workingTarea larga encolada: extract-*, agent-extract-*, convert-json-to-excel, query-space. El resultado llega por push webhook.
input-requiredFalta un parámetro que el llamante puede aportar (p. ej. space_id).
failedLa operación de negocio falló (HTTP de Claix ≠ 2xx).
canceledEl llamante canceló la tarea.

El resultado de negocio va en un artefacto JSON, no en SSE:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "id": "<taskId>",
    "contextId": "<contextId>",
    "status": { "state": "completed" },
    "artifacts": [
      {
        "name": "list-schemas-result",
        "parts": [{ "kind": "data", "data": { "success": true, "schemas": [] } }]
      }
    ]
  }
}

Errores de protocolo (antes de crear la tarea):

HTTPcodeSignificado
401-32001Falta API key o no es válida.
429-32000Rate limit. Mira Retry-After.
400-32602Invalid params: tipo/formato corrupto.
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": { "code": -32602, "message": "Invalid params: schema_id — …" }
}

7. Tareas largas y push notifications

Extraer un PDF, razonar en modo agente o preguntar a un space_id con muchos documentos no espera en la conexión HTTP. La primera respuesta queda en working. Configura un webhook A2A (tasks/pushNotificationConfig/set) para recibir la Task final (completed o failed) con el artefacto.

capabilities.pushNotifications está a true. No uses streaming SSE para estas operaciones.

8. Conversación y contextId

El contextId de A2A identifica el hilo entre varias tareas. Claix lo guarda en conversaciones (context_id, user_id, last_task_id, last_activity_at). Reutiliza el mismo contextId en cada message/send del mismo diálogo.

9. Skills (desde OpenAPI)

Cada operación relevante del OpenAPI es una skill. Un DataPart debe incluir "skill": "<id>".

Skill A2AoperationId OpenAPIEndpoint REST
extract-excelexcelToJsonPOST /excel-json
convert-json-to-exceljsonToExcelPOST /json-excel
extract-pdfpdfToJsonPOST /pdf-json
extract-docdocToJsonPOST /doc-json
extract-imgimgToJsonPOST /img-json
extract-txttxtToJsonPOST /txt-json
get-documentgetDocumentGET /get-document/{document_id}
query-documentdocumentContextAskPOST /document-context/{document_id}
query-spacespaceContextAskPOST /space-context/{space_id}
create-spacecreateSpacePOST /create-space
delete-spacedeleteSpaceDELETE /delete-space/{space_id}
delete-documentdeleteDocumentDELETE /delete-document/{document_id}
agent-extract-excelagentExcelToJsonPOST /agent/excel-json
agent-extract-pdfagentPdfToJsonPOST /agent/pdf-json
agent-extract-docagentDocToJsonPOST /agent/doc-json
agent-extract-imgagentImgToJsonPOST /agent/img-json
agent-extract-txtagentTxtToJsonPOST /agent/txt-json
list-schemaslistSchemasGET /schemas
create-schemacreateSchemaPOST /create-schema
delete-schemadeleteSchemaPOST /delete-schema

10. Clientes

  • SDK oficial TypeScript: @a2a-js/sdk
  • Inspector: a2aproject/a2a-inspector contra https://claix.dev
  • Cualquier cliente JSON-RPC A2A 0.3 / 1.0 con push notifications

MCP y A2A son interfaces distintas. MCP sigue en https://claix.dev/mcp. Este agente no llama al servidor MCP.

Ejemplos de petición

curl -sS "https://claix.dev/.well-known/agent.json"