{"slug": "cross-cloud-amazon-bedrock-agentcore-with-microsoft-foundry-over-a2a", "title": "Cross Cloud Amazon Bedrock AgentCore with Microsoft Foundry over A2A", "summary": "On July 29, 2026, a developer successfully tested cross-cloud interoperability between Amazon Bedrock AgentCore and Microsoft Foundry over the Agent-to-Agent (A2A) v1.0 protocol. The demo converted 100 USD to EUR using both an MCP tool and a Foundry-hosted agent, with a deterministic comparator reporting zero difference. The project, available on GitHub, demonstrates transport, authentication, and cross-framework agreement.", "body_md": "I wanted to test one specific path:\n\n``` php\nAmazon Bedrock AgentCore (AWS)\n    |\n    +-- MCP --> live exchange-rate tool\n    |\n    +-- A2A v1.0 --> Microsoft Foundry hosted agent (Azure)\n```\n\nOn July 29, 2026, that path worked end to end. An AgentCore-hosted Strands\n\ncoordinator called a Microsoft Foundry agent over A2A v1.0, authenticated with\n\nMicrosoft Entra, and compared the reply with an independent MCP conversion.\n\nFor the smoke case, both sides converted 100 USD to EUR using a rate of\n\n`0.87873`\n\nand returned `87.87300`\n\n. The deterministic comparator reported zero\n\nrelative difference and no warnings.\n\nThis article shows how to run that demo and documents what failed on the way.\n\nThe code is in\n\n[xbill9/bedrock-foundry-a2a-currency](https://github.com/xbill9/bedrock-foundry-a2a-currency).\n\nThis is not intended to be a currency chatbot. Currency conversion gives the\n\ndemo a small domain with exact arithmetic, a public data source, and answers\n\nthat are easy to compare.\n\nThe coordinator supports three modes:\n\n| Mode | Path |\n|---|---|\n`mcp_only` |\nAgentCore calls the exchange-rate MCP tool |\n`a2a_only` |\nAgentCore delegates to the Foundry agent over A2A |\n`verified` |\nBoth calls run concurrently and deterministic code compares the results |\n\nThe LLM selects and explains the workflow. It does not calculate the\n\nconversion or decide whether two amounts agree. Python `Decimal`\n\ndoes that:\n\n```\ndifference = abs(primary.converted_amount - verifier.converted_amount)\nrelative_difference = difference / abs(primary.converted_amount)\nagreed = relative_difference <= Decimal(\"0.005\")\n```\n\nIf the two sources disagree, the coordinator returns both quotes. It never\n\nasks a model which number looks better.\n\n```\nCLI / test runner\n       |\n       | SigV4\n       v\nAmazon Bedrock AgentCore Runtime, us-east-1\nStrands Agents coordinator, Amazon Nova Micro\n       |\n       +-- MCP stdio\n       |      |\n       |      +-- Frankfurter daily reference rates\n       |\n       +-- AWS Secrets Manager\n       |      |\n       |      +-- Entra service-principal credential\n       |\n       +-- Entra OAuth client-credentials exchange\n       |\n       +-- A2A v1.0 JSON-RPC\n              |\n              v\nMicrosoft Foundry hosted agent, East US 2\nMicrosoft Agent Framework, gpt-5-mini\n       |\n       +-- MCP stdio\n              |\n              +-- Frankfurter daily reference rates\n```\n\nThe two agents use the same rate provider deliberately. This smoke test is\n\nabout transport, authentication, tool use, and cross-framework agreement, not\n\nabout reconciling different market feeds.\n\nYou need:\n\n`azd`\n\n) with the Foundry agent extensionInstall the AgentCore CLI and authenticate:\n\n```\nnpm install -g @aws/agentcore\n\naws sts get-caller-identity\naz login\nazd auth login\n```\n\nThe Azure identity performing the deployment needs `Foundry Project Manager`\n\non the Foundry project. Azure management-plane `Owner`\n\nor `Contributor`\n\nalone\n\ndoes not grant the data-plane `agents/write`\n\naction.\n\nClone the repository and install into the current user's Python environment.\n\nThe related benchmark repositories expose the same console-script names, so\n\ninvoking modules from the intended checkout avoids accidentally running a\n\nsibling clone.\n\n```\ngit clone https://github.com/xbill9/bedrock-foundry-a2a-currency.git\ncd bedrock-foundry-a2a-currency\n\npip3 install --user --break-system-packages -e \".[dev]\"\npip3 install --user --break-system-packages -r requirements.txt\n\nPYTHONPATH=. python3 -m pytest -q\n```\n\nThe July 29 build passed 66 tests. These cover the `Decimal`\n\ndomain logic,\n\nMCP subprocess transport, failure policies, Entra credential parsing, and a\n\nFoundry-shaped authenticated A2A v1.0 server.\n\nTry the three modes with deterministic fixture rates:\n\n```\nPYTHONPATH=. python3 -m coordinator.cli \\\n  100 USD EUR --mode mcp_only\n\nPYTHONPATH=. python3 -m coordinator.cli \\\n  100 USD EUR --mode a2a_only\n\nPYTHONPATH=. python3 -m coordinator.cli \\\n  100 USD EUR --mode verified --transport mcp-stdio --json\n```\n\nFixture results prove orchestration and protocol behavior. They are not\n\nfinancial quotes.\n\nThe repository's deployment script packages the Foundry agent, provisions the\n\nproject and `gpt-5-mini`\n\nmodel deployment, deploys the hosted agent, enables\n\nincoming A2A, and reads back the authenticated v1.0 agent card:\n\n```\n./infra/deploy_foundry_peer.sh\n```\n\nThe script prints an endpoint shaped like:\n\n```\nhttps://<account>.services.ai.azure.com/api/projects/<project>/agents/currency-a2a-agent/endpoint/protocols/a2a\n```\n\nSave it for the next steps:\n\n```\nexport CURRENCY_FOUNDRY_A2A_ENDPOINT=\"https://<account>.services.ai.azure.com/api/projects/<project>/agents/currency-a2a-agent/endpoint/protocols/a2a\"\n```\n\nThe card is not public. Foundry serves it at\n\n`agentCard/v1.0`\n\n, and it requires an Entra bearer token just like the message\n\nendpoint.\n\nBefore involving AWS, test the real Foundry peer from the local coordinator.\n\nThe local path uses your ambient Azure CLI credential:\n\n```\nCURRENCY_RATE_PROVIDER=frankfurter \\\nCURRENCY_FOUNDRY_A2A_ENDPOINT=\"$CURRENCY_FOUNDRY_A2A_ENDPOINT\" \\\nPYTHONPATH=. python3 -m coordinator.cli \\\n  100 USD EUR \\\n  --mode verified \\\n  --transport mcp-stdio \\\n  --a2a-peer foundry \\\n  --timeout-seconds 90 \\\n  --json\n```\n\nExpect `mcp-stdio:frankfurter-live`\n\nas the primary source and\n\n`hosted-foundry-a2a`\n\nas the verifier.\n\nAn AgentCore runtime has an AWS IAM role, but it has no Azure identity.\n\nFoundry does not accept an API key for incoming A2A. The demo uses a dedicated\n\nEntra service principal with `Foundry Agent Consumer`\n\non only the Foundry\n\nproject.\n\nCreate that identity using your organization's normal process, grant the\n\nproject role, and place the client secret in a protected local file. Then run:\n\n```\nexport AZURE_TENANT_ID=\"<tenant-id>\"\nexport AZURE_CLIENT_ID=\"<application-client-id>\"\nexport AZURE_CLIENT_SECRET_FILE=\"/secure/path/to/client-secret\"\nexport CURRENCY_AZURE_SECRET_ID=\"bedrock-foundry-a2a/azure-service-principal\"\n\n./infra/configure_azure_secret.sh\n```\n\nThat script stores a JSON credential in AWS Secrets Manager without putting\n\nthe secret on the command line. It also prints the narrow IAM policy needed\n\nby the generated AgentCore execution role:\n\n```\n{\n  \"Effect\": \"Allow\",\n  \"Action\": \"secretsmanager:GetSecretValue\",\n  \"Resource\": \"<the-one-secret-arn>\"\n}\n```\n\nDo not place the client secret in `agentcore.json`\n\n. Runtime environment\n\nvariables are visible through the control plane.\n\nConfigure the AWS target and deploy once:\n\n```\n./infra/configure_aws_target.sh\n./infra/sync_app.sh\nagentcore deploy -y\nagentcore status\n```\n\nGrant the generated execution role the one-secret policy printed by\n\n`configure_azure_secret.sh`\n\n.\n\nNow point the runtime at Foundry and redeploy:\n\n```\nexport CURRENCY_AZURE_SECRET_ID=\"bedrock-foundry-a2a/azure-service-principal\"\nexport CURRENCY_FOUNDRY_A2A_ENDPOINT=\"https://<account>.services.ai.azure.com/api/projects/<project>/agents/currency-a2a-agent/endpoint/protocols/a2a\"\n\n./infra/point_coordinator_at_foundry.sh\n```\n\nThe script updates the local, account-specific runtime configuration, syncs\n\nthe bundle, deploys it, checks status, and runs a smoke request. Keep the\n\ngenerated endpoint and account configuration out of Git.\n\nRun each hosted mode explicitly:\n\n```\nagentcore invoke \"Convert 100 USD to EUR in mcp_only mode.\"\nagentcore invoke \"Convert 100 USD to EUR in a2a_only mode.\"\nagentcore invoke \"Convert 100 USD to EUR in verified mode.\"\n```\n\nThese are the hosted smoke observations from July 29, 2026. They are not a\n\nlatency distribution and should not be read as a platform benchmark.\n\n| Mode | Observed source | Result | Observed tool latency |\n|---|---|---|---|\n`mcp_only` |\n`mcp-stdio:frankfurter-live` |\nrate `0.87873` , amount `87.87300`\n|\nabout 4.2 s |\n`a2a_only` |\n`hosted-foundry-a2a` |\nrate `0.87873` , amount `87.87300`\n|\nabout 18.8 s |\n`verified` |\nboth sources | zero relative difference, no warnings | MCP about 3.1 s; A2A about 18.1 s |\n\nThe verified path runs both legs concurrently, so its tool time is dominated\n\nby the slower Foundry call rather than the sum of both calls.\n\nThe important result is functional: AWS SigV4 invocation, Bedrock tool use,\n\nMCP stdio, AWS Secrets Manager, an Entra client-credentials exchange, Foundry\n\nagent-card discovery, and A2A v1.0 JSON-RPC all completed in one request.\n\nThe full 38-case AWS-to-Foundry matrix, repeated warm/cold distributions,\n\ntoken use, and cloud cost have not been measured yet.\n\nThe Azure resource deployment succeeded, but hosted-agent creation failed\n\nwith:\n\n```\nIdentity does not have permissions for\nMicrosoft.CognitiveServices/accounts/AIServices/agents/write\n```\n\nAssigning `Foundry Project Manager`\n\nat the project scope fixed it. Azure\n\n`Owner`\n\ndid not imply this Foundry data-plane permission.\n\nThe manifest passed an unset `AZURE_AI_MODEL_DEPLOYMENT_NAME`\n\ntemplate value.\n\nThe container exited with:\n\n```\nValueError: Model is required\n```\n\nThe model deployment is owned by the same manifest, so the fix was to set its\n\nknown deployment name, `gpt-5-mini`\n\n, explicitly.\n\n`aiohttp`\n\n`azure.identity.aio`\n\nuses Azure Core's optional aiohttp transport. The first\n\nhosted invocation failed before token acquisition because `aiohttp`\n\nwas not\n\ndeclared in the CodeZip application's own dependency manifest.\n\nAdding and locking `aiohttp==3.13.3`\n\nin\n\n`app/CurrencyCoordinator/pyproject.toml`\n\nfixed the deployed runtime. Adding it\n\nonly to the repository-root requirements file was not enough; CodeZip resolves\n\nthe application bundle independently.\n\nEach of these interoperability failures now has a regression test or a\n\nmanifest assertion.\n\nFor this small conversion, MCP alone was faster and sufficient. A2A added an\n\nindependently hosted implementation, a separate model and framework, another\n\ntool invocation, and a distinct failure boundary.\n\nIt also added real engineering work:\n\nThat overhead is worthwhile only if independent execution, failover, or\n\ncross-framework portability matters to the application. The demo now gives us\n\na reproducible way to measure that tradeoff instead of treating an HTTP 200 as\n\nproof of interoperability.", "url": "https://wpnews.pro/news/cross-cloud-amazon-bedrock-agentcore-with-microsoft-foundry-over-a2a", "canonical_source": "https://dev.to/aws-builders/can-amazon-bedrock-agentcore-talk-to-microsoft-foundry-over-a2a-241h", "published_at": "2026-07-29 16:52:49+00:00", "updated_at": "2026-07-29 17:05:38.563138+00:00", "lang": "en", "topics": ["artificial-intelligence", "ai-agents", "ai-infrastructure", "ai-tools", "developer-tools"], "entities": ["Amazon Bedrock AgentCore", "Microsoft Foundry", "Microsoft Entra", "Agent-to-Agent (A2A)", "MCP", "Frankfurter", "Amazon Nova Micro", "gpt-5-mini"], "alternates": {"html": "https://wpnews.pro/news/cross-cloud-amazon-bedrock-agentcore-with-microsoft-foundry-over-a2a", "markdown": "https://wpnews.pro/news/cross-cloud-amazon-bedrock-agentcore-with-microsoft-foundry-over-a2a.md", "text": "https://wpnews.pro/news/cross-cloud-amazon-bedrock-agentcore-with-microsoft-foundry-over-a2a.txt", "jsonld": "https://wpnews.pro/news/cross-cloud-amazon-bedrock-agentcore-with-microsoft-foundry-over-a2a.jsonld"}}