Token导航 LogoToken导航TokenDH.com
ARDF MCP A2A logo
浏览器工具stdio官方级别未说明来源级核验

ARDF MCP A2A

MCP Server

一个连接MCP(模型上下文协议)和A2A代理的桥接服务,通过MCP工具协调任务并管理代理间的通信。

工具数

3

提示词数

0

GitHub Stars

2

资源数

0
HTMLDocker浏览器自动化

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

MauricioPerera

提供方

MauricioPerera

最后核验

2026/5/17 20:23

运行时

Docker

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

命令预览

docker run --rm -p 3000:3000 \

详细介绍

ARDF Subagent Profile + MCP ↔ A2A Bridge

](https://www.npmjs.com/package/mcp-bridge-a2a) ](https://www.npmjs.com/package/mcp-bridge-a2a) ](https://github.com/MauricioPerera/ARDF-MCP-A2A/releases) ![Tarball SHA256](https://github.com/MauricioPerera/ARDF-MCP-A2A/releases/latest)

Repositorio con el perfil ARDF subagent@v0.1 y un servidor MCP en Node/TypeScript que actúa como puente hacia agentes A2A.

Índice

Contenido

  • schemas/subagent.v0.1.json: JSON Schema (draft 2020-12) que describe cómo publicar un subagente (type subagent) como recurso MCP.
  • examples/ventas-subagent.json: Manifiesto de ejemplo que enlaza con un Agent Card A2A y declara los tools MCP (subagent_start, subagent_send, subagent_cancel).
  • src/server.ts: Servidor MCP sobre HTTP streamable usando el SDK oficial; expone el recurso del subagente, materializa tareas a2a://task/{id} y reenvía las llamadas A2A.

Uso

npm install
npm run dev
# Cliente MCP -> http://localhost:3000/mcp

Flujo sugerido con un cliente MCP:

  1. Leer a2a-agent://ventas-core para obtener el manifiesto ARDF.
  2. Invocar subagent_start con un mensaje (text: "Hola"); la respuesta incluye un resource_link a a2a://task/{id} y structuredContent con { taskUri, taskId }.
  3. Suscríbase a ese recurso (resources/subscribe) y continúe con subagent_send o finalice con subagent_cancel.

Uso rápido

  • Arranque el servidor:
  npm install
  npm run dev
  # Servidor MCP en http://localhost:3000/mcp
  • Ejemplo de invocación directa a /mcp para subagent_start (usando curl):
  curl -s \
    -X POST http://localhost:3000/mcp \
    -H "Content-Type: application/json" \
    -H "Accept: application/json, text/event-stream" \
    -d '{
      "type":"request",
      "method":"tools/call",
      "params":{
        "name":"subagent_start",
        "arguments":{"subagentUri":"a2a-agent://ventas-core","text":"Hola"}
      },
      "id":1
    }'
  • Respuesta esperada (forma general):
  {
    "type": "response",
    "result": {
      "content": [
        { "type": "resource_link", "uri": "a2a://task/abc-123" },
        { "type": "text", "text": "{\"taskUri\":\"a2a://task/abc-123\",\"taskId\":\"abc-123\"}" }
      ],
      "isError": false,
      "structuredContent": { "taskUri": "a2a://task/abc-123", "taskId": "abc-123" }
    },
    "id": 1
  }
  • Siguiente paso: suscríbase a a2a://task/{id} para recibir notifications/resources/updated y continúe con subagent_send o finalice con subagent_cancel.

Notas de implementación

  • El schema valida IDs, transporte preferido, mapping de skills A2A e identifica los tools MCP que orquestan la tarea.
  • server.ts usa ResourceTemplate para publicar a2a-agent://{id} y a2a://task/{taskId}, enviando notifications/resources/updated cuando el estado cambia.
  • Los tools consumen el Agent Card remoto y llaman a los endpoints JSON-RPC (message/send, tasks/cancel) del agente A2A, manteniendo un almacén en memoria de las tareas activas.
  • La enumeración de subagentes implementada con ResourceTemplate.list debe devolver un objeto { resources: [...] } (no un array directo).
  • Las URIs de subagente usan el esquema a2a-agent://{id}; el id se extrae del hostname de la URI (y se admite como pathname para compatibilidad).
  • El transporte HTTP streamable está configurado con enableJsonResponse: true y sin gestión de sesión (sessionIdGenerator: undefined):

