Weather MCP Server

Weather MCP Server

Okay, here's an example of a simple weather MCP (Minecraft Protocol) server in Python. This is a very basic example and doesn't implement the full Minecraft protocol. It focuses on sending a custom packet to a client that's expecting weather information. **Important Considerations:** * **MCP (Minecraft Protocol) Complexity:** The actual Minecraft protocol is quite complex. This example simplifies things significantly. A real-world server would need to handle authentication, world data, player movement, and much more. * **Client-Side Mod:** This server *requires* a client-side mod (or a modified client) that knows how to interpret the custom weather packet this server sends. The standard Minecraft client won't understand it. * **Python Libraries:** This example uses the `socket` library for basic network communication and `struct` for packing data into binary format. ```python import socket import struct import time # Configuration HOST = '127.0.0.1' # Listen on localhost PORT = 25565 # Use a port (not the default Minecraft port unless you know what you're doing) WEATHER_UPDATE_INTERVAL = 5 # Seconds between weather updates def create_weather_packet(temperature, humidity, rain): """ Creates a custom weather packet. Args: temperature: Temperature value (float). humidity: Humidity value (float). rain: Rain intensity (float, 0.0 - 1.0). Returns: A bytes object representing the weather packet. """ packet_id = 0x01 # Custom packet ID (must match client-side mod) # Pack the data into a binary format packet_data = struct.pack('!bff', temperature, humidity, rain) # ! = network byte order, b = byte (packet ID), f = float # Prepend the packet ID packet = struct.pack('!b', packet_id) + packet_data # Prepend the packet length packet_length = len(packet) packet = struct.pack('!i', packet_length) + packet return packet def main(): """ Main server loop. """ server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # Allow address reuse server_socket.bind((HOST, PORT)) server_socket.listen(1) # Listen for one connection print(f"Weather MCP Server listening on {HOST}:{PORT}") conn, addr = server_socket.accept() print(f"Client connected from {addr}") try: while True: # Simulate weather data (replace with real data source) temperature = 25.5 + (time.time() % 10) - 5 # Temperature between 20.5 and 30.5 humidity = 0.6 + (time.time() % 5) / 10 # Humidity between 0.6 and 1.1 rain = 0.0 if temperature > 28 else (time.time() % 3) / 3 # Rain if temp is below 28 weather_packet = create_weather_packet(temperature, humidity, rain) try: conn.sendall(weather_packet) print(f"Sent weather update: Temp={temperature:.1f}, Humidity={humidity:.2f}, Rain={rain:.2f}") except BrokenPipeError: print("Client disconnected.") break # Exit the loop if the client disconnects time.sleep(WEATHER_UPDATE_INTERVAL) except KeyboardInterrupt: print("Server shutting down.") finally: conn.close() server_socket.close() if __name__ == "__main__": main() ``` **Explanation:** 1. **Imports:** Imports necessary libraries (`socket`, `struct`, `time`). 2. **Configuration:** Sets the host, port, and weather update interval. *Change the port if you're running a real Minecraft server on the default port (25565).* 3. **`create_weather_packet()`:** * Takes temperature, humidity, and rain intensity as input. * `packet_id = 0x01`: This is a *crucial* part. This is a custom packet ID. Your client-side mod *must* be programmed to recognize this ID and know how to interpret the data that follows. If the client doesn't know about this ID, it will likely crash or ignore the packet. * `struct.pack('!bff', ...)`: This packs the data into a binary format. * `!`: Specifies network byte order (big-endian), which is standard for network communication. * `b`: Represents a single byte (for the packet ID). * `f`: Represents a float (for temperature, humidity, and rain). * The packet length is prepended to the packet. This is important for the client to know how many bytes to read. 4. **`main()`:** * Creates a socket, binds it to the host and port, and listens for connections. * `server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)`: This allows you to quickly restart the server without waiting for the port to be released. * Accepts a connection from a client. * Enters a `while True` loop to continuously send weather updates. * **Simulates Weather Data:** The example generates random weather data. In a real application, you would get this data from a weather API or some other source. * `conn.sendall(weather_packet)`: Sends the weather packet to the client. * `time.sleep(WEATHER_UPDATE_INTERVAL)`: Waits before sending the next update. * Handles `BrokenPipeError`: This exception is raised if the client disconnects. * Handles `KeyboardInterrupt`: Allows you to gracefully shut down the server with Ctrl+C. * Closes the connection and the socket in the `finally` block. **How to Use:** 1. **Client-Side Mod:** You *must* create a client-side mod (using Forge, Fabric, or another modding framework) that: * Connects to this server on the specified host and port. * Listens for packets with the packet ID `0x01`. * Unpacks the data from the packet (using `struct.unpack('!bff', data)`) to get the temperature, humidity, and rain values. * Displays the weather information in the game or uses it to affect the game world. 2. **Run the Server:** Save the Python code as a `.py` file (e.g., `weather_server.py`) and run it from your terminal: `python weather_server.py` 3. **Run Minecraft with the Mod:** Start Minecraft with your client-side mod installed. The mod should connect to the server and start receiving weather updates. **Example Client-Side Mod (Conceptual - Forge, Simplified):** ```java // (This is a very simplified example - you'll need to adapt it to your modding framework) import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import java.net.Socket; import java.io.DataInputStream; import java.nio.ByteBuffer; @Mod(modid = "weather_mod", name = "Weather Mod", version = "1.0") public class WeatherMod { private static final String SERVER_HOST = "127.0.0.1"; private static final int SERVER_PORT = 25565; private static Socket socket; private static DataInputStream in; private float temperature = 0.0f; private float humidity = 0.0f; private float rain = 0.0f; @Mod.EventHandler public void init(FMLInitializationEvent event) { new Thread(() -> { try { socket = new Socket(SERVER_HOST, SERVER_PORT); in = new DataInputStream(socket.getInputStream()); while (true) { // Read packet length int packetLength = in.readInt(); // Read packet ID byte packetId = in.readByte(); if (packetId == 0x01) { // Read the rest of the packet data byte[] data = new byte[packetLength - 1]; in.readFully(data); ByteBuffer buffer = ByteBuffer.wrap(data); buffer.order(java.nio.ByteOrder.BIG_ENDIAN); // Network byte order temperature = buffer.getFloat(); humidity = buffer.getFloat(); rain = buffer.getFloat(); System.out.println("Received weather: Temp=" + temperature + ", Humidity=" + humidity + ", Rain=" + rain); // Update game world (e.g., change sky color, add rain particles) // This part requires more Forge-specific code } } } catch (Exception e) { e.printStackTrace(); } }).start(); } // Getter methods to access weather data from other parts of your mod public float getTemperature() { return temperature; } public float getHumidity() { return humidity; } public float getRain() { return rain; } } ``` **Important Notes about the Client Mod:** * **Threading:** The client mod uses a separate thread to connect to the server and receive data. This prevents the main game thread from blocking. * **Error Handling:** The client mod needs proper error handling (e.g., handling connection errors, invalid packet data). * **Forge/Fabric Specifics:** The example uses some basic Forge annotations. You'll need to adapt it to the specific modding framework you're using. The code to update the game world (e.g., changing sky color, adding rain particles) will be very framework-specific. * **Byte Order:** Make sure the client uses the same byte order (`java.nio.ByteOrder.BIG_ENDIAN`) as the server when unpacking the data. * **Packet Length:** The client reads the packet length first to know how many bytes to read for the rest of the packet. **Chinese Translation (Simplified):** ```chinese # 这是一个用 Python 编写的简单天气 MCP (Minecraft 协议) 服务器的例子。 # 重要注意事项: # * MCP (Minecraft 协议) 非常复杂。 这个例子大大简化了。 # * 这个服务器需要一个客户端模组(或修改过的客户端),它知道如何解释这个服务器发送的自定义天气数据包。 # * 这个例子使用 socket 库进行基本的网络通信,并使用 struct 库将数据打包成二进制格式。 import socket import struct import time # 配置 HOST = '127.0.0.1' # 监听本地主机 PORT = 25565 # 使用一个端口(除非你知道自己在做什么,否则不要使用默认的 Minecraft 端口) WEATHER_UPDATE_INTERVAL = 5 # 天气更新之间的秒数 def create_weather_packet(temperature, humidity, rain): """ 创建一个自定义天气数据包。 参数: temperature: 温度值 (浮点数)。 humidity: 湿度值 (浮点数)。 rain: 降雨强度 (浮点数, 0.0 - 1.0)。 返回值: 表示天气数据包的字节对象。 """ packet_id = 0x01 # 自定义数据包 ID(必须与客户端模组匹配) # 将数据打包成二进制格式 packet_data = struct.pack('!bff', temperature, humidity, rain) # ! = 网络字节顺序,b = 字节 (数据包 ID),f = 浮点数 # 在前面加上数据包 ID packet = struct.pack('!b', packet_id) + packet_data # 在前面加上数据包长度 packet_length = len(packet) packet = struct.pack('!i', packet_length) + packet return packet def main(): """ 主服务器循环。 """ server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 允许地址重用 server_socket.bind((HOST, PORT)) server_socket.listen(1) # 监听一个连接 print(f"天气 MCP 服务器监听在 {HOST}:{PORT}") conn, addr = server_socket.accept() print(f"客户端从 {addr} 连接") try: while True: # 模拟天气数据(用真实数据源替换) temperature = 25.5 + (time.time() % 10) - 5 # 温度在 20.5 和 30.5 之间 humidity = 0.6 + (time.time() % 5) / 10 # 湿度在 0.6 和 1.1 之间 rain = 0.0 if temperature > 28 else (time.time() % 3) / 3 # 如果温度低于 28,则下雨 weather_packet = create_weather_packet(temperature, humidity, rain) try: conn.sendall(weather_packet) print(f"发送天气更新:温度={temperature:.1f}, 湿度={humidity:.2f}, 降雨={rain:.2f}") except BrokenPipeError: print("客户端断开连接。") break # 如果客户端断开连接,则退出循环 time.sleep(WEATHER_UPDATE_INTERVAL) except KeyboardInterrupt: print("服务器正在关闭。") finally: conn.close() server_socket.close() if __name__ == "__main__": main() ``` **Key Takeaways:** * This is a *very* simplified example. A real Minecraft server is much more complex. * The client-side mod is essential. Without it, the standard Minecraft client will not understand the custom weather packets. * Pay close attention to packet IDs, data packing/unpacking, and byte order. * Use threading in your client mod to avoid blocking the main game thread. * Handle errors gracefully. This should give you a good starting point. Good luck!

