Skip to main content
Glama
jamalla

Multi-Agent MCP Server

Multi-Agent MCP Demo

A working demonstration of one MCP server exposing many tools, with multiple LangGraph agents each bound to a filtered subset of those tools, and a supervisor that routes each user question to the right agent, all deployed to the cloud with a browser chat UI.

The core idea: a single MCP server hands over its entire tool catalog to any client. Filtering, deciding which agent sees which tools, happens on the client side, in one line:

agent_tools = [t for t in all_tools if t.name.startswith(prefix)]

πŸ”— Live URLs

⏳ Cold start: both services run on Render's free tier and sleep after ~15 min idle. The first request after a nap can take 30 to 50s to wake the container, then the second is fast. The chat UI shows a "may take ~40s" hint while waiting.

Related MCP server: Open-Meteo MCP Server

Architecture

                        Browser (chat UI)
                                β”‚
                                β–Ό
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚   FastAPI agent service  (Render service #2)    β”‚
        β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
        β”‚   β”‚           LangGraph Supervisor          β”‚  β”‚
        β”‚   β”‚  (LLM router β†’ picks the right agent)    β”‚  β”‚
        β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
        β”‚       β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β” β”Œβ”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β” β”Œβ–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
        β”‚       β”‚  Agent 1    β”‚ β”‚ Agent 2   β”‚ β”‚ Agent 3  β”‚ β”‚
        β”‚       β”‚ weather_*   β”‚ β”‚ country_* β”‚ β”‚worldcup_*β”‚ β”‚
        β”‚       β”‚ (2 tools)   β”‚ β”‚ (5 tools) β”‚ β”‚(5 tools) β”‚ β”‚
        β”‚       β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     filtered subsets of one catalog
                                  β”‚  (streamable-HTTP / MCP)
                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                     β”‚      MCP Server         β”‚  (Render service #1)
                     β”‚   12 tools, unfiltered  β”‚
                     β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”˜
                          β”‚          β”‚         β”‚
                 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β” β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β” β”Œβ”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                 β”‚Open-Meteoβ”‚ β”‚CountriesNowβ”‚ β”‚football-data.orgβ”‚
                 β”‚(weather) β”‚ β”‚ (country)  β”‚ β”‚  (World Cup)    β”‚
                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Two clean separations:

  • The supervisor decides who handles a query (routing).

  • The prefix filter decides what each agent can do (tool scoping).

The tools (12 total)

The naming convention (weather_ / country_ / worldcup_ prefixes) is what makes per-agent filtering a one-liner.

Prefix

Tool

Source API

weather_

weather_geocode

Open-Meteo (geocoding)

weather_

weather_current

Open-Meteo (forecast)

country_

country_capital

CountriesNow

country_

country_currency

CountriesNow

country_

country_population

CountriesNow

country_

country_dial_code

CountriesNow

country_

country_flag

CountriesNow

worldcup_

worldcup_matches_upcoming

football-data.org

worldcup_

worldcup_match_results

football-data.org

worldcup_

worldcup_group_standings

football-data.org

worldcup_

worldcup_teams

football-data.org

worldcup_

worldcup_team_form

football-data.org

Open-Meteo and CountriesNow are free and need no key. football-data.org needs a free API key (FOOTBALL_API_KEY). "Predictions" are the World Cup agent reasoning over standings and recent form it fetches with these tools, not a separate prediction API.

Observability: see the route & tool steps

Every answer returns a structured trace, rendered under each message in the UI (expandable):

🌀️ routed to Agent 1 (weather)   β–Έ Show reasoning (4 steps)
   πŸ”§ weather_geocode({"city":"Tokyo"})
   πŸ“₯ weather_geocode β†’ {"name":"Tokyo","country":"Japan","latitude":35.6895,...}
   πŸ”§ weather_current({"latitude":35.6895,"longitude":139.69171})
   πŸ“₯ weather_current β†’ {"temperature_2m":27.0,"wind_speed_10m":4.5,...}

The /ask endpoint returns:

{
  "answer": "…",
  "route":  { "destination": "weather", "agent": "Agent 1 (weather)" },
  "steps":  [ { "kind": "tool_call", "tool": "...", "args": {...} },
              { "kind": "tool_result", "tool": "...", "output": "..." } ]
}

For deeper tracing (timings, tokens, nested spans), set LANGCHAIN_TRACING_V2=true and LANGCHAIN_API_KEY to enable LangSmith, no code changes required.

Tech stack

  • MCP server: FastMCP over streamable-HTTP

  • Agents / routing: LangGraph (create_react_agent) + LangChain

  • MCP ↔ LangGraph bridge: langchain-mcp-adapters

  • LLM: OpenAI gpt-4o-mini (routing + agents)

  • API / UI: FastAPI (serves both /ask and the chat page)

  • Hosting: Render (two Docker web services, free tier)

Project structure

multi-agent-mcp/
β”œβ”€β”€ mcp_server/
β”‚   └── server.py          # FastMCP server: 7 tools + /health, reads $PORT
β”œβ”€β”€ agents/
β”‚   β”œβ”€β”€ agent_config.py    # MCP client + prefix map (reads MCP_URL from env)
β”‚   β”œβ”€β”€ graph.py           # build_agents(): filter tools β†’ create_react_agent
β”‚   β”œβ”€β”€ supervisor.py      # LLM router + trace extraction
β”‚   └── api.py             # FastAPI: /ask + chat UI
β”œβ”€β”€ Dockerfile.server      # image for the MCP server
β”œβ”€β”€ Dockerfile.agents      # image for the FastAPI agent service
β”œβ”€β”€ docker-compose.yml     # local parity for the MCP server
β”œβ”€β”€ render.yaml            # Render blueprint (MCP server)
β”œβ”€β”€ requirements.txt
└── .env                   # OPENAI_API_KEY (gitignored, never committed)

Run locally

# 1. Install
python -m venv .venv
.venv\Scripts\activate          # Windows  (macOS/Linux: source .venv/bin/activate)
pip install -r requirements.txt fastapi uvicorn

# 2. Configure
#   .env β†’ OPENAI_API_KEY=sk-...

# 3a. Start the MCP server (terminal 1)
python -m mcp_server.server                     # serves http://localhost:8000/mcp

# 3b. Start the agent API + chat UI (terminal 2)
#   defaults MCP_URL to http://localhost:8000/mcp
uvicorn agents.api:app --reload --port 8080     # open http://localhost:8080

Point the agents at a remote MCP server without any code change:

export MCP_URL="https://multi-agent-mcp.onrender.com/mcp"
uvicorn agents.api:app --port 8080

Deploy (Render)

Two Docker web services from this repo.

Service 1: MCP server

  • Dockerfile: Dockerfile.server

  • Health check path: /health

  • Env vars:

    • FOOTBALL_API_KEY = your football-data.org key (needed by the World Cup tools)

Service 2: Agent API + UI

  • Dockerfile: Dockerfile.agents

  • Env vars:

    • OPENAI_API_KEY = your OpenAI key

    • MCP_URL = https://multi-agent-mcp.onrender.com/mcp

Both read $PORT (injected by Render) and bind 0.0.0.0, so no port config is needed. render.yaml describes the MCP server as a blueprint.

Author

Jamalla Zawia - jamala.zawia@gmail.com

F
license - not found
-
quality - not tested
B
maintenance

Maintenance

–Maintainers
–Response time
–Release cycle
–Releases (12mo)
Commit activity

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jamalla/multi-agent-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server