- El cliente DEBE incluir Accept: application/json, text/event-stream. - El encabezado Mcp-Protocol-Version se negocia automáticamente si no se envía; no se requiere Mcp-Session-Id por defecto.

Personalización

  • Sustituye examples/ventas-subagent.json por tus propios subagentes o carga varios en SUBAGENTS.
  • Añade autenticación según security (OAuth2, API key, mTLS) ajustando jsonRpc.
  • Si el Agent Card anuncia message/stream, incorpora un listener SSE y utiliza notifyTaskUpdated para reflejar eventos en tiempo real.

Visión general

  • Propósito: Puente entre MCP (Model Context Protocol) y agentes A2A, exponiendo subagentes como recursos MCP y orquestando tareas mediante tools.
  • Contexto: MCP ofrece un contrato uniforme para recursos y herramientas; A2A define Agent Cards y endpoints JSON-RPC para mensajería y tareas.
  • Resultado: Clientes MCP pueden descubrir, iniciar y manejar conversaciones/tareas con agentes A2A sin conocer los detalles internos.

Arquitectura

  • Componentes principales:

- Servidor MCP HTTP streamable en src/server.ts. - Recursos: - a2a-agent://{id}: manifiesto ARDF del subagente. - a2a://task/{taskId}: estado de la tarea/conversación. - Tools: - subagent_start: inicia una tarea con un mensaje inicial. - subagent_send: envía mensajes adicionales a una tarea existente. - subagent_cancel: solicita cancelar una tarea.

  • Flujo de datos:

- Descubrimiento → resources/list y resources/read del subagente. - Inicio → tools/call subagent_start → creación y publicación de a2a://task/{taskId}. - Continuación/Cancelación → subagent_send/subagent_cancel → actualizaciones y notificaciones.

  • Notificaciones: El servidor envía notifications/resources/updated cuando cambian los recursos a2a://task/{taskId}.

Configuración

  • Subagentes:

- Archivo de ejemplo: examples/ventas-subagent.json. - Puedes cargar múltiples manifiestos en una estructura SUBAGENTS en src/server.ts.

  • Seguridad (a nivel de Agent Card):

- Ajusta encabezados Authorization para OAuth2 o API keys, o configura mTLS según el security del manifest.

  • Transporte MCP:

- enableJsonResponse: true y sin sesión por defecto. - Requisitos del cliente: Accept: application/json, text/event-stream. - Mcp-Protocol-Version se negocia si no se envía; Mcp-Session-Id no requerido por defecto.

  • Streaming SSE (message/stream):

- Variables de entorno: - SSE_IDLE_TIMEOUT_MS (por defecto 30000) tiempo de inactividad antes de abortar. - SSE_RETRY_BASE_MS (por defecto 1000) base del backoff exponencial. - SSE_RETRY_MAX_MS (por defecto 30000) máximo del backoff. - SSE_MAX_ATTEMPTS (por defecto , en test 1) límite de reconexiones del listener SSE. - En modo test, el listener limita reconexiones para evitar bucles.

  • Persistencia y directorio de datos:

- DATA_DIR: ruta para almacenar tasks.json. Por defecto ./data/. - Escritura atómica de tareas y limpieza periódica configurable: TASK_TTL_MS (TTL, por defecto 24h), TASK_CLEANUP_INTERVAL_MS (intervalo de compactación, por defecto 5min).

  • Endpoint de salud:

- GET /healthz devuelve { ok, activeSse, tasks, uptime } útil para probes.

  • En modo test, el listener limita reconexiones para evitar bucles.

Autenticación

  • Recomendaciones generales:

- No commitees secretos en manifiestos; usa variables de entorno y mecanismos seguros de inyección. - Si tus manifests usan placeholders (${VAR}), sustitúyelos antes de cargar el archivo o genera el manifest a partir de plantillas.

  • OAuth2 (Bearer):