jalateras

研究与数据
访问服务器

README

Weather MCP 服务器

概述

本项目实现了一个模型上下文协议 (MCP) 服务器,用于提供天气信息服务。它利用美国国家气象局 (NWS) API 获取天气警报和预报,并将它们作为工具暴露给像 Claude 这样的 MCP 客户端使用。

该服务器采用模块化架构构建,遵循 Python 项目的最佳实践,易于维护和扩展。

功能

  • 天气工具: 获取州的天气警报和特定坐标的预报
  • 系统工具: 运行 shell 命令并查看系统进程信息
  • MCP 集成: 与 Claude Desktop 等 MCP 客户端无缝集成

安装

前提条件

  • Python 3.11 或更高版本
  • uv 包管理器

设置

  1. 克隆仓库:

    git clone https://github.com/yourusername/weather.git
    cd weather
    
  2. 使用 uv 安装依赖:

    make install
    
  3. 对于开发,安装额外的依赖:

    make dev
    

使用

运行服务器

要启动 MCP 服务器:

make run

或者直接使用 uv:

uv run python -m main

连接到 Claude Desktop

  1. 更新您的 Claude Desktop 配置以包含天气服务器:
{
  "mcpServers": {
    "weather": {
      "command": "python",
      "args": ["-m", "main"],
      "cwd": "/path/to/weather"
    }
  }
}
  1. 重启 Claude Desktop 以应用更改

  2. 在 Claude Desktop 中,您现在可以从 MCP 服务器下拉菜单中选择 "weather" MCP 服务器

