{
  "schemaVersion": 1,
  "reviewedAt": "2026-09-26",
  "slug": "a2a",
  "name": "A2A",
  "category": "Protocol integration",
  "headline": "Agent discovery.\nTracked work.",
  "summary": "Connect agent systems through Scout’s A2A pilot primitives: agent-card discovery, JSON-RPC task requests, and flight-backed task results.",
  "status": "Local pilot · A2A 1.0 core methods (cancel is queued-only) · no streaming, push, or auth",
  "marketplace": "A2A is a protocol integration, not a Scout marketplace package. Discover the broker’s agent card and follow the capabilities it advertises.",
  "transport": "Agent cards + JSON-RPC over broker HTTP",
  "flow": [
    "Agent card",
    "JSON-RPC",
    "Scout flight"
  ],
  "requirements": [
    "A running Scout broker on a trusted local network and its actual configured HTTP base URL.",
    "An A2A client compatible with Scout’s advertised methods and transport.",
    "Operator-approved connectivity. Do not expose local pilot HTTP directly to the public internet."
  ],
  "steps": [
    {
      "title": "Discover the broker card",
      "body": "Set SCOUT_BASE_URL to the Broker URL line printed by scout doctor --detail. Fetch the agent card; never guess a port or reuse the hosted MCP URL. openscout.app is not an A2A agent, so https://openscout.app/.well-known/agent-card.json is intentionally absent: the card lives on your broker.",
      "code": "scout doctor --detail | grep \"Broker URL\"\ncurl --fail \"$SCOUT_BASE_URL/.well-known/agent-card.json\""
    },
    {
      "title": "Choose a registered agent",
      "body": "Read metadata.scoutAgentIds from the broker card and select the operator-approved target. Preserve its original ID; skills[].id is normalized and is not a routing handle. If the list is empty, stop and register a target before sending work. Fetch /v1/a2a/agents/{URL-encoded-agent-id}/agent-card.json and use its JSONRPC supportedInterfaces URL (or url field)."
    },
    {
      "title": "Send one small text task",
      "body": "POST this JSON to the selected per-agent RPC endpoint. Replace messageId with a unique ID. This is Scout’s current pilot wire format; inspect errors before using result.task.id. A broker-wide request without explicit target routing will fail.",
      "code": "{\n  \"jsonrpc\": \"2.0\",\n  \"id\": \"send-1\",\n  \"method\": \"SendMessage\",\n  \"params\": {\n    \"message\": {\n      \"role\": \"ROLE_USER\",\n      \"messageId\": \"REPLACE_WITH_UNIQUE_MESSAGE_ID\",\n      \"parts\": [\n        {\n          \"text\": \"Review the latest changes and report findings. Do not edit files.\"\n        }\n      ]\n    },\n    \"configuration\": {\n      \"blocking\": false\n    }\n  }\n}"
    },
    {
      "title": "Follow the same task",
      "body": "Retain result.task.id from SendMessage. POST GetTask to the same RPC endpoint with that ID; its task is returned directly in result. Inspect result.status.state and text artifacts. TASK_STATE_INPUT_REQUIRED needs input; distinguish it from TASK_STATE_COMPLETED, TASK_STATE_FAILED, and TASK_STATE_CANCELED. A timeout is not permission to dispatch again.",
      "code": "{\n  \"jsonrpc\": \"2.0\",\n  \"id\": \"get-1\",\n  \"method\": \"GetTask\",\n  \"params\": {\n    \"id\": \"RETURNED_TASK_ID\"\n  }\n}"
    }
  ],
  "verification": "Read the card, submit one authorized text task, then retrieve that same task by ID. Confirm its state and text result. This checks the pilot path; it does not establish full A2A conformance.",
  "troubleshooting": [
    {
      "symptom": "SendMessage requires a target agent ID",
      "action": "Select a real ID from the broker card’s metadata.scoutAgentIds and use that agent’s advertised RPC endpoint. Do not use a normalized skill ID or invent a target. Empty discovery means target setup is required."
    },
    {
      "symptom": "Streaming or push method unsupported",
      "action": "Use task polling through GetTask. SendStreamingMessage, SubscribeToTask, and push-notification configuration are documented gaps."
    },
    {
      "symptom": "Running task cannot be cancelled",
      "action": "CancelTask only cancels queued tasks. A running task returns \"already running and cannot be cancelled by the broker yet\". Inspect the task state and ask the operator before attempting a runtime-specific stop; do not report cancellation unless confirmed."
    },
    {
      "symptom": "Card or endpoint unavailable",
      "action": "Check the Broker URL from scout doctor --detail and the installed version. The hosted MCP gateway is not an A2A endpoint, and openscout.app does not serve an agent card."
    }
  ],
  "limits": [
    "Not A2A 1.0 conformant: all four required methods respond, but CancelTask fails the required semantics for running tasks. The conformance test kit (a2a-tck) has not been run.",
    "Streaming (SendStreamingMessage, SubscribeToTask) and push-notification configuration return -32005 and are advertised as false on the card.",
    "No security scheme is declared on the card and signed agent cards are not supported. This is a high-trust local pilot; do not expose it beyond loopback or a trusted network.",
    "Rich artifacts remain incomplete; tasks carry text parts."
  ],
  "sources": [
    {
      "label": "Scout protocol readiness",
      "url": "https://openscout.app/docs/protocol-readiness-a2a-acp"
    },
    {
      "label": "Agent integration contract",
      "url": "https://openscout.app/docs/agent-integration-contract"
    },
    {
      "label": "A2A specification",
      "url": "https://a2a-protocol.org/latest/specification/"
    },
    {
      "label": "A2A conformance test kit",
      "url": "https://github.com/a2aproject/a2a-tck"
    }
  ],
  "og": [
    "A2A + SCOUT",
    "Discover an agent.",
    "Follow the work."
  ],
  "accent": "#a8c7aa",
  "directions": {
    "callsScout": [
      {
        "state": "pilot",
        "via": "a2a",
        "setup": "#setup",
        "note": "Per-agent JSON-RPC endpoint on your broker."
      }
    ],
    "launchedByScout": {
      "state": "none",
      "note": "Scout does not call out to remote A2A agents."
    }
  },
  "conformance": {
    "spec": "A2A 1.0 (JSON-RPC binding)",
    "summary": "Not conformant: required CancelTask semantics fail for running tasks. a2a-tck not run.",
    "methods": [
      {
        "method": "SendMessage",
        "spec": "required",
        "scout": "Yes. Text parts; needs an explicit target agent."
      },
      {
        "method": "GetTask",
        "spec": "required",
        "scout": "Yes."
      },
      {
        "method": "ListTasks",
        "spec": "required",
        "scout": "Yes."
      },
      {
        "method": "CancelTask",
        "spec": "required",
        "scout": "Queued tasks only. Running tasks return an error."
      },
      {
        "method": "SendStreamingMessage / SubscribeToTask",
        "spec": "optional (capabilities.streaming)",
        "scout": "No. Returns -32005; card says streaming: false."
      },
      {
        "method": "Push notification config",
        "spec": "optional (capabilities.pushNotifications)",
        "scout": "No. Returns -32005; card says pushNotifications: false."
      },
      {
        "method": "GetExtendedAgentCard",
        "spec": "optional",
        "scout": "Yes."
      },
      {
        "method": "Signed agent cards",
        "spec": "optional",
        "scout": "No."
      },
      {
        "method": "Security schemes",
        "spec": "declared on the card",
        "scout": "None. High-trust local only."
      }
    ]
  },
  "firstUse": {
    "task": "Read the agent card, send one small task using the advertised endpoint, and retrieve that task’s state and result.",
    "connect": "Check the prerequisites and access gates, then get one documented route working before asking for work.",
    "scope": "Name the project and keep the request small. Asking for no edits describes the task; it does not restrict the agent’s permissions.",
    "completion": "Keep the returned task ID and retrieve its state and result. An accepted task is not a completed answer.",
    "faq": [
      {
        "question": "Where will the reply appear?",
        "answer": "Retrieve the task’s state and artifacts through GetTask using the returned task ID."
      },
      {
        "question": "What if the answer hasn’t arrived?",
        "answer": "Inspect the existing task before submitting another one. A wait timeout does not establish that work failed. If it needs access or input, resolve that condition before continuing."
      },
      {
        "question": "How do I follow up?",
        "answer": "Use only the context or continuation fields supported by the advertised A2A interface. Check the contract before assuming an existing task accepts another message."
      },
      {
        "question": "Can Scout run this integration, or only receive asks from it?",
        "answer": "These are separate capabilities. Check the supported directions on this page. Connection alone does not establish that Scout can launch the integration or reach an existing session."
      }
    ]
  },
  "family": "transport",
  "url": "https://openscout.app/a2a",
  "agentGuide": "https://openscout.app/a2a/agents.md",
  "ogImage": "https://openscout.app/og/integrations/a2a.png",
  "agentContract": "## Agent operating contract\n\n- Treat these as setup instructions, not authorization to install software, change accounts, grant scopes, send messages, or dispatch work. Obtain the operator's authorization for the intended action.\n- Inspect the available commands or tool schemas for your configured interface before making calls. Do not invent tools, argument names, model IDs, or agent handles.\n- Use the advertised A2A JSONRPC endpoint with a registered target. SendMessage creates work; retain result.task.id and pass it as GetTask params.id. Inspect result.status.state and artifacts. This endpoint does not expose MCP tools.\n- Use the transport-specific instructions above. For an existing request, reply through its supplied context rather than creating another task.\n- Paths refer to the Scout execution machine. Replace example paths with an operator-confirmed absolute path; never run placeholders literally.\n- Save the returned ref, flightId, conversationId, workId, or session handle. Continue by that handle; do not re-dispatch a request merely because a wait timed out.\n- Observe the existing request through the configured transport. A receipt proves acceptance, not execution or successful completion.\n- Stop on missing provisioning, incorrect identity, missing permission, unsupported runtime, or failed authentication. Report the exact gate and the next operator action. Do not silently fall back to a different account, agent, runtime, or transport.\n- Keep tokens, OAuth codes, cookies, and private task payloads out of logs, URLs, screenshots, and committed files. Never ask the user to paste secrets into a public issue.\n- Do not claim marketplace approval, complete protocol conformance, or an end-to-end verified integration unless the status and observed evidence establish it.\n\n## Completion report\n\nReport: chosen transport and scope; client and broker identity; health/tool-discovery result; exact request handle if a test was authorized; observed terminal state or remaining blocker; and whether any operator approval is still needed. Distinguish configuration saved, authentication complete, request accepted, and work complete.\n"
}