- Define VENTAS_TOKEN (u otro nombre según tu agente) y referencia en encabezados Authorization: Bearer ${VENTAS_TOKEN} dentro del manifest. - Renueva el token fuera del bridge (cron, CI/CD) y recarga el manifest si cambia. - Estrategia de refresh: mantén un job que obtenga tokens de corta duración y actualice la variable de entorno; evita tokens perpetuos.

  • API Key:

- Define FINANZAS_API_KEY y referencia en encabezados X-API-Key: ${FINANZAS_API_KEY}. - Rotación: usa mecanismos de rotación segura y métricas para detectar uso indebido.

  • mTLS:

- Evita incluir PEMs en el repositorio; usa inyección por archivo/volumen y variables como CLIENT_CERT_PEM, CLIENT_KEY_PEM. - Opción recomendada: Reverse proxy (Nginx/Envoy) con client cert del lado del proxy; el bridge habla HTTP(s) interno sin manejar certificados. - Si necesitas mTLS desde el bridge, usa una librería HTTP que soporte client cert (axios/node-fetch) y configura cert/key a partir de secretos; valida que tu runtime soporte esta opción. - Validación: verifica fecha de expiración y subject del cert al inicio y registra errores claros si faltan o son inválidos.

Despliegue Docker/Cloud

  • Variables de entorno típicas:

- SSE_IDLE_TIMEOUT_MS, SSE_RETRY_BASE_MS, SSE_RETRY_MAX_MS. - Credenciales: VENTAS_TOKEN, FINANZAS_API_KEY, CLIENT_CERT_PEM, CLIENT_KEY_PEM.

  • Docker (ejemplo de comandos):
  # Construir imagen
  docker build -t mcp-a2a-bridge .

  # Ejecutar con variables de entorno y volumen para manifests
  docker run --rm -p 3000:3000 \
    -e SSE_IDLE_TIMEOUT_MS=30000 \
    -e SSE_RETRY_BASE_MS=1000 \
    -e SSE_RETRY_MAX_MS=30000 \
    -e VENTAS_TOKEN=REDACTED \
    -v %cd%/examples:/app/examples \
    mcp-a2a-bridge
  • Docker Compose (idea general):
  services:
    bridge:
      image: mcp-a2a-bridge:latest
      ports:
        - "3000:3000"
      environment:
        SSE_IDLE_TIMEOUT_MS: 30000
        SSE_RETRY_BASE_MS: 1000
        SSE_RETRY_MAX_MS: 30000
        VENTAS_TOKEN: ${VENTAS_TOKEN}
      volumes:
        - ./examples:/app/examples
  • Cloud (lineamientos):

- Usa secretos gestionados (Render, Fly.io, Railway, etc.) y mapea a variables de entorno. - Expone el puerto 3000 y configura health checks básicos en / si tu plataforma lo requiere. - Monta examples/ como volumen o empaqueta manifests en la imagen si son públicos.

Publicación en npm

Pasos típicos:

  1. Inicia sesión: npm login
  2. Dry run opcional: npm publish --dry-run (ejecuta automáticamente prepacknpm run build)
  3. Publica: npm publish
  4. Uso rápido vía npx:
  • - npx mcp-bridge-a2a@latest (si el paquete expone un script de arranque) o instala global:
  • - npm i -g mcp-bridge-a2a y luego mcp-a2a-bridge

+ 4. Uso rápido vía npx: + - npx mcp-a2a-bridge (ejecuta el bin del paquete) + - o instala global: npm i -g mcp-bridge-a2a y luego mcp-a2a-bridge

Notas:

  • El bin del paquete es mcp-a2a-bridge → ejecuta dist/server.js.
  • Requiere Node.js >= 18.