天气 MCP 服务器将可用于 Claude Desktop,允许您直接在对话中与天气数据交互。

示例查询

连接后,您可以询问 Claude:

  • "CA 当前的天气警报是什么?"
  • "纬度 37.7749,经度 -122.4194 的预报是什么?"
  • "我的系统上哪些进程占用的 CPU 最多?"

项目结构

weather/
├── src/
│   └── weather/
│       ├── __init__.py          # 包初始化
│       ├── server.py            # 主要服务器设置
│       ├── tools/               # 工具实现
│       │   ├── __init__.py
│       │   ├── weather_tools.py
│       │   └── system_tools.py
│       ├── resources/           # 资源实现
│       │   ├── __init__.py
│       │   └── system_resources.py
│       ├── services/            # 外部服务集成
│       │   ├── __init__.py
│       │   ├── weather_service.py
│       │   └── system_service.py
│       └── utils/               # 辅助函数
│           ├── __init__.py
│           ├── http.py
│           └── formatting.py
├── tests/                       # 测试套件
├── main.py                      # 入口点
├── pyproject.toml               # 依赖和元数据
├── Makefile                     # 构建命令
└── README.md                    # 本文件

Make 目标

该项目包含多个 make 目标,以简化开发:

目标 描述
install 使用 uv 安装项目依赖
lint 使用 uv 运行 ruff linter 并自动修复
format 使用 uv 运行 black 格式化工具
format-check 检查文件是否会被 black 重新格式化
lint-format 同时运行 linter 和格式化工具
test 使用 uv 运行 pytest 测试
clean 删除构建工件和缓存文件
outdated 使用 uv 检查过时的依赖
upgrade-deps 使用 uv 升级所有过时的依赖
run 使用 uv 启动 MCP 服务器
inspector 启动 MCP Inspector 进行测试
hooks 安装 git hooks
dev-server 在开发模式下启动 MCP 服务器
stop-server 停止 MCP 服务器和 Inspector
claude-install 在 Claude Desktop 中安装服务器
claude-uninstall 从 Claude Desktop 中卸载服务器

