From f0055abe7ab00152716b3f30cac08228be2012b9 Mon Sep 17 00:00:00 2001 From: Kye Gomez Date: Thu, 11 Sep 2025 12:14:05 -0700 Subject: [PATCH] [Multi-MCP Examples] [Docs for multi mcp] [FIX][MCP client migration to streamable http instead of sse] [cleanup][examples] --- docs/examples/gold_etf_research.md | 53 +++ docs/examples/marketing_team.md | 372 ++++++++++++++++++ docs/mkdocs.yml | 9 +- docs/swarms/examples/multi_mcp_agent.md | 364 +++++++++++++++++ .../multiagent_client.py | 0 .../singleagent_client.py | 0 examples/mcp/multi_mcp_example.py | 191 +++++++++ .../agent_mcp.py | 10 +- .../mcp_agent_tool.py | 0 .../mcp/multi_mcp_guide/okx_crypto_server.py | 120 ++++++ examples/mcp/servers/mcp_agent_tool.py | 35 ++ examples/mcp/utils.py | 4 + swarms/structs/batched_grid_workflow.py | 66 +++- swarms/structs/transforms.py | 2 +- swarms/tools/mcp_client_tools.py | 45 +-- swarms/utils/litellm_wrapper.py | 49 ++- 16 files changed, 1261 insertions(+), 59 deletions(-) create mode 100644 docs/examples/gold_etf_research.md create mode 100644 docs/examples/marketing_team.md create mode 100644 docs/swarms/examples/multi_mcp_agent.md rename examples/mcp/{deploy_mcp_server => mcp_utils}/multiagent_client.py (100%) rename examples/mcp/{deploy_mcp_server => mcp_utils}/singleagent_client.py (100%) create mode 100644 examples/mcp/multi_mcp_example.py rename examples/mcp/{agent_examples => multi_mcp_guide}/agent_mcp.py (63%) rename examples/mcp/{deploy_mcp_server => multi_mcp_guide}/mcp_agent_tool.py (100%) create mode 100644 examples/mcp/multi_mcp_guide/okx_crypto_server.py create mode 100644 examples/mcp/servers/mcp_agent_tool.py create mode 100644 examples/mcp/utils.py diff --git a/docs/examples/gold_etf_research.md b/docs/examples/gold_etf_research.md new file mode 100644 index 00000000..65419393 --- /dev/null +++ b/docs/examples/gold_etf_research.md @@ -0,0 +1,53 @@ +# Gold ETF Research with HeavySwarm + +This example demonstrates how to use HeavySwarm to create a specialized research team that analyzes and compares gold ETFs using web search capabilities. The HeavySwarm orchestrates multiple agents to conduct comprehensive research and provide structured investment recommendations. + +## Install + +```bash +pip3 install -U swarms swarms-tools +``` + +## Environment Setup + +```bash +EXA_API_KEY="your_exa_api_key_here" +OPENAI_API_KEY="your_openai_api_key_here" +ANTHROPIC_API_KEY="your_anthropic_api_key_here" +``` + +## Code + +```python +from swarms import HeavySwarm +from swarms_tools import exa_search + +# Initialize the HeavySwarm for gold ETF research +swarm = HeavySwarm( + name="Gold ETF Research Team", + description="A team of agents that research the best gold ETFs", + worker_model_name="claude-sonnet-4-20250514", + show_dashboard=True, + question_agent_model_name="gpt-4.1", + loops_per_agent=1, + agent_prints_on=False, + worker_tools=[exa_search], + random_loops_per_agent=True, +) + +# Define the research task +prompt = ( + "Find the best 3 gold ETFs. For each ETF, provide the ticker symbol, " + "full name, current price, expense ratio, assets under management, and " + "a brief explanation of why it is considered among the best. Present the information " + "in a clear, structured format suitable for investors. Scrape the data from the web. " +) + +# Execute the research +out = swarm.run(prompt) +print(out) +``` + +## Conclusion + +This example demonstrates how HeavySwarm can be used to create specialized research teams for financial analysis. By leveraging multiple agents with web search capabilities, you can build powerful systems that provide comprehensive, real-time investment research and recommendations. The pattern can be easily adapted for various financial research tasks including stock analysis, sector research, and portfolio optimization. diff --git a/docs/examples/marketing_team.md b/docs/examples/marketing_team.md new file mode 100644 index 00000000..524e961c --- /dev/null +++ b/docs/examples/marketing_team.md @@ -0,0 +1,372 @@ +# Hierarchical Marketing Swarm + +This example demonstrates how to create a hierarchical marketing team using Swarms, where specialized agents work under the coordination of a marketing director. The team includes a Head of Content, Ad Creative Director, SEO Strategist, and Brand Strategist, all orchestrated by a Marketing Director to tackle complex marketing challenges with comprehensive expertise. + +## Install + + +```bash +pip3 install -U swarms +``` + + +## Usage + +``` +ANTHROPIC_API_KEY="" +OPENAI_API_KEY="" +``` + + +## Code + +```python +from swarms import Agent +from swarms.structs.hiearchical_swarm import HierarchicalSwarm + +# ============================================================================= +# HEAD OF CONTENT AGENT +# ============================================================================= +head_of_content_agent = Agent( + agent_name="Head-of-Content", + agent_description="Senior content strategist responsible for content planning, creation, and editorial direction", + system_prompt="""You are the Head of Content for a dynamic marketing organization. You are responsible for: + + CONTENT STRATEGY & PLANNING: + - Developing comprehensive content strategies aligned with business objectives + - Creating editorial calendars and content roadmaps + - Identifying content gaps and opportunities across all channels + - Establishing content themes, messaging frameworks, and voice guidelines + - Planning content distribution strategies and channel optimization + + CONTENT CREATION & MANAGEMENT: + - Overseeing the creation of high-quality, engaging content across all formats + - Developing compelling narratives, storylines, and messaging hierarchies + - Ensuring content consistency, quality standards, and brand voice adherence + - Managing content workflows, approvals, and publishing schedules + - Creating content that drives engagement, conversions, and brand awareness + + EDITORIAL EXCELLENCE: + - Maintaining editorial standards and content quality across all touchpoints + - Developing content guidelines, style guides, and best practices + - Ensuring content is SEO-optimized, accessible, and user-friendly + - Creating content that resonates with target audiences and drives action + - Measuring content performance and optimizing based on data insights + + CROSS-FUNCTIONAL COLLABORATION: + - Working closely with SEO, creative, and brand teams to ensure content alignment + - Coordinating with marketing teams to support campaign objectives + - Ensuring content supports overall business goals and customer journey + - Providing content recommendations that drive measurable business outcomes + + Your expertise includes: + - Content marketing strategy and execution + - Editorial planning and content calendar management + - Storytelling and narrative development + - Content performance analysis and optimization + - Multi-channel content distribution + - Brand voice and messaging development + - Content ROI measurement and reporting + + You deliver strategic, data-driven content recommendations that drive engagement, conversions, and brand growth.""", + model_name="claude-3-sonnet-20240229", + max_loops=1, + temperature=0.7, + dynamic_temperature_enabled=True, + streaming_on=True, + print_on=True, +) + +# ============================================================================= +# AD CREATIVE DIRECTOR AGENT +# ============================================================================= +ad_creative_director_agent = Agent( + agent_name="Ad-Creative-Director", + agent_description="Creative visionary responsible for ad concept development, visual direction, and campaign creativity", + system_prompt="""You are the Ad Creative Director, the creative visionary responsible for developing compelling advertising concepts and campaigns. Your role encompasses: + + CREATIVE CONCEPT DEVELOPMENT: + - Creating breakthrough advertising concepts that capture attention and drive action + - Developing creative briefs, campaign concepts, and visual directions + - Crafting compelling headlines, copy, and messaging that resonate with audiences + - Designing creative strategies that differentiate brands and drive engagement + - Creating memorable, shareable content that builds brand awareness + + VISUAL DIRECTION & DESIGN: + - Establishing visual identity guidelines and creative standards + - Directing photography, videography, and graphic design elements + - Creating mood boards, style guides, and visual concepts + - Ensuring creative consistency across all advertising touchpoints + - Developing innovative visual approaches that stand out in crowded markets + + CAMPAIGN CREATIVITY: + - Designing integrated campaigns across multiple channels and formats + - Creating compelling storytelling that connects emotionally with audiences + - Developing creative executions for digital, print, video, and social media + - Ensuring creative excellence while meeting business objectives + - Creating campaigns that drive measurable results and brand growth + + BRAND CREATIVE STRATEGY: + - Aligning creative direction with brand positioning and values + - Developing creative approaches that build brand equity and recognition + - Creating distinctive visual and messaging elements that differentiate brands + - Ensuring creative consistency across all brand touchpoints + - Developing creative strategies that support long-term brand building + + Your expertise includes: + - Creative concept development and campaign ideation + - Visual direction and design strategy + - Copywriting and messaging development + - Campaign creative execution across all media + - Brand creative strategy and visual identity + - Creative performance optimization and testing + - Innovative advertising approaches and trends + + You deliver creative solutions that are both strategically sound and creatively brilliant, driving brand awareness, engagement, and conversions.""", + model_name="claude-3-sonnet-20240229", + max_loops=1, + temperature=0.8, + dynamic_temperature_enabled=True, + streaming_on=True, + print_on=True, +) + +# ============================================================================= +# SEO STRATEGIST AGENT +# ============================================================================= +seo_strategist_agent = Agent( + agent_name="SEO-Strategist", + agent_description="Technical SEO expert responsible for search optimization, keyword strategy, and organic growth", + system_prompt="""You are the SEO Strategist, the technical expert responsible for driving organic search visibility and traffic growth. Your comprehensive role includes: + + TECHNICAL SEO OPTIMIZATION: + - Conducting comprehensive technical SEO audits and implementing fixes + - Optimizing website architecture, site speed, and mobile responsiveness + - Managing XML sitemaps, robots.txt, and technical crawlability issues + - Implementing structured data markup and schema optimization + - Ensuring proper canonicalization, redirects, and URL structure + - Monitoring Core Web Vitals and technical performance metrics + + KEYWORD STRATEGY & RESEARCH: + - Conducting comprehensive keyword research and competitive analysis + - Developing keyword strategies aligned with business objectives + - Identifying high-value, low-competition keyword opportunities + - Creating keyword clusters and topic clusters for content planning + - Analyzing search intent and user behavior patterns + - Monitoring keyword performance and ranking fluctuations + + ON-PAGE SEO OPTIMIZATION: + - Optimizing page titles, meta descriptions, and header tags + - Creating SEO-optimized content that satisfies search intent + - Implementing internal linking strategies and site architecture + - Optimizing images, videos, and multimedia content for search + - Ensuring proper content structure and readability optimization + - Creating SEO-friendly URLs and navigation structures + + CONTENT SEO STRATEGY: + - Developing content strategies that target high-value keywords + - Creating SEO-optimized content briefs and guidelines + - Ensuring content satisfies search intent and user needs + - Implementing content optimization best practices + - Developing content clusters and topic authority building + - Creating content that drives organic traffic and conversions + + SEO ANALYTICS & REPORTING: + - Monitoring organic search performance and ranking metrics + - Analyzing search traffic patterns and user behavior + - Creating comprehensive SEO reports and recommendations + - Tracking competitor SEO strategies and performance + - Measuring SEO ROI and business impact + - Providing actionable insights for continuous optimization + + Your expertise includes: + - Technical SEO implementation and optimization + - Keyword research and competitive analysis + - On-page SEO and content optimization + - SEO analytics and performance measurement + - Local SEO and Google My Business optimization + - E-commerce SEO and product page optimization + - Voice search and featured snippet optimization + + You deliver data-driven SEO strategies that drive sustainable organic growth, improve search visibility, and generate qualified traffic that converts.""", + model_name="claude-3-sonnet-20240229", + max_loops=1, + temperature=0.6, + dynamic_temperature_enabled=True, + streaming_on=True, + print_on=True, +) + +# ============================================================================= +# BRAND STRATEGIST AGENT +# ============================================================================= +brand_strategist_agent = Agent( + agent_name="Brand-Strategist", + agent_description="Strategic brand expert responsible for brand positioning, identity development, and market differentiation", + system_prompt="""You are the Brand Strategist, the strategic expert responsible for developing and maintaining powerful brand positioning and market differentiation. Your comprehensive role includes: + + BRAND POSITIONING & STRATEGY: + - Developing compelling brand positioning statements and value propositions + - Creating brand strategies that differentiate in competitive markets + - Defining brand personality, voice, and character attributes + - Establishing brand pillars, messaging frameworks, and communication guidelines + - Creating brand positioning that resonates with target audiences + - Developing brand strategies that support business objectives and growth + + BRAND IDENTITY DEVELOPMENT: + - Creating comprehensive brand identity systems and guidelines + - Developing visual identity elements, logos, and brand assets + - Establishing brand color palettes, typography, and visual standards + - Creating brand style guides and identity manuals + - Ensuring brand consistency across all touchpoints and applications + - Developing brand identity that reflects positioning and values + + MARKET RESEARCH & INSIGHTS: + - Conducting comprehensive market research and competitive analysis + - Analyzing target audience segments and consumer behavior + - Identifying market opportunities and competitive advantages + - Researching industry trends and market dynamics + - Understanding customer needs, pain points, and motivations + - Providing insights that inform brand strategy and positioning + + BRAND MESSAGING & COMMUNICATION: + - Developing core brand messages and communication frameworks + - Creating brand storytelling and narrative development + - Establishing brand voice and tone guidelines + - Developing messaging hierarchies and communication strategies + - Creating brand messages that connect emotionally with audiences + - Ensuring consistent brand communication across all channels + + BRAND EXPERIENCE & TOUCHPOINTS: + - Designing comprehensive brand experience strategies + - Mapping customer journeys and brand touchpoints + - Creating brand experience guidelines and standards + - Ensuring brand consistency across all customer interactions + - Developing brand experience that builds loyalty and advocacy + - Creating memorable brand experiences that differentiate + + BRAND PERFORMANCE & MEASUREMENT: + - Establishing brand performance metrics and KPIs + - Measuring brand awareness, perception, and equity + - Tracking brand performance against competitors + - Analyzing brand sentiment and customer feedback + - Providing brand performance insights and recommendations + - Ensuring brand strategies drive measurable business outcomes + + Your expertise includes: + - Brand positioning and strategy development + - Brand identity and visual system design + - Market research and competitive analysis + - Brand messaging and communication strategy + - Brand experience design and optimization + - Brand performance measurement and analytics + - Brand architecture and portfolio management + + You deliver strategic brand solutions that create powerful market differentiation, build strong brand equity, and drive sustainable business growth through compelling brand positioning and experiences.""", + model_name="claude-3-sonnet-20240229", + max_loops=1, + temperature=0.7, + dynamic_temperature_enabled=True, + streaming_on=True, + print_on=True, +) + +# ============================================================================= +# MARKETING DIRECTOR AGENT (COORDINATOR) +# ============================================================================= +marketing_director_agent = Agent( + agent_name="Marketing-Director", + agent_description="Senior marketing director who orchestrates comprehensive marketing strategies across all specialized teams", + system_prompt="""You are the Marketing Director, the senior executive responsible for orchestrating comprehensive marketing strategies and coordinating a team of specialized marketing experts. Your role is to: + + STRATEGIC COORDINATION: + - Analyze complex marketing challenges and break them down into specialized tasks + - Assign tasks to the most appropriate specialist based on their unique expertise + - Ensure comprehensive coverage of all marketing dimensions (content, creative, SEO, brand) + - Coordinate between specialists to avoid duplication and ensure synergy + - Synthesize findings from multiple specialists into coherent marketing strategies + - Ensure all marketing efforts align with business objectives and target audience needs + + TEAM LEADERSHIP: + - Lead the Head of Content in developing content strategies and editorial direction + - Guide the Ad Creative Director in creating compelling campaigns and visual concepts + - Direct the SEO Strategist in optimizing search visibility and organic growth + - Oversee the Brand Strategist in developing brand positioning and market differentiation + - Ensure all team members work collaboratively toward unified marketing goals + - Provide strategic direction and feedback to optimize team performance + + INTEGRATED MARKETING STRATEGY: + - Develop integrated marketing campaigns that leverage all specialist expertise + - Ensure content, creative, SEO, and brand strategies work together seamlessly + - Create marketing roadmaps that coordinate efforts across all channels + - Balance short-term campaign needs with long-term brand building + - Ensure marketing strategies drive measurable business outcomes + - Optimize marketing mix and budget allocation across all activities + + PERFORMANCE OPTIMIZATION: + - Monitor marketing performance across all channels and activities + - Analyze data to identify optimization opportunities and strategic adjustments + - Ensure marketing efforts deliver ROI and support business growth + - Provide strategic recommendations based on performance insights + - Coordinate testing and optimization efforts across all marketing functions + - Ensure continuous improvement and innovation in marketing approaches + + Your expertise includes: + - Integrated marketing strategy and campaign development + - Team leadership and cross-functional coordination + - Marketing performance analysis and optimization + - Strategic planning and business alignment + - Budget management and resource allocation + - Stakeholder communication and executive reporting + + You deliver comprehensive marketing strategies that leverage the full expertise of your specialized team, ensuring all marketing efforts work together to drive business growth, brand awareness, and customer acquisition.""", + model_name="claude-3-sonnet-20240229", + max_loops=1, + temperature=0.7, + dynamic_temperature_enabled=True, + streaming_on=True, + print_on=True, +) + +# ============================================================================= +# HIERARCHICAL MARKETING SWARM +# ============================================================================= +# Create list of specialized marketing agents +marketing_agents = [ + head_of_content_agent, + ad_creative_director_agent, + seo_strategist_agent, + brand_strategist_agent, +] + +# Initialize the hierarchical marketing swarm +marketing_swarm = HierarchicalSwarm( + name="Hierarchical-Marketing-Swarm", + description="A comprehensive marketing team with specialized agents for content, creative, SEO, and brand strategy, coordinated by a marketing director", + director=marketing_director_agent, + agents=marketing_agents, + max_loops=2, + verbose=True, +) + +# ============================================================================= +# EXAMPLE USAGE +# ============================================================================= +if __name__ == "__main__": + # Example marketing challenge + task = """Develop a comprehensive marketing strategy for a new SaaS product launch. + The product is a project management tool targeting small to medium businesses. + Please coordinate the team to create: + 1. Content strategy and editorial plan + 2. Creative campaign concepts and visual direction + 3. SEO strategy for organic growth + 4. Brand positioning and market differentiation + + Ensure all elements work together cohesively to drive awareness, engagement, and conversions.""" + + result = marketing_swarm.run(task=task) + print("=" * 80) + print("MARKETING SWARM RESULTS") + print("=" * 80) + print(result) +``` \ No newline at end of file diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 388e5ece..3dbe9e3f 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -363,7 +363,6 @@ nav: - Agents with Vision and Tool Usage: "swarms/examples/vision_tools.md" - Agents with Callable Tools: "swarms/examples/agent_with_tools.md" - Agent with Structured Outputs: "swarms/examples/agent_structured_outputs.md" - - Agent With MCP Integration: "swarms/examples/agent_with_mcp.md" - Message Transforms for Context Management: "swarms/structs/transforms.md" - Vision: - Agents with Vision: "swarms/examples/vision_processing.md" @@ -404,7 +403,6 @@ nav: - SwarmRouter Example: "swarms/examples/swarm_router.md" - MultiAgentRouter Minimal Example: "swarms/examples/multi_agent_router_minimal.md" - ConcurrentWorkflow Example: "swarms/examples/concurrent_workflow.md" - # - MixtureOfAgents Example: "swarms/examples/mixture_of_agents.md" - Mixture of Agents Example: "swarms/examples/moa_example.md" - Unique Swarms: "swarms/examples/unique_swarms.md" - Agents as Tools: "swarms/examples/agents_as_tools.md" @@ -414,9 +412,10 @@ nav: - Simple BatchedGridWorkflow: "swarms/examples/batched_grid_simple_example.md" - Advanced BatchedGridWorkflow: "swarms/examples/batched_grid_advanced_example.md" - Applications: - - Swarms DAO: "swarms/examples/swarms_dao.md" - Swarms of Browser Agents: "swarms/examples/swarms_of_browser_agents.md" - ConcurrentWorkflow with VLLM Agents: "swarms/examples/vllm.md" + - Hiearchical Marketing Team: "examples/marketing_team.md" + - Gold ETF Research with HeavySwarm: "examples/gold_etf_research.md" - Tools & Integrations: - Web Search with Exa: "examples/exa_search.md" @@ -424,6 +423,10 @@ nav: - Browser Use: "examples/browser_use.md" - Yahoo Finance: "swarms/examples/yahoo_finance.md" - Firecrawl: "developer_guides/firecrawl.md" + + - MCP: + - Multi-MCP Agent Integration: "swarms/examples/multi_mcp_agent.md" + - Agent With MCP Integration: "swarms/examples/agent_with_mcp.md" - RAG: - RAG with Qdrant: "swarms/RAG/qdrant_rag.md" diff --git a/docs/swarms/examples/multi_mcp_agent.md b/docs/swarms/examples/multi_mcp_agent.md new file mode 100644 index 00000000..9b1b938c --- /dev/null +++ b/docs/swarms/examples/multi_mcp_agent.md @@ -0,0 +1,364 @@ +# Multi-MCP Agent Integration + +This guide demonstrates how to use multiple MCP (Model Context Protocol) servers with a single Swarms agent, enabling powerful tool orchestration and cross-server functionality. + +## Overview + +The Multi-MCP integration allows a single agent to access tools from multiple MCP servers simultaneously. This is particularly useful when you need to combine different capabilities, such as: + +- **Financial data** from crypto exchanges +- **Agent creation** tools for dynamic agent spawning +- **Custom business logic** from specialized servers +- **External APIs** through dedicated MCP servers + +## Architecture + +```mermaid +graph TD + A[Single Swarms Agent] --> B[MCP Client] + B --> C[MCP Server 1: OKX Crypto] + B --> D[MCP Server 2: Agent Tools] + B --> E[MCP Server N: Custom Tools] + + C --> F[get_okx_crypto_price] + C --> G[get_okx_crypto_volume] + + D --> H[create_agent] + + E --> I[Custom Tool 1] + E --> J[Custom Tool 2] +``` + +## Setup + +### 1. Install Dependencies + +```bash +pip install swarms mcp requests +``` + +### 2. Create MCP Servers + +#### OKX Crypto Server (`okx_crypto_server.py`) + +```python +from mcp.server.fastmcp import FastMCP +import requests + +mcp = FastMCP("OKXCryptoPrice") +mcp.settings.port = 8001 + +@mcp.tool( + name="get_okx_crypto_price", + description="Get the current price and basic information for a given cryptocurrency from OKX exchange.", +) +def get_okx_crypto_price(symbol: str) -> str: + """ + Get the current price and basic information for a given cryptocurrency using OKX API. + + Args: + symbol (str): The cryptocurrency trading pair (e.g., 'BTC-USDT', 'ETH-USDT') + + Returns: + str: A formatted string containing the cryptocurrency information + """ + try: + if not symbol: + return "Please provide a valid trading pair (e.g., 'BTC-USDT')" + + # Convert to uppercase and ensure proper format + symbol = symbol.upper() + if not symbol.endswith("-USDT"): + symbol = f"{symbol}-USDT" + + # OKX API endpoint for ticker information + url = f"https://www.okx.com/api/v5/market/ticker?instId={symbol}" + + # Make the API request + response = requests.get(url) + response.raise_for_status() + + data = response.json() + + if data.get("code") != "0": + return f"Error: {data.get('msg', 'Unknown error')}" + + ticker_data = data.get("data", [{}])[0] + if not ticker_data: + return f"Could not find data for {symbol}. Please check the trading pair." + + price = float(ticker_data.get("last", 0)) + change_percent = float(ticker_data.get("change24h", 0)) + + base_currency = symbol.split("-")[0] + return f"Current price of {base_currency}/USDT: ${price:,.2f}\n24h Change: {change_percent:.2f}%" + + except requests.exceptions.RequestException as e: + return f"Error fetching OKX data: {str(e)}" + except Exception as e: + return f"Error: {str(e)}" + +@mcp.tool( + name="get_okx_crypto_volume", + description="Get the 24-hour trading volume for a given cryptocurrency from OKX exchange.", +) +def get_okx_crypto_volume(symbol: str) -> str: + """ + Get the 24-hour trading volume for a given cryptocurrency using OKX API. + + Args: + symbol (str): The cryptocurrency trading pair (e.g., 'BTC-USDT', 'ETH-USDT') + + Returns: + str: A formatted string containing the trading volume information + """ + try: + if not symbol: + return "Please provide a valid trading pair (e.g., 'BTC-USDT')" + + # Convert to uppercase and ensure proper format + symbol = symbol.upper() + if not symbol.endswith("-USDT"): + symbol = f"{symbol}-USDT" + + # OKX API endpoint for ticker information + url = f"https://www.okx.com/api/v5/market/ticker?instId={symbol}" + + # Make the API request + response = requests.get(url) + response.raise_for_status() + + data = response.json() + + if data.get("code") != "0": + return f"Error: {data.get('msg', 'Unknown error')}" + + ticker_data = data.get("data", [{}])[0] + if not ticker_data: + return f"Could not find data for {symbol}. Please check the trading pair." + + volume_24h = float(ticker_data.get("vol24h", 0)) + base_currency = symbol.split("-")[0] + return f"24h Trading Volume for {base_currency}/USDT: ${volume_24h:,.2f}" + + except requests.exceptions.RequestException as e: + return f"Error fetching OKX data: {str(e)}" + except Exception as e: + return f"Error: {str(e)}" + +if __name__ == "__main__": + mcp.run(transport="streamable-http") +``` + +#### Agent Tools Server (`mcp_agent_tool.py`) + +```python +from mcp.server.fastmcp import FastMCP +from swarms import Agent + +mcp = FastMCP("MCPAgentTool") + +@mcp.tool( + name="create_agent", + description="Create an agent with the specified name, system prompt, and model, then run a task.", +) +def create_agent( + agent_name: str, system_prompt: str, model_name: str, task: str +) -> str: + """ + Create an agent with the given parameters and execute the specified task. + + Args: + agent_name (str): The name of the agent to create. + system_prompt (str): The system prompt to initialize the agent with. + model_name (str): The model name to use for the agent. + task (str): The task for the agent to perform. + + Returns: + str: The result of the agent running the given task. + """ + agent = Agent( + agent_name=agent_name, + system_prompt=system_prompt, + model_name=model_name, + ) + return agent.run(task) + +if __name__ == "__main__": + mcp.run(transport="streamable-http") +``` + +### 3. Start MCP Servers + +Start each MCP server in separate terminals: + +```bash +# Terminal 1 - OKX Crypto Server +python okx_crypto_server.py + +# Terminal 2 - Agent Tools Server +python mcp_agent_tool.py +``` + +## Usage Examples + +### Basic Multi-MCP Agent + +```python +from swarms import Agent +from swarms.prompts.finance_agent_sys_prompt import ( + FINANCIAL_AGENT_SYS_PROMPT, +) + +# Initialize the agent with multiple MCP servers +agent = Agent( + agent_name="Financial-Analysis-Agent", + agent_description="Personal finance advisor agent", + system_prompt=FINANCIAL_AGENT_SYS_PROMPT, + max_loops=1, + mcp_urls=[ + "http://0.0.0.0:8001/mcp", # OKX Crypto Server + "http://0.0.0.0:8000/mcp", # Agent Tools Server + ], + model_name="gpt-4o-mini", + output_type="all", +) + +# Use tools from multiple servers +result = agent.run( + "Get the current price of Bitcoin and then create a new agent to analyze the market trends" +) +print(result) +``` + +### Advanced Multi-MCP Workflow + +```python +from swarms import Agent + +# Custom system prompt for multi-tool coordination +MULTI_MCP_SYSTEM_PROMPT = """ +You are a sophisticated financial analysis agent with access to multiple tools: + +1. OKX Crypto Tools: + - get_okx_crypto_price: Get current cryptocurrency prices + - get_okx_crypto_volume: Get 24h trading volumes + +2. Agent Creation Tools: + - create_agent: Create specialized agents for specific tasks + +Use these tools strategically to provide comprehensive financial analysis. +When creating agents, ensure they have specific, focused tasks. +""" + +agent = Agent( + agent_name="Multi-MCP-Financial-Agent", + system_prompt=MULTI_MCP_SYSTEM_PROMPT, + mcp_urls=[ + "http://0.0.0.0:8001/mcp", # OKX Crypto + "http://0.0.0.0:8000/mcp", # Agent Tools + ], + model_name="gpt-4o-mini", + max_loops=3, +) + +# Complex multi-step analysis +result = agent.run(""" +1. Get the current price and volume for Bitcoin, Ethereum, and Solana +2. Create a technical analysis agent to analyze these prices +3. Create a market sentiment agent to provide additional insights +4. Summarize the findings from all agents +""") + +print(result) +``` + +## Configuration Options + +### MCP URL Configuration + +```python +# Multiple MCP servers +mcp_urls = [ + "http://localhost:8000/mcp", # Server 1 + "http://localhost:8001/mcp", # Server 2 + "http://localhost:8002/mcp", # Server 3 + # Add more servers as needed +] + +agent = Agent( + mcp_urls=mcp_urls, + # ... other parameters +) +``` + +### Error Handling + +```python +from swarms import Agent + +agent = Agent( + agent_name="Robust-Multi-MCP-Agent", + mcp_urls=[ + "http://0.0.0.0:8001/mcp", + "http://0.0.0.0:8000/mcp", + ], + model_name="gpt-4o-mini", + max_loops=1, + # The agent will gracefully handle MCP server failures + # and continue with available tools +) + +try: + result = agent.run("Use available tools to analyze the market") + print(result) +except Exception as e: + print(f"Error: {e}") +``` + +## Best Practices + +### 1. Server Organization + +- **Dedicated servers**: Create separate MCP servers for different domains (finance, data processing, etc.) +- **Port management**: Use different ports for each server to avoid conflicts +- **Error isolation**: If one server fails, others continue to work + +### 2. Tool Naming + +- Use descriptive, unique tool names across servers +- Avoid naming conflicts between different MCP servers +- Include server context in tool descriptions + +### 3. System Prompts + +- Clearly document available tools from each server +- Provide guidance on when to use which tools +- Include error handling instructions + +### 4. Performance Optimization + +- Start with essential servers first +- Use connection pooling for multiple servers +- Monitor server health and response times + +## Troubleshooting + +### Common Issues + +1. **Connection Refused**: Ensure MCP servers are running on correct ports +2. **Tool Not Found**: Check tool names and server availability +3. **Timeout Errors**: Increase timeout settings for slow servers +4. **Authentication**: Some servers may require API keys + + +## Conclusion + +Multi-MCP integration provides powerful capabilities for creating sophisticated agents that can leverage tools from multiple specialized servers. This approach enables: + +- **Modularity**: Separate concerns into different MCP servers +- **Scalability**: Add new capabilities without modifying existing code +- **Reliability**: Fault tolerance through multiple server support +- **Flexibility**: Mix and match tools from different domains + +By following the patterns and best practices outlined in this guide, you can build robust, multi-capability agents that can handle complex, multi-step tasks across different domains. diff --git a/examples/mcp/deploy_mcp_server/multiagent_client.py b/examples/mcp/mcp_utils/multiagent_client.py similarity index 100% rename from examples/mcp/deploy_mcp_server/multiagent_client.py rename to examples/mcp/mcp_utils/multiagent_client.py diff --git a/examples/mcp/deploy_mcp_server/singleagent_client.py b/examples/mcp/mcp_utils/singleagent_client.py similarity index 100% rename from examples/mcp/deploy_mcp_server/singleagent_client.py rename to examples/mcp/mcp_utils/singleagent_client.py diff --git a/examples/mcp/multi_mcp_example.py b/examples/mcp/multi_mcp_example.py new file mode 100644 index 00000000..1636da92 --- /dev/null +++ b/examples/mcp/multi_mcp_example.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python3 +""" +Multi-MCP Agent Example + +This example demonstrates how to use multiple MCP (Model Context Protocol) servers +with a single Swarms agent. The agent can access tools from different MCP servers +simultaneously, enabling powerful cross-server functionality. + +Prerequisites: +1. Start the OKX crypto server: python multi_mcp_guide/okx_crypto_server.py +2. Start the agent tools server: python multi_mcp_guide/mcp_agent_tool.py +3. Install required dependencies: pip install swarms mcp fastmcp requests + +Usage: + python examples/multi_agent/multi_mcp_example.py +""" + +from swarms import Agent +from swarms.prompts.finance_agent_sys_prompt import ( + FINANCIAL_AGENT_SYS_PROMPT, +) + + +def create_multi_mcp_agent(): + """ + Create an agent that can access multiple MCP servers. + + Returns: + Agent: Configured agent with access to multiple MCP servers + """ + return Agent( + agent_name="Multi-MCP-Financial-Agent", + agent_description="Advanced financial analysis agent with multi-MCP capabilities", + system_prompt=FINANCIAL_AGENT_SYS_PROMPT, + max_loops=3, + mcp_urls=[ + "http://0.0.0.0:8001/mcp", # OKX Crypto Server + "http://0.0.0.0:8000/mcp", # Agent Tools Server + ], + model_name="gpt-4o-mini", + output_type="all", + ) + + +def basic_crypto_analysis(): + """ + Basic example: Get cryptocurrency prices using OKX MCP server. + """ + print("=== Basic Crypto Analysis ===") + + agent = create_multi_mcp_agent() + + # Simple crypto price lookup + result = agent.run( + "Get the current price of Bitcoin, Ethereum, and Solana using the OKX crypto tools" + ) + + print("Result:", result) + print("\n" + "=" * 50 + "\n") + + +def advanced_multi_step_analysis(): + """ + Advanced example: Combine crypto data with agent creation. + """ + print("=== Advanced Multi-Step Analysis ===") + + agent = create_multi_mcp_agent() + + # Complex multi-step task + result = agent.run( + """ + Perform a comprehensive crypto market analysis: + + 1. Get current prices for Bitcoin, Ethereum, and Solana + 2. Get 24h trading volumes for these cryptocurrencies + 3. Create a technical analysis agent to analyze the price trends + 4. Create a market sentiment agent to provide additional insights + 5. Summarize all findings in a comprehensive report + """ + ) + + print("Result:", result) + print("\n" + "=" * 50 + "\n") + + +def custom_system_prompt_example(): + """ + Example with custom system prompt for better tool coordination. + """ + print("=== Custom System Prompt Example ===") + + custom_prompt = """ + You are a sophisticated financial analysis agent with access to multiple specialized tools: + + CRYPTO TOOLS (from OKX server): + - get_okx_crypto_price: Get current cryptocurrency prices + - get_okx_crypto_volume: Get 24h trading volumes + + AGENT CREATION TOOLS (from Agent Tools server): + - create_agent: Create specialized agents for specific analysis tasks + + INSTRUCTIONS: + 1. Always use the most appropriate tool for each task + 2. When creating agents, give them specific, focused tasks + 3. Provide clear, actionable insights based on the data + 4. If a tool fails, try alternative approaches + 5. Always explain your reasoning and methodology + + Your goal is to provide comprehensive, data-driven financial analysis. + """ + + agent = Agent( + agent_name="Custom-Multi-MCP-Agent", + system_prompt=custom_prompt, + mcp_urls=[ + "http://0.0.0.0:8001/mcp", # OKX Crypto + "http://0.0.0.0:8000/mcp", # Agent Tools + ], + model_name="gpt-4o-mini", + max_loops=2, + ) + + result = agent.run( + "Analyze the current crypto market and create specialized agents to help with investment decisions" + ) + + print("Result:", result) + print("\n" + "=" * 50 + "\n") + + +def error_handling_example(): + """ + Example demonstrating error handling with multiple MCP servers. + """ + print("=== Error Handling Example ===") + + agent = Agent( + agent_name="Robust-Multi-MCP-Agent", + system_prompt="You are a resilient agent that handles errors gracefully.", + mcp_urls=[ + "http://0.0.0.0:8001/mcp", # OKX Crypto (should be running) + "http://0.0.0.0:8002/mcp", # Non-existent server (will fail) + "http://0.0.0.0:8000/mcp", # Agent Tools (should be running) + ], + model_name="gpt-4o-mini", + max_loops=1, + ) + + try: + result = agent.run( + "Try to use all available tools. If some fail, work with what's available." + ) + print("Result:", result) + except Exception as e: + print(f"Error occurred: {e}") + + print("\n" + "=" * 50 + "\n") + + +def main(): + """ + Main function to run all examples. + """ + print("Multi-MCP Agent Examples") + print("=" * 50) + print("Make sure the MCP servers are running:") + print( + "1. OKX Crypto Server: python multi_mcp_guide/okx_crypto_server.py" + ) + print( + "2. Agent Tools Server: python multi_mcp_guide/mcp_agent_tool.py" + ) + print("=" * 50) + + try: + # Run examples + basic_crypto_analysis() + advanced_multi_step_analysis() + custom_system_prompt_example() + error_handling_example() + + print("All examples completed successfully!") + + except Exception as e: + print(f"Error running examples: {e}") + print("Make sure the MCP servers are running and accessible.") + + +if __name__ == "__main__": + main() diff --git a/examples/mcp/agent_examples/agent_mcp.py b/examples/mcp/multi_mcp_guide/agent_mcp.py similarity index 63% rename from examples/mcp/agent_examples/agent_mcp.py rename to examples/mcp/multi_mcp_guide/agent_mcp.py index 13ab9bff..1740f1ee 100644 --- a/examples/mcp/agent_examples/agent_mcp.py +++ b/examples/mcp/multi_mcp_guide/agent_mcp.py @@ -3,22 +3,24 @@ from swarms.prompts.finance_agent_sys_prompt import ( FINANCIAL_AGENT_SYS_PROMPT, ) - # Initialize the agent agent = Agent( agent_name="Financial-Analysis-Agent", agent_description="Personal finance advisor agent", system_prompt=FINANCIAL_AGENT_SYS_PROMPT, max_loops=1, - mcp_url="http://0.0.0.0:8000/sse", + mcp_urls=[ + "http://0.0.0.0:8001/mcp", + "http://0.0.0.0:8000/mcp", + ], model_name="gpt-4o-mini", output_type="all", ) # Create a markdown file with initial content out = agent.run( - "Use the get_okx_crypto_volume to get the volume of BTC just put the name of the coin", + # "Use the get_okx_crypto_price to get the price of solana just put the name of the coin", + "Use the create_agent tool that is specialized in creating agents" ) print(out) -print(type(out)) diff --git a/examples/mcp/deploy_mcp_server/mcp_agent_tool.py b/examples/mcp/multi_mcp_guide/mcp_agent_tool.py similarity index 100% rename from examples/mcp/deploy_mcp_server/mcp_agent_tool.py rename to examples/mcp/multi_mcp_guide/mcp_agent_tool.py diff --git a/examples/mcp/multi_mcp_guide/okx_crypto_server.py b/examples/mcp/multi_mcp_guide/okx_crypto_server.py new file mode 100644 index 00000000..f082c353 --- /dev/null +++ b/examples/mcp/multi_mcp_guide/okx_crypto_server.py @@ -0,0 +1,120 @@ +from mcp.server.fastmcp import FastMCP +import requests + +mcp = FastMCP("OKXCryptoPrice") + +mcp.settings.port = 8001 + + +@mcp.tool( + name="get_okx_crypto_price", + description="Get the current price and basic information for a given cryptocurrency from OKX exchange.", +) +def get_okx_crypto_price(symbol: str) -> str: + """ + Get the current price and basic information for a given cryptocurrency using OKX API. + + Args: + symbol (str): The cryptocurrency trading pair (e.g., 'BTC-USDT', 'ETH-USDT') + + Returns: + str: A formatted string containing the cryptocurrency information + + Example: + >>> get_okx_crypto_price('BTC-USDT') + 'Current price of BTC/USDT: $45,000' + """ + try: + if not symbol: + return "Please provide a valid trading pair (e.g., 'BTC-USDT')" + + # Convert to uppercase and ensure proper format + symbol = symbol.upper() + if not symbol.endswith("-USDT"): + symbol = f"{symbol}-USDT" + + # OKX API endpoint for ticker information + url = f"https://www.okx.com/api/v5/market/ticker?instId={symbol}" + + # Make the API request + response = requests.get(url) + response.raise_for_status() + + data = response.json() + + if data.get("code") != "0": + return f"Error: {data.get('msg', 'Unknown error')}" + + ticker_data = data.get("data", [{}])[0] + if not ticker_data: + return f"Could not find data for {symbol}. Please check the trading pair." + + price = float(ticker_data.get("last", 0)) + float(ticker_data.get("last24h", 0)) + change_percent = float(ticker_data.get("change24h", 0)) + + base_currency = symbol.split("-")[0] + return f"Current price of {base_currency}/USDT: ${price:,.2f}\n24h Change: {change_percent:.2f}%" + + except requests.exceptions.RequestException as e: + return f"Error fetching OKX data: {str(e)}" + except Exception as e: + return f"Error: {str(e)}" + + +@mcp.tool( + name="get_okx_crypto_volume", + description="Get the 24-hour trading volume for a given cryptocurrency from OKX exchange.", +) +def get_okx_crypto_volume(symbol: str) -> str: + """ + Get the 24-hour trading volume for a given cryptocurrency using OKX API. + + Args: + symbol (str): The cryptocurrency trading pair (e.g., 'BTC-USDT', 'ETH-USDT') + + Returns: + str: A formatted string containing the trading volume information + + Example: + >>> get_okx_crypto_volume('BTC-USDT') + '24h Trading Volume for BTC/USDT: $1,234,567' + """ + try: + if not symbol: + return "Please provide a valid trading pair (e.g., 'BTC-USDT')" + + # Convert to uppercase and ensure proper format + symbol = symbol.upper() + if not symbol.endswith("-USDT"): + symbol = f"{symbol}-USDT" + + # OKX API endpoint for ticker information + url = f"https://www.okx.com/api/v5/market/ticker?instId={symbol}" + + # Make the API request + response = requests.get(url) + response.raise_for_status() + + data = response.json() + + if data.get("code") != "0": + return f"Error: {data.get('msg', 'Unknown error')}" + + ticker_data = data.get("data", [{}])[0] + if not ticker_data: + return f"Could not find data for {symbol}. Please check the trading pair." + + volume_24h = float(ticker_data.get("vol24h", 0)) + base_currency = symbol.split("-")[0] + return f"24h Trading Volume for {base_currency}/USDT: ${volume_24h:,.2f}" + + except requests.exceptions.RequestException as e: + return f"Error fetching OKX data: {str(e)}" + except Exception as e: + return f"Error: {str(e)}" + + +if __name__ == "__main__": + # Run the server on port 8000 (you can change this to any available port) + mcp.run(transport="streamable-http") diff --git a/examples/mcp/servers/mcp_agent_tool.py b/examples/mcp/servers/mcp_agent_tool.py new file mode 100644 index 00000000..dcaf9b04 --- /dev/null +++ b/examples/mcp/servers/mcp_agent_tool.py @@ -0,0 +1,35 @@ +from mcp.server.fastmcp import FastMCP +from swarms import Agent + +mcp = FastMCP("MCPAgentTool") + + +@mcp.tool( + name="create_agent", + description="Create an agent with the specified name, system prompt, and model, then run a task.", +) +def create_agent( + agent_name: str, system_prompt: str, model_name: str, task: str +) -> str: + """ + Create an agent with the given parameters and execute the specified task. + + Args: + agent_name (str): The name of the agent to create. + system_prompt (str): The system prompt to initialize the agent with. + model_name (str): The model name to use for the agent. + task (str): The task for the agent to perform. + + Returns: + str: The result of the agent running the given task. + """ + agent = Agent( + agent_name=agent_name, + system_prompt=system_prompt, + model_name=model_name, + ) + return agent.run(task) + + +if __name__ == "__main__": + mcp.run(transport="streamable-http") diff --git a/examples/mcp/utils.py b/examples/mcp/utils.py new file mode 100644 index 00000000..fca8fd8c --- /dev/null +++ b/examples/mcp/utils.py @@ -0,0 +1,4 @@ +from swarms.tools.mcp_client_tools import get_mcp_tools_sync + + +print(get_mcp_tools_sync(server_path="http://localhost:8000/mcp")) diff --git a/swarms/structs/batched_grid_workflow.py b/swarms/structs/batched_grid_workflow.py index 2c2f25d3..66e6d71f 100644 --- a/swarms/structs/batched_grid_workflow.py +++ b/swarms/structs/batched_grid_workflow.py @@ -11,6 +11,36 @@ from swarms.structs.swarm_id import swarm_id class BatchedGridWorkflow: + """ + A workflow class for executing tasks in a batched grid pattern. + + This class implements a batched grid workflow where multiple agents can execute + tasks concurrently in a grid-like fashion. Each agent processes tasks independently, + and the workflow can be run for multiple loops to enable iterative processing. + + The workflow supports: + - Concurrent task execution across multiple agents + - Configurable number of execution loops + - Error handling and logging for robust operation + - Unique identification and naming for workflow instances + + Attributes: + id (str): Unique identifier for the workflow instance. + name (str): Human-readable name for the workflow. + description (str): Description of the workflow's purpose. + agents (List[AgentType]): List of agents to execute tasks. + max_loops (int): Maximum number of execution loops to perform. + + Example: + >>> from swarms.structs.batched_grid_workflow import BatchedGridWorkflow + >>> workflow = BatchedGridWorkflow( + ... name="Data Processing Workflow", + ... agents=[agent1, agent2, agent3], + ... max_loops=3 + ... ) + >>> results = workflow.run(["task1", "task2", "task3"]) + """ + def __init__( self, id: str = swarm_id(), @@ -23,11 +53,11 @@ class BatchedGridWorkflow: Initialize a BatchedGridWorkflow instance. Args: - id: Unique identifier for the workflow - name: Name of the workflow - description: Description of what the workflow does - agents: List of agents to execute tasks - max_loops: Maximum number of execution loops to run (must be >= 1) + id: Unique identifier for the workflow. + name: Name of the workflow. + description: Description of what the workflow does. + agents: List of agents to execute tasks. + max_loops: Maximum number of execution loops to run (must be >= 1). """ self.id = id self.name = name @@ -44,10 +74,10 @@ class BatchedGridWorkflow: Execute one step of the batched grid workflow. Args: - tasks: List of tasks to execute + tasks: List of tasks to execute. Returns: - Output from the batched grid agent execution + Output from the batched grid agent execution. """ return batched_grid_agent_execution(self.agents, tasks) @@ -56,10 +86,10 @@ class BatchedGridWorkflow: Run the batched grid workflow with the given tasks. Args: - tasks: List of tasks to execute + tasks: List of tasks to execute. Returns: - List: Results from all execution loops + List: Results from all execution loops. """ results = [] current_loop = 0 @@ -75,11 +105,25 @@ class BatchedGridWorkflow: def run(self, tasks: List[str]): """ Run the batched grid workflow with the given tasks. + + Args: + tasks: List of tasks to execute. + + Returns: + List: Results from all execution loops. + + Raises: + Exception: If an error occurs during workflow execution. """ try: return self.run_(tasks) except Exception as e: logger.error( - f"BatchedGridWorkflow Error: {self.name}\n\nId: {self.id}\n\nAn error occurred while running the batched grid workflow: {e}\nTraceback:\n{traceback.format_exc()}" + ( + f"BatchedGridWorkflow Error: {self.name}\n" + f"Id: {self.id}\n" + f"An error occurred while running the batched grid workflow: {e}\n" + f"Traceback:\n{traceback.format_exc()}" + ) ) - raise e + raise diff --git a/swarms/structs/transforms.py b/swarms/structs/transforms.py index 1a705531..22310049 100644 --- a/swarms/structs/transforms.py +++ b/swarms/structs/transforms.py @@ -3,8 +3,8 @@ from typing import Any, Dict, List, Optional from loguru import logger -from swarms.utils.litellm_tokenizer import count_tokens from swarms.structs.conversation import Conversation +from swarms.utils.litellm_tokenizer import count_tokens @dataclass diff --git a/swarms/tools/mcp_client_tools.py b/swarms/tools/mcp_client_tools.py index bd42f8cf..c45d15dd 100644 --- a/swarms/tools/mcp_client_tools.py +++ b/swarms/tools/mcp_client_tools.py @@ -7,20 +7,12 @@ import traceback from concurrent.futures import ThreadPoolExecutor, as_completed from functools import wraps from typing import Any, Dict, List, Literal, Optional, Union +from urllib.parse import urlparse from litellm.types.utils import ChatCompletionMessageToolCall from loguru import logger from mcp import ClientSession - -try: - from mcp.client.streamable_http import streamablehttp_client -except ImportError: - logger.error( - "streamablehttp_client is not available. Please ensure the MCP SDK is up to date with pip3 install -U mcp" - ) - -from urllib.parse import urlparse - +from mcp.client.streamable_http import streamablehttp_client from mcp.types import ( CallToolRequestParams as MCPCallToolRequestParams, ) @@ -281,7 +273,7 @@ def connect_to_mcp_server(connection: MCPConnection = None): return ( headers, connection.timeout or 5, - connection.transport or "sse", + connection.transport or "streamable-http", connection.url, ) @@ -289,9 +281,9 @@ def connect_to_mcp_server(connection: MCPConnection = None): def get_mcp_client(transport, url, headers=None, timeout=5, **kwargs): """ Helper to select the correct MCP client context manager based on transport. - Supports 'sse' (default) and 'streamable_http'. + Supports 'streamable_http' (default). Args: - transport (str): The transport type ('sse' or 'streamable_http'). + transport (str): The transport type ('streamable_http'). url (str): The server URL. headers (dict): Optional headers. timeout (int): Timeout in seconds. @@ -323,7 +315,7 @@ def auto_detect_transport(url: str) -> str: """ Guess the MCP transport based on the URL scheme and path. Does not make any network requests. - Returns one of: 'streamable_http', 'sse', or 'stdio'. + Returns one of: 'streamable_http' or 'stdio'. Args: url (str): The server URL. Returns: @@ -336,19 +328,16 @@ def auto_detect_transport(url: str) -> str: f"Automatically selected 'streamable_http' transport for {url}" ) return "streamable_http" - elif scheme in ("ws", "wss"): - logger.info( - f"Automatically selected 'sse' transport for {url}" - ) - return "sse" # or 'websocket' if you support it elif "stdio" in url or scheme == "": logger.info( f"Automatically selected 'stdio' transport for {url}" ) return "stdio" else: - logger.info(f"Defaulting to 'sse' transport for {url}") - return "sse" + logger.info( + f"Defaulting to 'streamable_http' transport for {url}" + ) + return "streamable-http" @retry_with_backoff(retries=3) @@ -430,7 +419,7 @@ def get_mcp_tools_sync( server_path: Optional[str] = None, format: str = "openai", connection: Optional[MCPConnection] = None, - transport: Optional[str] = None, + transport: Optional[str] = "streamable-http", *args, **kwargs, ) -> List[Dict[str, Any]]: @@ -578,7 +567,7 @@ async def _execute_tool_call_simple( **kwargs, ): """ - Execute a tool call using the MCP client, supporting both SSE and streamable HTTP. + Execute a tool call using the MCP client, supporting streamable HTTP. Args: response (any): The tool call request. server_path (str): The server URL. @@ -605,7 +594,7 @@ async def _execute_tool_call_simple( headers, timeout, _transport, url = ( None, 5, - "sse", + "streamable-http", server_path, ) try: @@ -765,7 +754,7 @@ async def _create_server_tool_mapping_async( urls: List[str], connections: List[MCPConnection] = None, format: str = "openai", - transport: str = "sse", + transport: str = "streamable-http", ) -> Dict[str, Dict[str, Any]]: """ Async version: Create a mapping of function names to server information for all MCP servers. @@ -819,7 +808,7 @@ async def _execute_tool_on_server( tool_call: Dict[str, Any], server_info: Dict[str, Any], output_type: Literal["json", "dict", "str", "formatted"] = "str", - transport: str = "sse", + transport: str = "streamable-http", ) -> Dict[str, Any]: """ Execute a single tool call on a specific server. @@ -870,7 +859,7 @@ async def execute_multiple_tools_on_multiple_mcp_servers( connections: List[MCPConnection] = None, output_type: Literal["json", "dict", "str", "formatted"] = "str", max_concurrent: Optional[int] = None, - transport: str = "sse", + transport: str = "streamable-http", *args, **kwargs, ) -> List[Dict[str, Any]]: @@ -1105,7 +1094,7 @@ def execute_multiple_tools_on_multiple_mcp_servers_sync( connections: List[MCPConnection] = None, output_type: Literal["json", "dict", "str", "formatted"] = "str", max_concurrent: Optional[int] = None, - transport: str = "sse", + transport: str = "streamable-http", *args, **kwargs, ) -> List[Dict[str, Any]]: diff --git a/swarms/utils/litellm_wrapper.py b/swarms/utils/litellm_wrapper.py index 33afab4b..d053f565 100644 --- a/swarms/utils/litellm_wrapper.py +++ b/swarms/utils/litellm_wrapper.py @@ -395,20 +395,45 @@ class LiteLLM: def output_for_tools(self, response: any): if self.mcp_call is True: - out = response.choices[0].message.tool_calls[0].function - output = { - "function": { - "name": out.name, - "arguments": out.arguments, + # Check if tool_calls exists and is not None + if ( + response.choices + and response.choices[0].message + and response.choices[0].message.tool_calls + and len(response.choices[0].message.tool_calls) > 0 + ): + out = ( + response.choices[0].message.tool_calls[0].function + ) + output = { + "function": { + "name": out.name, + "arguments": out.arguments, + } + } + return output + else: + # Return a default response when no tool calls are present + return { + "function": { + "name": "no_tool_call", + "arguments": "{}", + } } - } - return output else: - out = response.choices[0].message.tool_calls - - if isinstance(out, BaseModel): - out = out.model_dump() - return out + # Check if tool_calls exists and is not None + if ( + response.choices + and response.choices[0].message + and response.choices[0].message.tool_calls + ): + out = response.choices[0].message.tool_calls + if isinstance(out, BaseModel): + out = out.model_dump() + return out + else: + # Return empty list when no tool calls are present + return [] def output_for_reasoning(self, response: any): """