Ejemplos de payloads

  • Petición resources/list (cliente):
{
  "type": "request",
  "method": "resources/list",
  "params": {},
  "id": 1
}
  • Respuesta resources/list (servidor):
{
  "type": "response",
  "result": {
    "resources": [
      { "uri": "a2a-agent://ventas-core", "name": "Ventas Core", "mimeType": "application/json" }
    ]
  },
  "id": 1
}
  • Petición resources/read de subagente:
{
  "type": "request",
  "method": "resources/read",
  "params": { "uri": "a2a-agent://ventas-core" },
  "id": 2
}
  • Respuesta resources/read de subagente:
{
  "type": "response",
  "result": {
    "contents": [
      { "type": "text", "text": "Manifiesto ARDF", "mimeType": "application/json" },
      { "type": "json", "json": { /* contenido del manifest */ } }
    ]
  },
  "id": 2
}
  • Petición tools/call subagent_start:
{
  "type": "request",
  "method": "tools/call",
  "params": {
    "name": "subagent_start",
    "arguments": { "subagentUri": "a2a-agent://ventas-core", "text": "Hola" }
  },
  "id": 3
}
  • Respuesta tools/call subagent_start:
{
  "type": "response",
  "result": {
    "content": [
      { "type": "resource_link", "uri": "a2a://task/abc-123" },
      { "type": "text", "text": "{\"taskUri\":\"a2a://task/abc-123\",\"taskId\":\"abc-123\"}" }
    ],
    "isError": false,
    "structuredContent": { "taskUri": "a2a://task/abc-123", "taskId": "abc-123" }
  },
  "id": 3
}
  • Petición tools/call subagent_send:
{
  "type": "request",
  "method": "tools/call",
  "params": {
    "name": "subagent_send",
    "arguments": { "taskId": "abc-123", "text": "Siguiente mensaje" }
  },
  "id": 4
}
  • Respuesta tools/call subagent_send:
{
  "type": "response",
  "result": {
    "content": [ { "type": "text", "text": "Mensaje enviado" } ],
    "isError": false,
    "structuredContent": { "ok": true }
  },
  "id": 4
}
  • Petición tools/call subagent_cancel:
{
  "type": "request",
  "method": "tools/call",
  "params": {
    "name": "subagent_cancel",
    "arguments": { "taskId": "abc-123" }
  },
  "id": 5
}
  • Respuesta tools/call subagent_cancel:
{
  "type": "response",
  "result": {
    "content": [ { "type": "text", "text": "Tarea cancelada" } ],
    "isError": false,
    "structuredContent": { "canceled": true }
  },
  "id": 5
}
  • Petición resources/read de tarea:
{
  "type": "request",
  "method": "resources/read",
  "params": { "uri": "a2a://task/abc-123" },
  "id": 6
}
  • Respuesta resources/read de tarea (ejemplo):
{
  "type": "response",
  "result": {
    "contents": [
      { "type": "json", "json": { "taskId": "abc-123", "status": "running", "messages": [] } }
    ]
  },
  "id": 6
}

Diagrama de notificaciones (SVG)

Para un diagrama detallado del flujo de suscripciones y eventos SSE, ver docs/notifications.svg.

Validación de esquemas (JSON Schema)

  • El esquema de subagentes está en schemas/subagent.v0.1.json.
  • Recomendación: valida tus manifiestos con una librería de JSON Schema (p. ej., Ajv) antes de cargarlos en el bridge.
  • Puntos clave a validar:

- type debe ser subagent. - id único y estable. - a2a.agentCardUri accesible y válido. - security acorde (OAuth2, API Key, mTLS) y sin secretos hardcodeados. - mcpBridge.tools declara al menos subagent_start (y opcionalmente subagent_send, subagent_cancel). - taskResourceTemplate con el patrón a2a://task/{taskId}.

  • Ejemplo de validación conceptual:

- Instala una librería de validación en tu pipeline y falla el build si el manifest no cumple el schema.

Manifest avanzado (API Key + mTLS)

Ejemplo ilustrativo de un subagente que usa API Key y mTLS para llamadas JSON-RPC:

{
  "type": "subagent",
  "id": "finanzas-core",
  "name": "Finanzas Core",
  "a2a": {
    "agentCardUri": "https://finanzas.example.com/.well-known/agent-card.json"
  },
  "security": {
    "auth": {
      "type": "apiKey",
      "in": "header",
      "name": "X-API-Key",
      "value": "${FINANZAS_API_KEY}"
    },
    "mtls": {
      "enabled": true,
      "clientCert": "${CLIENT_CERT_PEM}",
      "clientKey": "${CLIENT_KEY_PEM}"
    }
  },
  "mcpBridge": {
    "tools": [
      { "name": "subagent_start" },
      { "name": "subagent_send" },
      { "name": "subagent_cancel" }
    ]
  },
  "taskResourceTemplate": "a2a://task/{taskId}",
  "capabilities": {
    "message": {
      "send": {
        "endpoint": "https://finanzas.example.com/json-rpc/message/send",
        "headers": { "X-API-Key": "${FINANZAS_API_KEY}" },
        "mtls": true
      }
    },
    "tasks": {
      "get": {
        "endpoint": "https://finanzas.example.com/json-rpc/tasks/get",
        "headers": { "X-API-Key": "${FINANZAS_API_KEY}" },
        "mtls": true
      },
      "cancel": {
        "endpoint": "https://finanzas.example.com/json-rpc/tasks/cancel",
        "headers": { "X-API-Key": "${FINANZAS_API_KEY}" },
        "mtls": true
      }
    }
  }
}

Notas:

  • Usa variables de entorno para credenciales y claves mTLS; no las incluyas en el repositorio.
  • Verifica certificados y claves en tiempo de arranque y reporta errores claros si faltan.

FAQ (Preguntas frecuentes)

  • ¿Por qué no veo recursos en resources/list?

- Asegúrate de que ResourceTemplate.list devuelve { resources: [...] } y no un array directo. - Confirma que hay manifiestos cargados en SUBAGENTS y que sus URIs a2a-agent://{id} se publican.

  • ¿Recibo error de protocolo o encabezados inválidos?

- Incluye Accept: application/json, text/event-stream y permite que el servidor negocie Mcp-Protocol-Version si falta.

  • ¿subagent_start no devuelve resource_link?

- Revisa que el agente A2A devuelva taskId; el bridge construye a2a://task/{taskId} a partir de ese valor.

  • ¿Se parsea mal subagentUri?

- Para URIs como a2a-agent://ventas-core, el ID se extrae del hostname. Se admite pathname por compatibilidad.

  • ¿No recibo actualizaciones de la tarea?

- Suscríbete al recurso a2a://task/{id} con resources/subscribe y mantén SSE activo para notifications/resources/updated.

Pruebas

  • Ejecutar: npm test.
  • El archivo test/mcp.spec.ts cubre:

- resources/list + resources/read de subagentes. - tools/call para subagent_start, subagent_send, subagent_cancel.

  • Mock de fetch para simular respuestas A2A.
  • Validaciones clave:

- ResourceTemplate.list devuelve { resources: [...] }. - Accept incluye application/json, text/event-stream. - resource_link.uri correcto en subagent_start.

Troubleshooting

  • Error: expected undefined to be an instance of Array en resources/list.

- Causa: El callback de ResourceTemplate.list devuelve un array en lugar de { resources }. - Solución: Devolver { resources: [...] }.

  • tools/call subagent_start no devuelve resource_link.

- Causa: Falta taskId en la respuesta del agente A2A. - Solución: Asegurar que la respuesta A2A incluya taskId y construir a2a://task/{taskId}.

  • Identificador de subagente incorrecto.

- Causa: Extracción desde pathname cuando la URI es a2a-agent://{id}. - Solución: Extraer desde hostname y usar pathname solo por compatibilidad.

  • Protocolo/encabezados.

- Causa: Accept incorrecto o versión MCP no negociada. - Solución: Incluir Accept: application/json, text/event-stream; permitir negociación de Mcp-Protocol-Version.

Glosario

  • ARDF: Esquema para describir recursos y capacidades de agentes.
  • MCP: Protocolo para herramientas y recursos de contexto.
  • A2A: Protocolo para agentes y sus interacciones JSON-RPC.
  • Agent Card: Documento que describe endpoints y capacidades de un agente A2A.
  • ResourceTemplate: Utilidad del SDK MCP para publicar familias de URIs.

Diagrama de arquitectura (ASCII)