运行 make help 查看所有可用的目标。

与 Claude Desktop 一起使用

要将天气 MCP 服务器与 Claude Desktop 一起使用:

  1. 在 Claude Desktop 中安装服务器:
make claude-install

这将:

  • 使用 MCP CLI 在 Claude Desktop 中安装服务器
  • 以可编辑模式安装项目 (-e .)
  • 注册名称为 "weather" 的服务器
  • 配置服务器以从您的项目目录运行
  1. 重启 Claude Desktop 以应用更改

  2. 在 Claude Desktop 中,您现在可以从 MCP 服务器下拉菜单中选择 "weather" MCP 服务器

天气 MCP 服务器将可用于 Claude Desktop,允许您直接在对话中与天气数据交互。

要从 Claude Desktop 中卸载服务器:

make claude-uninstall

这将从 Claude Desktop 中删除天气 MCP 服务器配置。您需要重启 Claude 以应用更改。

开发模式

对于主动开发,并在代码更改时自动重新加载:

# 在开发模式下使用 MCP Inspector 启动服务器
make dev-server

这将:

  1. 使用 mcp dev 命令启动 MCP 服务器
  2. 以可编辑模式安装项目 (-e .)
  3. 自动启动 MCP Inspector
  4. 在您的代码更改时启用自动重新加载

MCP Inspector 将在您的 Web 浏览器中的 http://localhost:5173 上可用。

要停止服务器和 Inspector:

make stop-server

此设置非常适合迭代开发,因为当您更改代码时,服务器将自动重新加载。

Inspector 功能

MCP Inspector 允许您:

  1. 浏览工具: 查看所有可用的工具、它们的参数和文档。
  2. 调用工具: 使用自定义参数执行工具并查看结果。
  3. 浏览资源: 查看所有可用的资源及其当前值。
  4. 测试提示: 如果您的服务器提供提示模板,您可以使用不同的输入来测试它们。
  5. 查看日志: 查看 Inspector 和您的服务器之间所有交互的详细日志。

测试天气工具

使用 Inspector,您可以轻松地测试天气工具:

  1. 在 Inspector 界面中找到 get_weather_alerts 工具
  2. 在参数字段中输入一个州代码 (例如,"CA", "NY", "FL")
  3. 执行该工具并查看结果

类似地,您可以通过提供纬度和经度坐标来测试 get_forecast 工具。

测试系统工具

Inspector 还可以轻松地测试系统工具:

  1. 找到 run_shell_command 工具
  2. 在参数字段中输入一个安全的命令 (例如,"ls -la", "echo hello")
  3. 执行该工具并查看结果

使用 Inspector 调试

Inspector 对于调试特别有用:

  1. 如果工具调用失败,它会显示详细的错误消息
  2. 您可以看到确切的请求和响应有效负载
  3. 它有助于识别参数验证或工具实现的问题

有关 MCP Inspector 的更多信息,请访问 模型上下文协议文档

本地测试

