Russell Sakauye

Entrepreneur building with AI agents | PMP | Ex-Shopify PMO | Okotoks, AB

CIW workshop · 4 November 2026

A travel question, answered two ways

One orchestrator plans the trip. Weather stays in the same process. Currency is asked of a second agent, which calls a tool for the rate. Built with Google's open-source Agent Development Kit for a personal workshop.

How a question moves

The travel agent does not fetch rates or weather itself. It hands each part to a specialist. Only the currency specialist leaves the process.

Travel demo architecture The travel agent sends currency questions over A2A to the currency agent, which calls the Frankfurter API through an MCP tool. The same travel agent calls an in-process weather subagent, which calls wttr.in. ORCHESTRATOR Travel agent port 8082 REMOTE AGENT Currency agent port 8081 · agent card TOOL API Frankfurter exchange rates IN-PROCESS Weather subagent same process as travel TOOL API wttr.in current conditions A2A MCP in-process HTTPS Travel demo architecture, branched The travel agent splits in two. Over A2A it calls the currency agent, which calls Frankfurter through MCP. In-process it calls the weather subagent, which calls wttr.in. ORCHESTRATOR · PORT 8082 Travel agent A2A in-process REMOTE · 8081 Currency agent agent card SAME PROCESS Weather subagent MCP HTTPS TOOL API Frankfurter exchange rates TOOL API wttr.in conditions

Labels name the protocol. Colour repeats the same four roles and is not the only cue.

MCP and A2A

They look similar from the orchestrator, because both specialists are wrapped as tools. Underneath, the contracts differ.

Agent to tool

MCP

The currency agent holds an MCP toolset pointed at Streamable HTTP on /mcp. It can list get_exchange_rate and call it. The tool's arguments and the Frankfurter payload are visible to that agent. The travel agent never sees them.

Agent to agent

A2A

The currency agent is served with to_a2a and publishes a card at /.well-known/agent-card.json. The travel agent sends a JSON-RPC message to that agent. Multi-turn state and the MCP tools stay inside the currency service.

Seven steps, verified that day

This is the path that passed on 4 November 2026, written up for the workshop. The longer public codelab covers the same system in more sections. Outputs below are from that recorded run.

  1. Project, billing, and a budget alert

    A fresh cloud project, billing on, and a budget alert (the notes use $10, with mail at 50%, 90%, and 100%) before any deploy. The verified run used under $0.05. The alert is what catches a service left up.

  2. Python 3.13, uv, and a placeholder env file

    Pin 3.13. An unpinned sync can pick 3.15, which breaks beartype inside fastmcp. Copy .env.example: enterprise mode, your-project-id, location global. On a Mac, point the Cloud SDK at Homebrew Python if the system one is 3.9, and turn off the ADK telemetry prompt.

  3. Currency MCP server

    FastMCP on port 8080. Recorded call get_exchange_rate from USD to EUR returned amount 1.0, base USD, date 2026-11-04, EUR rate 0.88755.

  4. Currency agent over A2A

    Port 8081. The card listed skills currency_agent and currency_agent-get_exchange_rate. "how much is 100 USD in GBP?" came back as 100 USD = 74.08 GBP (rate 0.74075).

  5. Travel agent

    Port 8082. Weather is a local subagent. Currency is a remote A2A agent. Both are wrapped the same way. The London question and the recorded answer are in the replay.

  6. Cloud Run, then AGENT_URL

    Deploy the MCP server, then the currency agent. Read the public URL and set AGENT_URL so the card advertises https on port 443. Then deploy the travel agent with that URL. The demo flag --allow-unauthenticated makes each service public.

  7. Delete all three services

    Remove currency-mcp-server, currency-agent, and travel-agent. The verified cleanup listed 0 items. Do this before you stop, even if a later deploy failed.

Recorded London answer

Recorded run from 4 November 2026. Not a live answer.

Asked

I'm planning a trip to London. What is the weather like and how much is 200 EUR in GBP?

Weather

Overcast in London

10°C 50°F

Humidity
63%
Wind
19 km/h

Travel agent, in-process weather subagent, wttr.in

Currency

200 EUR in pounds

166.92 GBP

Rate
0.8346
Pair
EUR to GBP

Travel agent, currency agent over A2A, currency MCP server, Frankfurter

Same day, the MCP probe USD to EUR returned {"amount":1.0,"base":"USD","date":"2026-11-04","rates":{"EUR":0.88755}}.

The currency agent, asked "how much is 100 USD in GBP?", answered 100 USD = 74.08 GBP (rate 0.74075).

What to keep

MCP is the tool port

List tools, call a tool, get a structured result. The currency server is a good first tool because the contract is small and the upstream API is public.

A2A is the agent port

Discovery is the card. The caller does not import the callee's tools. That is why the currency agent can move to its own service without the travel agent changing shape.

Start in-process

The weather helper is the same kind of tool wrapper as the remote currency agent. Promote a helper to A2A when it crosses a service, a repo, or a language.

The card must name a public URL

On Cloud Run, deploy first, read the service URL, then set AGENT_URL. A card that still says localhost cannot be called from the travel service.

Run it yourself

From apps/ciw-adk-travel-agent. The README next to this site has Mac gotchas, the Cloud Run order, the AGENT_URL update, and the mandatory delete of all three public services. Nothing on this page is hosted.

uv sync --group dev
uv run python currency_mcp_server/server.py
uv run python currency_agent/agent.py
uv run python travel_agent/agent.py

Three terminals, in that order. Then open http://localhost:8082. Offline tests, with the network mocked, are uv run pytest.

Optional local call

Off by default. Turning this on does not call anything until you send. If port 8082 is quiet, the page says so and stays on the recorded answer.