+--------------------+            HTTP (JSON/SSE)            +-------------------------+
|    Cliente MCP     |-------------------------------------->|   Servidor MCP (bridge) |
| (Inspector, IDE)   |    resources/*, tools/call            |   src/server.ts         |
+--------------------+                                       +-----------+-------------+
                                                                     |  JSON-RPC
                                                                     v
                                                              +------+----------------+
                                                              |   Agente A2A remoto  |
                                                              | (Agent Card: send,   |
                                                              |  stream, tasks/*)    |
                                                              +----------------------+

Versión SVG (detallada): docs/architecture.svg

  • Descubrimiento: El cliente llama resources/list y resources/read.
  • Orquestación: tools/call ejecuta message/send y publica a2a://task/{id}.
  • Actualizaciones: El servidor envía notifications/resources/updated a suscriptores.

Manifest avanzado (OAuth2 + SSE)

Ejemplo ilustrativo de un subagente con autenticación Bearer y message/stream para SSE:

{
  "type": "subagent",
  "id": "ventas-core",
  "name": "Ventas Core",
  "a2a": {
    "agentCardUri": "https://ventas.example.com/.well-known/agent-card.json"
  },
  "security": {
    "auth": {
      "type": "oauth2",
      "token": "${VENTAS_TOKEN}",
      "scopes": ["message:send", "tasks:read", "tasks:cancel"]
    }
  },
  "mcpBridge": {
    "tools": [
      { "name": "subagent_start" },
      { "name": "subagent_send" },
      { "name": "subagent_cancel" }
    ]
  },
  "taskResourceTemplate": "a2a://task/{taskId}",
  "capabilities": {
    "message": {
      "send": {
        "endpoint": "https://ventas.example.com/json-rpc/message/send",
        "headers": { "Authorization": "Bearer ${VENTAS_TOKEN}" }
      },
      "stream": {
        "endpoint": "https://ventas.example.com/events/message/stream",
        "sse": true,
        "headers": { "Authorization": "Bearer ${VENTAS_TOKEN}" }
      }
    },
    "tasks": {
      "get": {
        "endpoint": "https://ventas.example.com/json-rpc/tasks/get",
        "headers": { "Authorization": "Bearer ${VENTAS_TOKEN}" }
      },
      "cancel": {
        "endpoint": "https://ventas.example.com/json-rpc/tasks/cancel",
        "headers": { "Authorization": "Bearer ${VENTAS_TOKEN}" }
      }
    }
  }
}

Notas:

  • Usa variables de entorno (${VENTAS_TOKEN}) para no commitear secretos.
  • Si message/stream está presente, el servidor puede abrir SSE y llamar a notifyTaskUpdated con cada evento.

Integración con clientes MCP (rápida)

  • Encabezados recomendados:

- Accept: application/json, text/event-stream - Mcp-Protocol-Version: 2024-10-01 (opcional; el servidor negocia si falta)

  • Endpoints típicos (ejemplo de curl):
# resources/list
curl -s -X POST \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  http://localhost:3000/mcp \
  -d '{"type":"request","method":"resources/list","params":{},"id":1}'

# tools/call subagent_start
curl -s -X POST \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  http://localhost:3000/mcp \
  -d '{"type":"request","method":"tools/call","params":{"name":"subagent_start","arguments":{"subagentUri":"a2a-agent://ventas-core","text":"Hola"}},"id":2}'

# resources/read de tarea
curl -s -X POST \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  http://localhost:3000/mcp \
  -d '{"type":"request","method":"resources/read","params":{"uri":"a2a://task/abc-123"},"id":3}'

Sugerencias:

  • Suscríbete a a2a://task/{id} (resources/subscribe) para recibir resources/updated via SSE.
  • Valida siempre structuredContent contra outputSchema del tool.

目录标签

目录标签

HTMLDocker浏览器自动化本地部署协议桥接任务协调代理通信JSON-RPCMCP协议

接入字段

传输方式(transport,传输协议)

stdio

鉴权方式(authType,认证方式)

api-key

运行时(runtime,运行环境)

Docker

工具数量(toolCount,工具数)

3

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

stdioapi-key部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

来源信息

继续浏览同类 MCP