您可以使用 mcp[cli] 包附带的 MCP CLI 工具在本地测试您的 MCP 服务器:

  1. 启动您的服务器:

    make run
    
  2. 在单独的终端中,使用 MCP CLI 与您的服务器交互:

    # 列出所有可用的工具
    make inspector
    
    # 调用特定的天气工具
    mcp call-tool http://localhost:8000 get_weather_alerts --args '{"state": "CA"}'
    
    # 获取天气预报
    mcp call-tool http://localhost:8000 get_forecast --args '{"latitude": 37.7749, "longitude": -122.4194}'
    
    # 列出系统资源
    mcp list-resources http://localhost:8000
    
    # 获取系统进程
    mcp get-resource http://localhost:8000 top_processes
    

如果您直接使用 uv,则可以使用以下命令运行 MCP CLI:

uv run mcp list-tools http://localhost:8000

开发

添加新工具

要向服务器添加新工具:

  1. 在适当的 tools 模块中创建一个函数
  2. 使用 @server.tool() 装饰器注册它
  3. 更新 tools/__init__.py 中的工具注册

示例:

@server.tool()
async def my_new_tool(param1: str, param2: int) -> str:
    """
    工具描述.
    
    Args:
        param1: param1 的描述
        param2: param2 的描述
        
    Returns:
        返回值描述
    """
    # 实现
    return result

添加新资源

要添加新资源:

  1. 在适当的 resources 模块中创建一个函数
  2. 使用 @server.resource() 装饰器注册它
  3. 更新 resources/__init__.py 中的资源注册

许可证

本项目采用 MIT 许可证 - 有关详细信息,请参阅 LICENSE 文件。

鸣谢

推荐服务器

Crypto Price & Market Analysis MCP Server

Crypto Price & Market Analysis MCP Server

一个模型上下文协议 (MCP) 服务器,它使用 CoinCap API 提供全面的加密货币分析。该服务器通过一个易于使用的界面提供实时价格数据、市场分析和历史趋势。 (Alternative, slightly more formal and technical translation): 一个模型上下文协议 (MCP) 服务器,利用 CoinCap API 提供全面的加密货币分析服务。该服务器通过用户友好的界面,提供实时价格数据、市场分析以及历史趋势数据。

精选
TypeScript
MCP PubMed Search

MCP PubMed Search

用于搜索 PubMed 的服务器(PubMed 是一个免费的在线数据库,用户可以在其中搜索生物医学和生命科学文献)。 我是在 MCP 发布当天创建的,但当时正在度假。 我看到有人在您的数据库中发布了类似的服务器,但还是决定发布我的服务器。

精选
Python
mixpanel

mixpanel

连接到您的 Mixpanel 数据。 从 Mixpanel 分析查询事件、留存和漏斗数据。

精选
TypeScript
Sequential Thinking MCP Server

Sequential Thinking MCP Server

这个服务器通过将复杂问题分解为顺序步骤来促进结构化的问题解决,支持修订,并通过完整的 MCP 集成来实现多条解决方案路径。

精选
Python
Nefino MCP Server

Nefino MCP Server

为大型语言模型提供访问德国可再生能源项目新闻和信息的能力,允许按地点、主题(太阳能、风能、氢能)和日期范围进行筛选。

官方
Python
Vectorize

Vectorize

将 MCP 服务器向量化以实现高级检索、私有深度研究、Anything-to-Markdown 文件提取和文本分块。

官方
JavaScript
Mathematica Documentation MCP server

Mathematica Documentation MCP server

一个服务器,通过 FastMCP 提供对 Mathematica 文档的访问,使用户能够从 Wolfram Mathematica 检索函数文档和列出软件包符号。

本地
Python
kb-mcp-server

kb-mcp-server

一个 MCP 服务器,旨在实现便携性、本地化、简易性和便利性,以支持对 txtai “all in one” 嵌入数据库进行基于语义/图的检索。任何 tar.gz 格式的 txtai 嵌入数据库都可以被加载。

本地
Python
Research MCP Server

Research MCP Server

这个服务器用作 MCP 服务器,与 Notion 交互以检索和创建调查数据,并与 Claude Desktop Client 集成以进行和审查调查。

本地
Python
Cryo MCP Server

Cryo MCP Server

一个API服务器,实现了模型补全协议(MCP),用于Cryo区块链数据提取,允许用户通过任何兼容MCP的客户端查询以太坊区块链数据。

本地
Python