diff --git a/owl/utils/mcp/mcp_servers_config.json b/owl/mcp_servers_config.json similarity index 100% rename from owl/utils/mcp/mcp_servers_config.json rename to owl/mcp_servers_config.json diff --git a/owl/run_mcp.py b/owl/run_mcp.py index 4ae556b..570a03a 100644 --- a/owl/run_mcp.py +++ b/owl/run_mcp.py @@ -134,11 +134,9 @@ async def construct_society( async def main(): - config_path = str( - Path(__file__).parent / "utils/mcp/mcp_servers_config.json" - ) + config_path = Path(__file__).parent / "mcp_servers_config.json" - mcp_toolkit = MCPToolkit(config_path=config_path) + mcp_toolkit = MCPToolkit(config_path=str(config_path)) question = ( "I'd like a academic report about Guohao Li, including his research " diff --git a/owl/utils/mcp/__init__.py b/owl/utils/mcp/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/owl/utils/mcp/servers/__init__.py b/owl/utils/mcp/servers/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/owl/utils/mcp/servers/mcp_server.py b/owl/utils/mcp/servers/mcp_server.py deleted file mode 100755 index 7f02d57..0000000 --- a/owl/utils/mcp/servers/mcp_server.py +++ /dev/null @@ -1,136 +0,0 @@ -# ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. ========= -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. ========= -from typing import Any - -import httpx -from mcp.server.fastmcp import FastMCP - -mcp = FastMCP("weather") - -NWS_API_BASE = "https://api.weather.gov" -USER_AGENT = "weather-app/1.0" - - -async def make_nws_request(url: str) -> dict[str, Any] | None: - r"""Make a request to the NWS API with proper error handling.""" - headers = {"User-Agent": USER_AGENT, "Accept": "application/geo+json"} - async with httpx.AsyncClient() as client: - try: - response = await client.get(url, headers=headers, timeout=30.0) - response.raise_for_status() - return response.json() - except Exception: - return None - - -def format_alert(feature: dict) -> str: - r"""Format an alert feature into a readable string.""" - props = feature["properties"] - return f""" -Event: {props.get('event', 'Unknown')} -Area: {props.get('areaDesc', 'Unknown')} -Severity: {props.get('severity', 'Unknown')} -Description: {props.get('description', 'No description available')} -Instructions: {props.get('instruction', 'No specific instructions provided')} -""" - - -@mcp.tool() -async def get_alerts(state: str) -> str: - r"""Get weather alerts for a US state. - - Args: - state: Two-letter US state code (e.g. CA, NY) - """ - url = f"{NWS_API_BASE}/alerts/active/area/{state}" - data = await make_nws_request(url) - - if not data or "features" not in data: - return "Unable to fetch alerts or no alerts found." - - if not data["features"]: - return "No active alerts for this state." - - alerts = [format_alert(feature) for feature in data["features"]] - return "\n---\n".join(alerts) - - -@mcp.tool() -async def get_forecast(latitude: float, longitude: float) -> str: - r"""Get weather forecast for a location. - - Args: - latitude: Latitude of the location - longitude: Longitude of the location - """ - # First get the forecast grid endpoint - points_url = f"{NWS_API_BASE}/points/{latitude},{longitude}" - points_data = await make_nws_request(points_url) - - if not points_data: - return "Unable to fetch forecast data for this location." - - # Get the forecast URL from the points response - forecast_url = points_data["properties"]["forecast"] - forecast_data = await make_nws_request(forecast_url) - - if not forecast_data: - return "Unable to fetch detailed forecast." - - # Format the periods into a readable forecast - periods = forecast_data["properties"]["periods"] - forecasts = [] - for period in periods[:5]: # Only show next 5 periods - forecast = f""" -{period['name']}: -Temperature: {period['temperature']}°{period['temperatureUnit']} -Wind: {period['windSpeed']} {period['windDirection']} -Forecast: {period['detailedForecast']} -""" - forecasts.append(forecast) - - return "\n---\n".join(forecasts) - - -def main(transport: str = "stdio"): - r"""Weather MCP Server - - This server provides weather-related functionalities implemented via the Model Context Protocol (MCP). - It demonstrates how to establish interactions between AI models and external tools using MCP. - - The server supports two modes of operation: - - 1. stdio mode (default): - - - Communicates with clients via standard input/output streams, ideal for local command-line usage. - - - Example usage: python mcp_server.py [--transport stdio] - - 2. SSE mode (Server-Sent Events): - - - Communicates with clients over HTTP using server-sent events, suitable for persistent network connections. - - - Runs by default at http://127.0.0.1:8000. - - - Example usage: python mcp_server.py --transport sse - """ # noqa: E501 - if transport == 'stdio': - mcp.run(transport='stdio') - elif transport == 'sse': - mcp.run(transport='sse') - - -if __name__ == "__main__": - # Hardcoded to use stdio transport mode - main("stdio")