1"use strict";(self.webpackChunkinnovation_labs=self.webpackChunkinnovation_labs||[]).push([[1377],{89090:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"examples/mcp-integration/multi-server-agent-example","title":"Multi-Server MCP LangGraph Agent","description":"This guide demonstrates two approaches for building LangGraph agents that connect to multiple MCP servers, then wrap them as uAgents and register them on Agentverse for discovery and use by ASI:One.","source":"@site/docs/examples/mcp-integration/multi-server-agent-example.md","sourceDirName":"examples/mcp-integration","slug":"/examples/mcp-integration/multi-server-agent-example","permalink":"/resources/docs/next/examples/mcp-integration/multi-server-agent-example","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"id":"multi-server-agent-example","title":"Multi-Server MCP LangGraph Agent"},"sidebar":"tutorialSidebar","previous":{"title":"LangGraph Agent with MCP Tools","permalink":"/resources/docs/next/examples/mcp-integration/langgraph-mcp-agent-example"},"next":{"title":"Connect an Agent to Multiple Remote MCP Servers","permalink":"/resources/docs/next/examples/mcp-integration/connect-an-agent-to-multiple-remote-mcp-servers"}}');var a=t(74848),s=t(28453);const i={id:"multi-server-agent-example",title:"Multi-Server MCP LangGraph Agent"},o="Multi-Server MCP LangGraph Agent",l={},c=[{value:"Overview",id:"overview",level:2},{value:"Transport Methods",id:"transport-methods",level:2},{value:"Common Server Setup",id:"common-server-setup",level:2},{value:"1. Create the Math MCP Server",id:"1-create-the-math-mcp-server",level:3},{value:"2. Create the Weather MCP Server",id:"2-create-the-weather-mcp-server",level:3},{value:"Approach 1: Basic Multi-Server Agent",id:"approach-1-basic-multi-server-agent",level:2},{value:"Create and Register the Basic Multi-Server Agent",id:"create-and-register-the-basic-multi-server-agent",level:3},{value:"Approach 2: Advanced State Graph Agent",id:"approach-2-advanced-state-graph-agent",level:2},{value:"Create and Register the Multi-Server Graph Agent",id:"create-and-register-the-multi-server-graph-agent",level:3},{value:"Key Differences Between the Two Approaches",id:"key-differences-between-the-two-approaches",level:2},{value:"Getting Started",id:"getting-started",level:2},{value:"Sample success logs",id:"sample-success-logs",level:3},{value:"When to Use Each Approach",id:"when-to-use-each-approach",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"multi-server-mcp-langgraph-agent",children:"Multi-Server MCP LangGraph Agent"})}),"\n",(0,a.jsxs)(n.p,{children:["This guide demonstrates two approaches for building LangGraph agents that connect to multiple MCP servers, then wrap them as uAgents and register them on ",(0,a.jsx)(n.a,{href:"/docs/agentverse",children:"Agentverse"})," for discovery and use by ASI",":One","."]}),"\n",(0,a.jsxs)(n.p,{children:["If you are new to MCP + LangGraph, start with the simpler single-server guide: ",(0,a.jsx)(n.a,{href:"langgraph-mcp-agent-example",children:"LangGraph Agent with MCP adapter"}),"."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Roles in this demo:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsxs)(n.strong,{children:["OpenAI ",(0,a.jsx)(n.code,{children:"gpt-4o"})]})," is the agent brain (tool selection and reasoning)."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsxs)(n.strong,{children:["ASI",":One"," / Agentverse"]})," is how users discover and chat with the registered uAgent."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Weather tools are mock"})," \u2014 ",(0,a.jsx)(n.code,{children:"get_weather"})," returns a fixed sunny reply, not live forecast data."]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,a.jsx)(n.p,{children:"Both examples in this guide:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Connect to multiple MCP servers (math and weather) using ",(0,a.jsx)(n.code,{children:"langchain_mcp_adapters.MultiServerMCPClient"})]}),"\n",(0,a.jsxs)(n.li,{children:["Use ",(0,a.jsx)(n.strong,{children:"stdio"})," for the local math server and ",(0,a.jsx)(n.strong,{children:"streamable HTTP"})," for the weather server (preferred over deprecated SSE)"]}),"\n",(0,a.jsxs)(n.li,{children:["Wrap the LangGraph agent using ",(0,a.jsx)(n.code,{children:"uagents_adapter"})," to become a uAgent"]}),"\n",(0,a.jsxs)(n.li,{children:["Register the uAgent on Agentverse, making it discoverable and callable by ASI",":One"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"The key difference is in the agent ar
1chitecture:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Basic Multi-Server Agent"}),": Uses LangGraph's ",(0,a.jsx)(n.code,{children:"create_react_agent"})," (ReAct auto tool-loop)"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Advanced State Graph Agent"}),": Uses an explicit ",(0,a.jsx)(n.code,{children:"StateGraph"})," with ",(0,a.jsx)(n.code,{children:"call_model"})," \u2194 ",(0,a.jsx)(n.code,{children:"ToolNode"})," edges"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"transport-methods",children:"Transport Methods"}),"\n",(0,a.jsx)(n.p,{children:"In both examples, we use two different transport methods for the MCP servers:"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"stdio transport (math server)"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Used for local MCP servers that run as subprocesses"}),"\n",(0,a.jsx)(n.li,{children:"Communication happens through standard input/output"}),"\n",(0,a.jsx)(n.li,{children:"Good for local development and testing"}),"\n",(0,a.jsxs)(n.li,{children:["Example: ",(0,a.jsx)(n.code,{children:'mcp.run(transport="stdio")'})]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"HTTP / streamable HTTP transport (weather server)"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["FastMCP serves streamable HTTP with ",(0,a.jsx)(n.code,{children:'mcp.run(transport="streamable-http")'})," (default path ",(0,a.jsx)(n.code,{children:"/mcp"}),", port ",(0,a.jsx)(n.code,{children:"8000"}),")"]}),"\n",(0,a.jsxs)(n.li,{children:["Clients use ",(0,a.jsx)(n.code,{children:'transport: "http"'})," and URLs like ",(0,a.jsx)(n.code,{children:"http://localhost:8000/mcp"})," (langchain-mcp-adapters)"]}),"\n",(0,a.jsxs)(n.li,{children:["SSE (",(0,a.jsx)(n.code,{children:'transport: "sse"'}),", ",(0,a.jsx)(n.code,{children:"/sse"}),") is deprecated in current LangChain MCP docs; prefer HTTP unless you intentionally pin an older SSE-first stack"]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"MultiServerMCPClient"})," handles both transport types. Construct the client plainly, then call ",(0,a.jsx)(n.code,{children:"tools = await client.get_tools()"})," (do not use ",(0,a.jsx)(n.code,{children:"async with MultiServerMCPClient(...)"}),")."]}),"\n",(0,a.jsx)(n.h2,{id:"common-server-setup",children:"Common Server Setup"}),"\n",(0,a.jsx)(n.p,{children:"Both examples use the same MCP servers. Set those up first."}),"\n",(0,a.jsx)(n.h3,{id:"1-create-the-math-mcp-server",children:"1. Create the Math MCP Server"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-python",metastring:'title="math_server.py"',children:'from mcp.server.fastmcp import FastMCP\n\nmcp = FastMCP("Math")\n\n\[email protected]()\ndef add(a: int, b: int) -> int:\n """Add two numbers"""\n return a + b\n\n\[email protected]()\ndef multiply(a: int, b: int) -> int:\n """Multiply two numbers"""\n return a * b\n\n\nif __name__ == "__main__":\n mcp.run(transport="stdio")\n'})}),"\n",(0,a.jsx)(n.h3,{id:"2-create-the-weather-mcp-server",children:"2. Create the Weather MCP Server"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-python",metastring:'title="weather_server.py"',children:'from mcp.server.fastmcp import FastMCP\n\nmcp = FastMCP("Weather", port=8000)\n\n\[email protected]()\ndef get_weather(city: str) -> str:\n """Get the current weather for a city"""\n # Mock implementation \u2014 not a live weather API\n return f"The weather in {city} is sunny and 25\xb0C"\n\n\nif __name__ == "__main__":\n mcp.run(transport="streamable-http")\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Prerequisite:"})," Start the weather server before either agent. Multi-server ",(0,a.jsx)(n.code,{children:"get_tools()"})," can fail or return an incomplete tool set if weather is down."]}),"\n",(0,a.jsx)(n.h2,{id:"approach-1-basic-multi-server-agent",children:"Approach 1: Basic Multi-Server Agent"}),"\n",(0,a.jsxs)(n.p,{children:["This approach uses LangGraph's ",(0,a.jsx)(n.code,{children:"create_react_agent"})," to create a simple agent that can access tools from multiple MCP servers."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Before you run:"})," Start ",(0,a.jsx)(n.code,{children:"weather_server.py"})," in another terminal first. Do not run the basic and graph agents at the same time \u2014 both bind port ",(0,a.jsx)(n.strong,{children:"8080"}),"."]}),"\n",(0,a.jsx)("div",{style:{textAlign:"center"},children:(0,a.jsx)("img",{src:"/resources/img/mcp-integration/mcp-multiple-1.png",alt:"mcp-multiple-1",style:{width:"100%",maxWidth:"650px"}})}),"\n",(0,a.jsx)(n.h3,{id:"create-and-register-the-basic-multi-server-agent",children:"Create and Register the Basic Multi-Server Agent"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-python",metastring:'title="basic_agent.py"',children:'import asyncio\nimport os\nimport sys\nfrom pathlib import Path\n\nfrom dotenv import load_dotenv\nfrom langchain_core.messages import HumanMessage\nfrom langchain_mcp_adapters.client import MultiServerMCPClient\nfrom langchain_openai import ChatOpenAI\nfrom langgraph.prebuilt import
1create_react_agent\nfrom uagents_adapter import LangchainRegisterTool, cleanup_uagent\nfrom uagents_adapter.langchain import AgentManager\n\nload_dotenv()\n\nOPENAI_API_KEY = os.getenv("OPENAI_API_KEY")\nAPI_TOKEN = os.getenv("AGENTVERSE_API_KEY")\n\nmodel = ChatOpenAI(model="gpt-4o")\n\nAGENT_NAME = "multi_server_agent_math_langchain_mcp"\nMATH_SERVER = str(Path(__file__).resolve().parent / "math_server.py")\n\nagent = None\nagent_ready = asyncio.Event()\n\n\nasync def setup_multi_server_agent():\n global agent\n\n print("Setting up multi-server agent...")\n print("Prerequisite: weather_server.py must already be running on port 8000.")\n try:\n client = MultiServerMCPClient(\n {\n "math": {\n "command": sys.executable,\n "args": [MATH_SERVER],\n "transport": "stdio",\n },\n "weather": {\n "url": "http://localhost:8000/mcp",\n "transport": "http",\n },\n }\n )\n\n tools = await client.get_tools()\n print(f"Connected servers: math (stdio), weather (http)")\n print(f"Successfully loaded {len(tools)} tools: {[t.name for t in tools]}")\n\n agent = create_react_agent(model, tools)\n\n print("Testing math capabilities...")\n math_response = await agent.ainvoke(\n {"messages": [HumanMessage(content="what\'s (3 + 5) x 12?")]}\n )\n print(f"Math test response: {math_response[\'messages\'][-1].content}")\n\n print("Testing weather capabilities...")\n weather_response = await agent.ainvoke(\n {"messages": [HumanMessage(content="what\'s the weather in NYC?")]}\n )\n print(f"Weather test response: {weather_response[\'messages\'][-1].content}")\n\n agent_ready.set()\n\n while True:\n await asyncio.sleep(1)\n except Exception as e:\n print(f"Error setting up agent: {e}")\n print(\n "Leaving agent_ready unset so chat requests time out with a clear error "\n "instead of soft-failing forever. Fix the setup error and restart."\n )\n raise\n\n\ndef main():\n manager = AgentManager()\n\n async def agent_func(x):\n try:\n await asyncio.wait_for(agent_ready.wait(), timeout=60)\n except asyncio.TimeoutError:\n return "Error: Agent setup timed out. Check weather server and logs, then restart."\n\n if agent is None:\n return "Error: Agent not initialized properly. Please try again later."\n\n response = await agent.ainvoke({"messages": [HumanMessage(content=x)]})\n return response["messages"][-1].content\n\n agent_wrapper = manager.create_agent_wrapper(agent_func)\n manager.start_agent(setup_multi_server_agent)\n\n print("Registering multi-server agent...")\n tool = LangchainRegisterTool()\n agent_info = tool.invoke(\n {\n "agent_obj": agent_wrapper,\n "name": AGENT_NAME,\n "port": 8080,\n "description": "A multi-service agent that can handle math calculations and weather queries",\n "api_token": API_TOKEN,\n "mailbox": True,\n }\n )\n\n print(f"\u2705 Registered multi-server agent: {agent_info}")\n\n try:\n manager.run_forever()\n except KeyboardInterrupt:\n print("\ud83d\uded1 Shutting down...")\n cleanup_uagent(AGENT_NAME)\n print("\u2705 Agent stopped.")\n\n\nif __name__ == "__main__":\n main()\n'})}),"\n",(0,a.jsx)(n.h2,{id:"approach-2-advanced-state-graph-agent",children:"Approach 2: Advanced State Graph Agent"}),"\n",(0,a.jsxs)(n.p,{children:["This approach uses LangGraph's ",(0,a.jsx)(n.code,{children:"StateGraph"})," to create a more sophisticated agent with explicit state management and conditional workflow branching."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Before you run:"})," Start ",(0,a.jsx)(n.code,{children:"weather_server.py"})," in another terminal first. Do not run this agent at the same time as the basic agent \u2014 both use port ",(0,a.jsx)(n.strong,{children:"8080"}),"."]}),"\n",(0,a.jsx)("div",{style:{textAlign:"center"},children:(0,a.jsx)("img",{src:"/resources/img/mcp-integration/mcp-multiple-2.png",alt:"mcp-multiple-2",style:{width:"100%",maxWidth:"650px"}})}),"\n",(0,a.jsx)(n.h3,{id:"create-and-register-the-multi-server-graph-agent",children:"Create and Register the Multi-Server Graph Agent"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-python",metastring:'title="graph_agent.py"',children:'import asyncio\nimport os\nimport sys\nfrom pathlib import Path\n\nfrom dotenv import load_dotenv\nfrom langchain_core.messages import HumanMessage\nfrom langchain_mcp_adapters.client import MultiServerMCPClient\nfrom langchain_openai import ChatOpenAI\nfrom langgraph.graph import START, MessagesState, StateGraph\nfrom langgraph.prebuilt import ToolNode, tools_condition\nfrom uagents_adapter import LangchainRegisterTool, cleanup_uagent\nfrom uagents_adapter.langchain import AgentManager\n\nload_dotenv()\n\nOPENAI_API_KEY = os.getenv("OPENAI_API_KEY")\nAPI_TOKEN = os.getenv("AGENTVERSE_API_KEY")\n\nmodel = ChatOpenAI(model="gpt-4o")\n\nAGENT_NAME = "multi_server_graph_agent_math_langchain_mcp"\nMATH_SERVER = str(Path(__file__).resolve().parent / "math_server.py")\n\n_global_graph = None\ngraph_ready = asyncio.Event()\n\n\nasync def setup_multi_server_graph_agent():\n global _global_graph\n\n print("Setting up multi-server graph agent...")\n print("Prerequisite: weather_server.py must already be running on port 8000.")\n try:\n client = MultiServerMCPClient(\n {\n "math": {\n "command": sys.executable,\n "args": [MATH_SERVER],\n "transport": "stdio",\n },\n "weather": {\n "url": "http://localhost:8000/mcp",\n "transport": "http",\n },\n }\n )\n\n tools = await client.get_tools()\n print(f"Connected servers: math (stdio), weather (http)")\n print(f"Successfully loaded {len(tools)} tools: {[t.name for t in tools]}")\n\n def call_model(state: MessagesState):\n response = model.bind_tools(tools).invoke(state["messages"])\n return {"messages": response}\n\n builder = StateGraph(MessagesState)\n builder.add_node(call_model)\n builder.add_node(ToolNode(tools))\n builder.add_edge(START, "call_model")\n builder.add_conditional_edges("call_model", tools_condition)\n builder.add_edge("tools", "call_model")\n _global_graph = builder.compile()\n print("Graph successfully compiled")\n\n try:\n print("Testing math capabilities...")\n math_response = await _global_graph.ainvoke(\n {"messages": [HumanMessage(content="what\'s (3 + 5) x 12?")]}\n )\n print(f"Math test response: {math_response[\'messages\'][-1].content}")\n\n print("Testing weather capabilities...")\n weather_response = await _global_graph.ainvoke(\n {"messages": [HumanMessage(content="what\'s the weather in NYC?")]}\n )\n print(f"Weather test response: {weather_response[\'messages\'][-1].content}")\n except Exception as e:\n print(f"Error during testing: {e}")\n\n graph_ready.set()\n\n while True:\n await asyncio.sleep(1)\n except Exception as e:\n print(f"Error setting up graph: {e}")\n print(\n "Leaving graph_ready unset so chat requests time out with a clear error "\n "instead of soft-failing forever. Fix the setup error and restart."\n )\n raise\n\n\ndef main():\n print("Initializing agent...")\n manager = AgentManager()\n\n async def graph_func(x):\n try:\n await asyncio.wait_for(graph_ready.wait(), timeout=60)\n except asyncio.TimeoutError:\n return "
1Error: Graph setup timed out. Check weather server and logs, then restart."\n\n if _global_graph is None:\n error_msg = "Error: Graph not initialized properly. Please try again later."\n print(f"Response: {error_msg}")\n return error_msg\n\n try:\n print(f"\\nReceived query: {x}")\n messages = [HumanMessage(content=x)] if isinstance(x, str) else x\n response = await _global_graph.ainvoke({"messages": messages})\n result = response["messages"][-1].content\n print(f"\\n\u2705 Response: {result}\\n")\n return result\n except Exception as e:\n error_msg = f"Error processing request: {str(e)}"\n print(f"\\n\u274c {error_msg}\\n")\n return error_msg\n\n agent_wrapper = manager.create_agent_wrapper(graph_func)\n manager.start_agent(setup_multi_server_graph_agent)\n\n print("Registering multi-server graph agent...")\n tool = LangchainRegisterTool()\n try:\n agent_info = tool.invoke(\n {\n "agent_obj": agent_wrapper,\n "name": AGENT_NAME,\n "port": 8080,\n "description": "A multi-service graph agent that can handle math calculations and weather queries",\n "api_token": API_TOKEN,\n "mailbox": True,\n }\n )\n print(f"\u2705 Registered multi-server graph agent: {agent_info}")\n except Exception as e:\n print(f"\u26a0\ufe0f Error registering agent: {e}")\n print("Continuing with local agent only...")\n\n try:\n manager.run_forever()\n except KeyboardInterrupt:\n print("\ud83d\uded1 Shutting down...")\n cleanup_uagent(AGENT_NAME)\n print("\u2705 Agent stopped.")\n\n\nif __name__ == "__main__":\n main()\n'})}),"\n",(0,a.jsx)(n.h2,{id:"key-differences-between-the-two-approaches",children:"Key Differences Between the Two Approaches"}),"\n",(0,a.jsxs)(n.p,{children:["In short: the basic agent relies on ReAct\u2019s automatic tool loop via ",(0,a.jsx)(n.code,{children:"create_react_agent"}),", while the graph agent wires an explicit ",(0,a.jsx)(n.code,{children:"call_model"})," \u2194 ",(0,a.jsx)(n.code,{children:"ToolNode"})," cycle with conditional edges."]}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Architecture"})," \u2014 Basic uses ",(0,a.jsx)(n.code,{children:"create_react_agent"})," (ReAct-style). Graph uses ",(0,a.jsx)(n.code,{children:"StateGraph"})," for explicit workflow control."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Control flow"})," \u2014 Basic: managed internally by ReAct. Graph: nodes, edges, and ",(0,a.jsx)(n.code,{children:"tools_condition"})," branching you define."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"State management"})," \u2014 Basic: implicit inside the ReAct agent. Graph: explicit ",(0,a.jsx)(n.code,{children:"MessagesState"})," you can inspect and extend."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Extensibility"})," \u2014 Basic: quicker setup, less flexible. Graph: more boilerplate, better for multi-step specialized workflows."]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"getting-started",children:"Getting Started"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Get your Agentverse API key"})," \u2014 Follow the ",(0,a.jsx)(n.a,{href:"/docs/agentverse/agentverse-api-key",children:"Agentverse API Key guide"})," and store the key securely (treat it like a password; rotate it from the Agentverse dashboard if it is exposed)."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Set up environment variables"})," in a ",(0,a.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-text",children:"OPENAI_API_KEY=your_openai_api_key\nAGENTVERSE_API_KEY=your_agentverse_api_key\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Install dependencies"})," (include ",(0,a.jsx)(n.code,{children:"langgraph"}),"; pin or match a tested set):"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'pip install \\\n "langchain-openai>=1.0.0,<2" \\\n "langgraph>=0.3.0,<2" \\\n "mcp>=1.9.0,<2" \\\n "langchain-mcp-adapters>=0.1.0,<0.4" \\\n "uagents-adapter>=0.6.2" \\\n "python-dotenv>=1.0.0"\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Tested with:"})," Python 3.10\u20133.12, ",(0,a.jsx)(n.code,{children:"langgraph"}
1)," 0.3+/1.x (",(0,a.jsx)(n.code,{children:"create_react_agent"})," from ",(0,a.jsx)(n.code,{children:"langgraph.prebuilt"}),"), ",(0,a.jsx)(n.code,{children:"langchain-mcp-adapters"})," 0.1.x\u20130.3.x (",(0,a.jsx)(n.code,{children:"await client.get_tools()"}),", HTTP weather transport), ",(0,a.jsx)(n.code,{children:"uagents-adapter"})," 0.6.x. Same stack shape as ",(0,a.jsx)(n.a,{href:"langgraph-mcp-agent-example",children:"LangGraph Agent with MCP adapter"}),", plus multi-server HTTP."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Create the files"})," \u2014 Save ",(0,a.jsx)(n.code,{children:"math_server.py"}),", ",(0,a.jsx)(n.code,{children:"weather_server.py"}),", and either ",(0,a.jsx)(n.code,{children:"basic_agent.py"})," or ",(0,a.jsx)(n.code,{children:"graph_agent.py"})," in the same directory."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Start the weather server, then one agent"})," (not both agents at once \u2014 port ",(0,a.jsx)(n.strong,{children:"8080"})," collision):"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"# Terminal 1: weather MCP server (required first)\npython weather_server.py\n\n# Terminal 2: basic agent OR graph agent (pick one)\npython basic_agent.py\n# python graph_agent.py\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Do ",(0,a.jsx)(n.strong,{children:"not"})," run ",(0,a.jsx)(n.code,{children:"basic_agent.py"})," and ",(0,a.jsx)(n.code,{children:"graph_agent.py"})," simultaneously; both listen on port 8080."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Test your agent"})," from the Agentverse chat UI."]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Open your Agentverse account and go to ",(0,a.jsx)(n.a,{href:"https://agentverse.ai/agents/local",children:"local agents"}),"."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)("div",{style:{textAlign:"center"},children:(0,a.jsx)("img",{src:"/resources/img/mcp-integration/multi-server-1.png",alt:"multi-server-1",style:{width:"100%",maxWidth:"1000px"}})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Click your agent and use ",(0,a.jsx)(n.strong,{children:"Chat with Agent"})," on the Agentverse agent page."]}),"\n"]}),"\n",(0,a.jsx)("div",{style:{textAlign:"center"},children:(0,a.jsx)("img",{src:"/resources/img/mcp-integration/multi-server-2.png",alt:"multi-server-2",style:{width:"100%",maxWidth:"1000px"}})}),"\n",(0,a.jsx)("div",{style:{textAlign:"center"},children:(0,a.jsx)("img",{src:"/resources/img/mcp-integration/multi-server-3.png",alt:"multi-server-3",style:{width:"100%",maxWidth:"1000px"}})}),"\n",(0,a.jsx)(n.h3,{id:"sample-success-logs",children:"Sample success logs"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Terminal 1 \u2014 weather server up:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-text",children:"INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Terminal 2 \u2014 basic agent (graph agent looks similar):"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-text",children:"Setting up multi-server agent...\nPrerequisite: weather_server.py must already be running on port 8000.\nConnected servers: math (stdio), weather (http)\nSuccessfully loaded 3 tools: ['add', 'multiply', 'get_weather']\nTesting math capabilities...\nMath test response: (3 + 5) \xd7 12 = 96\nTesting weather capabilities...\nWeather test response: The weather in NYC is sunny and 25\xb0C\nRegistering multi-server agent...\n\u2705 Registered multi-server agent: Created uAgent 'multi_server_agent_math_langchain_mcp' ...\nINFO: [multi_server_agent_math_langchain_mcp]: Starting mailbox client for https://agentverse.ai\n"})}),"\n",(0,a.jsx)(n.h2,{id:"when-to-use-each-approach",children:"When to Use Each Approach"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Use the Basic Agent when:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"You need a simple agent that can access multiple tools"}),"\n",(0,a.jsx)(n.li,{children:"You want a quick setup with minimal boilerplate"}),"\n",(0,a.jsx)(n.li,{children:"The agent's decision-making process is relatively straightforward"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Use the Graph Agent when:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"You need more control over the agent's workflow"}),"\n",(0,a.jsx)(n.li,{children:"You want explicit state management"}),"\n",(0,a.jsx)(n.li,{children:"You need complex conditional branching in your agent's behavior"}),"\n",(0,a.jsx)(n.li,{children:"You're building an agent with multiple specialized steps or phases"}),"\n"]}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsx)(n.p,{children:"These examples show how to connect to multiple MCP servers with stdio + HTTP transports and two LangGraph architectures. Extend the same patterns to more servers or richer graphs as needed."})})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>o});var r=t(96540);const a={},s=r.createContext(a);function i(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.