mcp_servers.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. """
  2. An example of running an agency with a local and a public MCP server.
  3. This example connects to the pre-made MCP servers with custom tools
  4. that can be found at examples/utils/stdio_mcp_server.py and examples/utils/sse_mcp_server.py
  5. The public MCP server is running on port 8000 and can be accessed at http://localhost:8000/sse
  6. Additionally, you can set up custom APP_TOKEN in .env file for auth, otherwise the token will be set to "test_token_123".
  7. Run the example with: python examples/mcp_servers.py
  8. It will ask the agent to use tools from both MCP servers and present the results.
  9. To fully test the public MCP server example (copy/paste):
  10. 1) Start ngrok in one terminal:
  11. ngrok http 8000
  12. 2) In another terminal (replace YOUR_NGROK_ID):
  13. MCP_PUBLIC_SERVER_URL="https://YOUR_NGROK_ID.ngrok-free.app/sse" python examples/mcp_servers.py
  14. IF you do not want to run the public MCP server, you can comment out the public_mcp_server_example() call in the main function below.
  15. """
  16. import asyncio
  17. import os
  18. import subprocess
  19. import sys
  20. import time
  21. from agents.mcp.server import MCPServerStdio, MCPServerStdioParams
  22. from dotenv import load_dotenv
  23. from agency_swarm import Agency, Agent, HostedMCPTool
  24. load_dotenv()
  25. _EXAMPLES_DIR = os.path.dirname(os.path.abspath(__file__))
  26. _STDIO_SERVER_PATH = os.path.join(_EXAMPLES_DIR, "utils", "stdio_mcp_server.py")
  27. _SSE_SERVER_PATH = os.path.join(_EXAMPLES_DIR, "utils", "sse_mcp_server.py")
  28. app_token = os.getenv("APP_TOKEN")
  29. if not app_token:
  30. os.environ["APP_TOKEN"] = "test_token_123"
  31. app_token = "test_token_123"
  32. stdio_server = MCPServerStdio(
  33. MCPServerStdioParams(command=sys.executable, args=[_STDIO_SERVER_PATH], env={"APP_TOKEN": app_token}),
  34. cache_tools_list=True,
  35. )
  36. # Launch the SSE MCP server
  37. def launch_sse_server():
  38. """Launch the SSE MCP server in a separate process"""
  39. env = os.environ.copy()
  40. env["APP_TOKEN"] = app_token
  41. process = subprocess.Popen(
  42. [sys.executable, _SSE_SERVER_PATH],
  43. env=env,
  44. )
  45. # Give the server time to start
  46. time.sleep(2)
  47. return process
  48. mcp_agent_local = Agent(
  49. name="local_MCP_Agent",
  50. instructions="You are a helpful assistant",
  51. description="Helpful assistant",
  52. model="gpt-5.4-mini",
  53. mcp_servers=[stdio_server], # <- local mcp server
  54. )
  55. agency_local = Agency(mcp_agent_local)
  56. async def local_mcp_server_example():
  57. # Agent will handle execution lifecycle of the MCP server automatically.
  58. print("Running local MCP server example")
  59. print("-" * 25)
  60. message = "Get unique id and then current time in Europe/Amsterdam"
  61. print(f"Sending message: {message}")
  62. response = await agency_local.get_response(message)
  63. print(f"Answer: {response.final_output}")
  64. print("\nIf you see the time and id in the answer, that means agent used the local MCP server successfully")
  65. print("Local MCP server example completed\n")
  66. print("-" * 25 + "\n")
  67. async def public_mcp_server_example():
  68. # HostedMCPTools do not require manual connection
  69. public_server_url = os.getenv("MCP_PUBLIC_SERVER_URL")
  70. if not public_server_url:
  71. print("MCP_PUBLIC_SERVER_URL is not set; skipping public MCP server example.")
  72. print("Set MCP_PUBLIC_SERVER_URL to your ngrok URL (including /sse) to enable it.")
  73. return
  74. public_server_url = public_server_url.rstrip("/")
  75. public_agent = Agent(
  76. name="public_MCP_Agent",
  77. instructions="You are a helpful assistant",
  78. description="Helpful assistant",
  79. model="gpt-5.4-mini",
  80. tools=[
  81. HostedMCPTool( # <- public mcp server (requires ngrok)
  82. tool_config={
  83. "type": "mcp",
  84. "server_label": "mcp-tools-server",
  85. # server_url must be accessible from the internet (not locally)
  86. "server_url": public_server_url,
  87. "require_approval": "never",
  88. "headers": {"Authorization": f"Bearer {app_token}"},
  89. }
  90. ),
  91. ],
  92. )
  93. agency_public = Agency(public_agent)
  94. print("Running public MCP server example")
  95. print("-" * 25)
  96. sse_server = None
  97. try:
  98. sse_server = launch_sse_server()
  99. await asyncio.sleep(5) # wait for the server to start
  100. response = await agency_public.get_response("Get secret word and then list directory")
  101. print(response.final_output)
  102. except Exception as e:
  103. print(
  104. f"Error using public MCP server: {e}\n Please check the ngrok url and try again.\n"
  105. "If issue persists, try manually starting sse server by running `python examples/utils/sse_mcp_server.py`"
  106. )
  107. return
  108. finally:
  109. if sse_server is not None:
  110. sse_server.terminate()
  111. print(
  112. "\nIf secret word is 'strawberry' and agent presented a list of files from the utils folder,"
  113. " that means the public MCP server worked successfully"
  114. )
  115. print("Public MCP server example completed")
  116. print("-" * 25)
  117. if __name__ == "__main__":
  118. print("MCP Server Example")
  119. print("=" * 50)
  120. asyncio.run(local_mcp_server_example())
  121. asyncio.run(public_mcp_server_example()) # <- comment this out if you want to run local example only