Weather App
Okay, this is a complex request, but I'll provide a conceptual outline and code snippets to illustrate how you might implement a minimal MCP (Microservice Communication Protocol) server for weather data in Python, along with testing and pre-commit setup. I'll focus on clarity and structure rather than production-readiness. **Conceptual Overview** 1. **MCP Definition (Protocol Buffer):** Define the data structures and service interface using Protocol Buffers. This is the core of MCP. 2. **Server Implementation (Python):** Implement a gRPC server in Python that serves weather data based on the MCP definition. 3. **Client (Example):** A simple client to demonstrate how to request data from the server. 4. **Testing (pytest):** Write unit tests to verify the server's functionality. 5. **Pre-commit Hooks:** Configure pre-commit to run linters (e.g., `flake8`, `black`) and tests before committing code. **1. MCP Definition (weather.proto)** Create a file named `weather.proto`: ```protobuf syntax = "proto3"; package weather; service WeatherService { rpc GetWeather(WeatherRequest) returns (WeatherResponse) {} } message WeatherRequest { string city = 1; } message WeatherResponse { string city = 1; float temperature = 2; string condition = 3; } ``` **Explanation:** * `syntax = "proto3";`: Specifies the Protocol Buffer version. * `package weather;`: Defines the package name for the generated code. * `service WeatherService`: Defines the service with a single RPC method `GetWeather`. * `WeatherRequest`: The request message, containing the city name. * `WeatherResponse`: The response message, containing weather information. **2. Generate gRPC Code (Python)** You'll need the `grpcio-tools` package: ```bash pip install grpcio-tools ``` Then, compile the `.proto` file: ```bash python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. weather.proto ``` This will generate two Python files: `weather_pb2.py` (the data structures) and `weather_pb2_grpc.py` (the gRPC service definitions). **3. Server Implementation (server.py)** ```python import grpc from concurrent import futures import weather_pb2 import weather_pb2_grpc class WeatherServicer(weather_pb2_grpc.WeatherServiceServicer): def GetWeather(self, request, context): city = request.city # Simulate weather data (replace with actual data source) if city == "London": temperature = 15.0 condition = "Cloudy" elif city == "New York": temperature = 25.0 condition = "Sunny" else: temperature = 10.0 condition = "Unknown" return weather_pb2.WeatherResponse(city=city, temperature=temperature, condition=condition) def serve(): server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) weather_pb2_grpc.add_WeatherServiceServicer_to_server(WeatherServicer(), server) server.add_insecure_port('[::]:50051') # Listen on all interfaces, port 50051 server.start() server.wait_for_termination() if __name__ == '__main__': print("Starting gRPC server...") serve() ``` **Explanation:** * `WeatherServicer`: Implements the `WeatherServiceServicer` interface defined in `weather_pb2_grpc.py`. * `GetWeather`: The actual implementation of the RPC method. It receives a `WeatherRequest` and returns a `WeatherResponse`. This example uses hardcoded data for simplicity. In a real application, you'd fetch weather data from an external API or database. * `serve`: Creates a gRPC server, registers the `WeatherServicer`, and starts the server. **4. Client (client.py)** ```python import grpc import weather_pb2 import weather_pb2_grpc def run(): with grpc.insecure_channel('localhost:50051') as channel: stub = weather_pb2_grpc.WeatherServiceStub(channel) city = "London" request = weather_pb2.WeatherRequest(city=city) response = stub.GetWeather(request) print(f"Weather in {response.city}:") print(f" Temperature: {response.temperature}°C") print(f" Condition: {response.condition}") if __name__ == '__main__': run() ``` **Explanation:** * Creates a gRPC channel to connect to the server. * Creates a `WeatherServiceStub` to make RPC calls. * Sends a `WeatherRequest` for the city "London". * Prints the received `WeatherResponse`. **5. Testing (test_server.py)** Install `pytest` and `grpcio-testing`: ```bash pip install pytest grpcio-testing ``` ```python import pytest import grpc from grpc import aio from concurrent import futures import weather_pb2 import weather_pb2_grpc from server import WeatherServicer # Import your server implementation @pytest.fixture def grpc_server(): server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) weather_pb2_grpc.add_WeatherServiceServicer_to_server(WeatherServicer(), server) port = server.add_insecure_port('[::]:0') # Let the OS choose a port server.start() yield server, port # Provide the server and port to the tests server.stop(0) def test_get_weather(grpc_server): server, port = grpc_server with grpc.insecure_channel(f'localhost:{port}') as channel: stub = weather_pb2_grpc.WeatherServiceStub(channel) request = weather_pb2.WeatherRequest(city="London") response = stub.GetWeather(request) assert response.city == "London" assert response.temperature == 15.0 assert response.condition == "Cloudy" def test_get_weather_new_york(grpc_server): server, port = grpc_server with grpc.insecure_channel(f'localhost:{port}') as channel: stub = weather_pb2_grpc.WeatherServiceStub(channel) request = weather_pb2.WeatherRequest(city="New York") response = stub.GetWeather(request) assert response.city == "New York" assert response.temperature == 25.0 assert response.condition == "Sunny" def test_get_weather_unknown(grpc_server): server, port = grpc_server with grpc.insecure_channel(f'localhost:{port}') as channel: stub = weather_pb2_grpc.WeatherServiceStub(channel) request = weather_pb2.WeatherRequest(city="SomeRandomCity") response = stub.GetWeather(request) assert response.city == "SomeRandomCity" assert response.temperature == 10.0 assert response.condition == "Unknown" ``` **Explanation:** * `grpc_server` fixture: Creates and starts a gRPC server before each test and stops it afterward. It uses a dynamically assigned port to avoid conflicts. * `test_get_weather`: Tests the `GetWeather` method for a specific city ("London"). * `test_get_weather_new_york`: Tests the `GetWeather` method for a specific city ("New York"). * `test_get_weather_unknown`: Tests the `GetWeather` method for an unknown city. Run the tests: ```bash pytest ``` **6. Pre-commit Setup** Install `pre-commit`: ```bash pip install pre-commit ``` Create a `.pre-commit-config.yaml` file in the root of your project: ```yaml repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 # Use the latest stable version hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - id: check-added-large-files - repo: https://github.com/psf/black rev: 24.2.0 # Use the latest stable version hooks: - id: black - repo: https://github.com/pycqa/flake8 rev: 7.0.0 # Use the latest stable version hooks: - id: flake8 additional_dependencies: ["flake8-protobuf"] # Add protobuf support - repo: local hooks: - id: pytest name: pytest entry: pytest language: system types: [python] pass_filenames: false ``` **Explanation:** * This configuration uses several popular pre-commit hooks: * `trailing-whitespace`, `end-of-file-fixer`, `check-yaml`, `check-added-large-files`: Basic cleanup and checks. * `black`: Code formatter. * `flake8`: Linter. The `additional_dependencies` line adds support for linting Protocol Buffer-related code. * `pytest`: Runs your tests. Install the pre-commit hooks: ```bash pre-commit install ``` Now, every time you commit, pre-commit will run these checks and formatters. If any of them fail, the commit will be aborted. **Running the Example** 1. **Generate gRPC code:** `python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. weather.proto` 2. **Start the server:** `python server.py` (in a separate terminal) 3. **Run the client:** `python client.py` 4. **Run the tests:** `pytest` 5. **Commit your changes:** `git commit -m "Your commit message"` (pre-commit will run) **Important Considerations and Improvements** * **Error Handling:** The server implementation lacks proper error handling. You should handle exceptions and return appropriate gRPC status codes. * **Data Source:** The server uses hardcoded weather data. Replace this with a real data source (e.g., an API or database). * **Authentication/Authorization:** For production systems, you'll need to add authentication and authorization to secure your gRPC service. * **Logging:** Implement logging for debugging and monitoring. * **Configuration:** Use environment variables or configuration files to manage server settings (e.g., port number, data source connection details). * **Asynchronous gRPC:** Consider using `grpc.aio` for asynchronous gRPC, which can improve performance, especially for I/O-bound operations. * **Health Checks:** Implement a health check endpoint to allow monitoring systems to verify the server's availability. * **Code Generation:** Consider using a build system (e.g., `make`, `nox`) to automate the code generation process. * **Dependency Management:** Use a tool like `poetry` or `pipenv` to manage your project's dependencies. * **CI/CD:** Integrate your tests and pre-commit hooks into a CI/CD pipeline to automate the build, test, and deployment process. This comprehensive example provides a solid foundation for building a gRPC-based microservice with testing and pre-commit setup. Remember to adapt and extend it to meet the specific requirements of your application.
mindsightventures
README
天气应用
一个基于命令行和 MCP 的天气应用程序,提供全球各地当前的天气状况、预报和警报。
功能
- 获取任何地点的当前天气状况
- 获取每日天气预报
- 获取每小时天气预报
- 获取天气警报
- 通过坐标获取天气
- 自动位置检测
- 测试 API 连接
- 检查 API 密钥和订阅状态
安装
前提条件
- Python 3.12 或更高版本
- uv 包管理器
设置
-
克隆此仓库:
git clone <repository-url> cd weather-app -
在根目录中创建一个
.env文件,其中包含您的 OpenWeatherMap API 密钥:OPENWEATHER_API_KEY=your_api_key_here您可以从 OpenWeatherMap 获取 API 密钥。
-
运行安装脚本:
./scripts/install.sh对于开发设置,请使用:
./scripts/install.sh --dev
用法
运行天气应用:
./scripts/run_weather.sh
这将启动 MCP 服务器,并提供以下可用工具:
get_current_weather: 获取当前天气状况get_forecast: 获取每日天气预报get_hourly_forecast: 获取每小时天气预报get_alerts: 获取天气警报get_weather_by_coordinates: 通过坐标获取天气get_user_location: 获取您当前的位置test_api_connection: 测试 API 连接check_api_key_and_subscription: 检查您的 API 密钥和订阅
开发
代码风格和 Linting
本项目使用:
所有这些工具都在 pyproject.toml 文件中配置。
Pre-commit Hooks
我们使用 pre-commit hooks 来确保代码质量。 安装开发依赖项后,将自动设置 hooks。
要手动安装 pre-commit hooks:
uv run pre-commit install
要手动运行 pre-commit hooks:
uv run pre-commit run --all-files
测试
运行测试:
./scripts/run_tests.sh
运行并显示覆盖率:
./scripts/run_tests.sh --coverage
运行集成测试(需要 API 密钥):
./scripts/run_tests.sh --integration
运行集成测试并显示覆盖率:
./scripts/run_tests.sh --integration --coverage
创建 MCP 服务器
要使用本项目作为模板创建您自己的 MCP 服务器:
-
安装带有开发依赖项的项目:
./scripts/install.sh --dev -
创建一个新的 Python 文件,其中包含您的 MCP 服务器实现:
import os from dotenv import load_dotenv from mcp.server.fastmcp import FastMCP # 加载环境变量 load_dotenv() # 初始化 FastMCP 服务器 mcp = FastMCP("your-app-name") # 定义您的工具 @mcp.tool async def your_tool(param1: str, param2: int) -> str: """工具描述.""" # 在这里实现您的逻辑 return "Result" # 运行服务器 if __name__ == "__main__": mcp.run() -
运行您的服务器:
python your_server.py
许可证
本项目根据 MIT 许可证获得许可 - 有关详细信息,请参阅 LICENSE 文件。
推荐服务器
Crypto Price & Market Analysis MCP Server
一个模型上下文协议 (MCP) 服务器,它使用 CoinCap API 提供全面的加密货币分析。该服务器通过一个易于使用的界面提供实时价格数据、市场分析和历史趋势。 (Alternative, slightly more formal and technical translation): 一个模型上下文协议 (MCP) 服务器,利用 CoinCap API 提供全面的加密货币分析服务。该服务器通过用户友好的界面,提供实时价格数据、市场分析以及历史趋势数据。
MCP PubMed Search
用于搜索 PubMed 的服务器(PubMed 是一个免费的在线数据库,用户可以在其中搜索生物医学和生命科学文献)。 我是在 MCP 发布当天创建的,但当时正在度假。 我看到有人在您的数据库中发布了类似的服务器,但还是决定发布我的服务器。
mixpanel
连接到您的 Mixpanel 数据。 从 Mixpanel 分析查询事件、留存和漏斗数据。
Sequential Thinking MCP Server
这个服务器通过将复杂问题分解为顺序步骤来促进结构化的问题解决,支持修订,并通过完整的 MCP 集成来实现多条解决方案路径。
Nefino MCP Server
为大型语言模型提供访问德国可再生能源项目新闻和信息的能力,允许按地点、主题(太阳能、风能、氢能)和日期范围进行筛选。
Vectorize
将 MCP 服务器向量化以实现高级检索、私有深度研究、Anything-to-Markdown 文件提取和文本分块。
Mathematica Documentation MCP server
一个服务器,通过 FastMCP 提供对 Mathematica 文档的访问,使用户能够从 Wolfram Mathematica 检索函数文档和列出软件包符号。
kb-mcp-server
一个 MCP 服务器,旨在实现便携性、本地化、简易性和便利性,以支持对 txtai “all in one” 嵌入数据库进行基于语义/图的检索。任何 tar.gz 格式的 txtai 嵌入数据库都可以被加载。
Research MCP Server
这个服务器用作 MCP 服务器,与 Notion 交互以检索和创建调查数据,并与 Claude Desktop Client 集成以进行和审查调查。
Cryo MCP Server
一个API服务器,实现了模型补全协议(MCP),用于Cryo区块链数据提取,允许用户通过任何兼容MCP的客户端查询以太坊区块链数据。