MCP-ChatBot
Okay, here's a simple example of an MCP (Minecraft Coder Pack) client-server setup, focusing on the core concepts and using simplified code for clarity. This example demonstrates a basic message exchange. Keep in mind that a real-world Minecraft mod would be significantly more complex. **Important Considerations:** * **MCP Setup:** This assumes you have a working MCP development environment set up. This is *essential* before you can run any of this code. Follow the official MCP documentation for your Minecraft version. * **Minecraft Forge:** You'll need Minecraft Forge to create mods. Make sure you have the correct Forge version for your MCP version. * **Simplified:** This is a *very* simplified example. It doesn't handle error conditions, complex data, or proper Minecraft threading. It's meant to illustrate the basic structure. * **Networking:** Minecraft Forge provides its own networking system, which is what you should use for real mods. This example uses standard Java sockets for simplicity, but it's not recommended for production mods. **1. Common Code (Shared between Client and Server)** Create a class to hold constants and shared data. This helps keep things organized. ```java // CommonConstants.java public class CommonConstants { public static final String MOD_ID = "simplemcp"; public static final String MOD_NAME = "Simple MCP Mod"; public static final String MOD_VERSION = "1.0"; public static final int SERVER_PORT = 12345; // Choose a port public static final String MESSAGE_TO_SERVER = "Hello from the client!"; public static final String MESSAGE_FROM_SERVER = "Hello from the server!"; } ``` **2. Server-Side (Minecraft Server Mod)** Create a class that will run on the Minecraft server. ```java // ServerProxy.java (or ServerSide.java, etc.) import java.io.*; import java.net.*; public class ServerProxy { public void init() { // Server-side initialization code here (e.g., registering commands, event handlers) System.out.println("ServerProxy init"); startServer(); } private void startServer() { new Thread(() -> { // Run the server in a separate thread try (ServerSocket serverSocket = new ServerSocket(CommonConstants.SERVER_PORT)) { System.out.println("Server started on port " + CommonConstants.SERVER_PORT); while (true) { // Keep listening for connections try (Socket clientSocket = serverSocket.accept(); PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) { System.out.println("Client connected: " + clientSocket.getInetAddress().getHostAddress()); String inputLine = in.readLine(); System.out.println("Received from client: " + inputLine); out.println(CommonConstants.MESSAGE_FROM_SERVER); // Send a response System.out.println("Sent to client: " + CommonConstants.MESSAGE_FROM_SERVER); } catch (IOException e) { System.err.println("Exception handling client: " + e.getMessage()); } } } catch (IOException e) { System.err.println("Could not listen on port " + CommonConstants.SERVER_PORT + ": " + e.getMessage()); } }).start(); } } ``` **3. Client-Side (Minecraft Client Mod)** Create a class that will run on the Minecraft client. ```java // ClientProxy.java (or ClientSide.java, etc.) import java.io.*; import java.net.*; public class ClientProxy { public void init() { // Client-side initialization code here (e.g., registering keybindings, event handlers) System.out.println("ClientProxy init"); startClient(); } private void startClient() { new Thread(() -> { // Run the client in a separate thread try (Socket socket = new Socket("localhost", CommonConstants.SERVER_PORT); // Connect to the server PrintWriter out = new PrintWriter(socket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) { out.println(CommonConstants.MESSAGE_TO_SERVER); // Send a message System.out.println("Sent to server: " + CommonConstants.MESSAGE_TO_SERVER); String response = in.readLine(); System.out.println("Received from server: " + response); } catch (UnknownHostException e) { System.err.println("Don't know about host localhost"); } catch (IOException e) { System.err.println("Couldn't get I/O for the connection to localhost: " + e.getMessage()); } }).start(); } } ``` **4. Main Mod Class** This is the core class that Forge uses to load your mod. ```java // SimpleMCPMod.java import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.SidedProxy; @Mod(modid = CommonConstants.MOD_ID, name = CommonConstants.MOD_NAME, version = CommonConstants.MOD_VERSION) public class SimpleMCPMod { @SidedProxy(clientSide = "ClientProxy", serverSide = "ServerProxy") public static ServerProxy proxy; // Changed to ServerProxy @Mod.EventHandler public void preInit(FMLPreInitializationEvent event) { // Pre-initialization code (e.g., configuration loading) } @Mod.EventHandler public void init(FMLInitializationEvent event) { // Initialization code (e.g., registering blocks, items, recipes) proxy.init(); // Call the init method of the appropriate proxy } } ``` **5. `mcmod.info` (Required)** Create a `mcmod.info` file in the root of your mod's source directory (usually `src/main/resources`). This file tells Minecraft about your mod. ```json [ { "modid": "simplemcp", "name": "Simple MCP Mod", "description": "A simple example mod demonstrating client-server communication.", "version": "1.0", "mcversion": "1.12.2", // Or your Minecraft version "authorList": ["Your Name"], "credits": "MCP, Forge, and you!", "url": "" } ] ``` **How to Run:** 1. **MCP Setup:** Ensure your MCP environment is correctly set up for your Minecraft version. 2. **Forge Installation:** Make sure Forge is installed in your development environment. 3. **Code Placement:** Place the Java files in the correct package structure within your `src/main/java` directory. Place the `mcmod.info` file in `src/main/resources`. 4. **Recompile:** Recompile your mod using the MCP commands (e.g., `gradlew build`). 5. **Run Minecraft:** Run Minecraft from your development environment (using the MCP run configurations). Make sure you run both the client and the server. 6. **Check Logs:** Look at the Minecraft client and server logs (usually in the `logs` directory) to see the output from the `System.out.println` statements. You should see the messages being exchanged. **Explanation:** * **`CommonConstants`:** Holds shared information like the mod ID, name, version, and the port number for the server. * **`ServerProxy`:** This class runs on the *server* side. It creates a `ServerSocket` to listen for incoming connections on the specified port. When a client connects, it reads a message from the client and sends a response. The server runs in a separate thread to avoid blocking the main Minecraft server thread. * **`ClientProxy`:** This class runs on the *client* side. It creates a `Socket` to connect to the server. It sends a message to the server and then waits for a response. The client also runs in a separate thread. * **`SimpleMCPMod`:** This is the main mod class. The `@Mod` annotation tells Forge that this is a mod. The `@SidedProxy` annotation tells Forge to load either the `ClientProxy` or the `ServerProxy` depending on whether the code is running on the client or the server. The `init` method is called during the Minecraft initialization process. * **`mcmod.info`:** Provides metadata about your mod. **Important Notes:** * **Threading:** Using `new Thread(() -> ...).start()` is a basic way to handle networking in a separate thread. In a real Minecraft mod, you should use Forge's built-in threading mechanisms for better integration with the game. * **Error Handling:** The error handling in this example is very basic. You should add more robust error handling to catch exceptions and prevent crashes. * **Forge Networking:** For a real mod, *use Forge's networking system*. It provides a more reliable and efficient way to communicate between the client and the server. Look into `SimpleNetworkWrapper` and message handlers. * **Security:** Be very careful about what data you send between the client and the server. Never trust data from the client. Validate all data on the server side to prevent exploits. * **Synchronization:** If you are modifying Minecraft data (e.g., player inventories, world data) from the networking threads, you will need to use proper synchronization to avoid race conditions and data corruption. Use `Minecraft.getMinecraft().addScheduledTask()` on the client and `MinecraftServer.addScheduledTask()` on the server to execute code on the main thread. **Chinese Translation (Simplified Chinese):** 好的,这是一个简单的 MCP (Minecraft Coder Pack) 客户端-服务器设置的例子,重点在于核心概念,并使用简化的代码以求清晰。 这个例子演示了一个基本的消息交换。 请记住,一个真实的 Minecraft Mod 会复杂得多。 **重要注意事项:** * **MCP 设置:** 这假设你已经设置了一个可用的 MCP 开发环境。 这是运行任何这些代码的*必要条件*。 请按照你的 Minecraft 版本的官方 MCP 文档进行操作。 * **Minecraft Forge:** 你需要 Minecraft Forge 来创建 Mod。 确保你拥有适用于你的 MCP 版本的正确 Forge 版本。 * **简化:** 这是一个*非常*简化的例子。 它不处理错误情况、复杂数据或正确的 Minecraft 线程处理。 它的目的是说明基本结构。 * **网络:** Minecraft Forge 提供了自己的网络系统,这才是你应该用于真实 Mod 的。 这个例子为了简单起见使用了标准的 Java 套接字,但不建议用于生产 Mod。 **1. 通用代码(客户端和服务器之间共享)** 创建一个类来保存常量和共享数据。 这有助于保持组织性。 ```java // CommonConstants.java public class CommonConstants { public static final String MOD_ID = "simplemcp"; public static final String MOD_NAME = "Simple MCP Mod"; public static final String MOD_VERSION = "1.0"; public static final int SERVER_PORT = 12345; // 选择一个端口 public static final String MESSAGE_TO_SERVER = "来自客户端的问候!"; public static final String MESSAGE_FROM_SERVER = "来自服务器的问候!"; } ``` **2. 服务器端(Minecraft 服务器 Mod)** 创建一个将在 Minecraft 服务器上运行的类。 ```java // ServerProxy.java (或 ServerSide.java 等) import java.io.*; import java.net.*; public class ServerProxy { public void init() { // 服务器端初始化代码(例如,注册命令、事件处理程序) System.out.println("ServerProxy init"); startServer(); } private void startServer() { new Thread(() -> { // 在单独的线程中运行服务器 try (ServerSocket serverSocket = new ServerSocket(CommonConstants.SERVER_PORT)) { System.out.println("服务器在端口 " + CommonConstants.SERVER_PORT + " 上启动"); while (true) { // 持续监听连接 try (Socket clientSocket = serverSocket.accept(); PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) { System.out.println("客户端已连接: " + clientSocket.getInetAddress().getHostAddress()); String inputLine = in.readLine(); System.out.println("从客户端收到: " + inputLine); out.println(CommonConstants.MESSAGE_FROM_SERVER); // 发送响应 System.out.println("发送到客户端: " + CommonConstants.MESSAGE_FROM_SERVER); } catch (IOException e) { System.err.println("处理客户端时发生异常: " + e.getMessage()); } } } catch (IOException e) { System.err.println("无法监听端口 " + CommonConstants.SERVER_PORT + ": " + e.getMessage()); } }).start(); } } ``` **3. 客户端(Minecraft 客户端 Mod)** 创建一个将在 Minecraft 客户端上运行的类。 ```java // ClientProxy.java (或 ClientSide.java 等) import java.io.*; import java.net.*; public class ClientProxy { public void init() { // 客户端初始化代码(例如,注册按键绑定、事件处理程序) System.out.println("ClientProxy init"); startClient(); } private void startClient() { new Thread(() -> { // 在单独的线程中运行客户端 try (Socket socket = new Socket("localhost", CommonConstants.SERVER_PORT); // 连接到服务器 PrintWriter out = new PrintWriter(socket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) { out.println(CommonConstants.MESSAGE_TO_SERVER); // 发送消息 System.out.println("发送到服务器: " + CommonConstants.MESSAGE_TO_SERVER); String response = in.readLine(); System.out.println("从服务器收到: " + response); } catch (UnknownHostException e) { System.err.println("不知道主机 localhost"); } catch (IOException e) { System.err.println("无法获取到 localhost 的连接的 I/O: " + e.getMessage()); } }).start(); } } ``` **4. 主 Mod 类** 这是 Forge 用于加载你的 Mod 的核心类。 ```java // SimpleMCPMod.java import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.SidedProxy; @Mod(modid = CommonConstants.MOD_ID, name = CommonConstants.MOD_NAME, version = CommonConstants.MOD_VERSION) public class SimpleMCPMod { @SidedProxy(clientSide = "ClientProxy", serverSide = "ServerProxy") public static ServerProxy proxy; // 更改为 ServerProxy @Mod.EventHandler public void preInit(FMLPreInitializationEvent event) { // 预初始化代码(例如,配置加载) } @Mod.EventHandler public void init(FMLInitializationEvent event) { // 初始化代码(例如,注册方块、物品、配方) proxy.init(); // 调用相应代理的 init 方法 } } ``` **5. `mcmod.info` (必需)** 在你的 Mod 的源目录的根目录(通常是 `src/main/resources`)中创建一个 `mcmod.info` 文件。 此文件告诉 Minecraft 关于你的 Mod 的信息。 ```json [ { "modid": "simplemcp", "name": "Simple MCP Mod", "description": "一个简单的示例 Mod,演示客户端-服务器通信。", "version": "1.0", "mcversion": "1.12.2", // 或你的 Minecraft 版本 "authorList": ["你的名字"], "credits": "MCP, Forge, 和你!", "url": "" } ] ``` **如何运行:** 1. **MCP 设置:** 确保你的 MCP 环境已为你的 Minecraft 版本正确设置。 2. **Forge 安装:** 确保 Forge 已安装在你的开发环境中。 3. **代码放置:** 将 Java 文件放置在 `src/main/java` 目录中的正确包结构中。 将 `mcmod.info` 文件放置在 `src/main/resources` 中。 4. **重新编译:** 使用 MCP 命令重新编译你的 Mod(例如,`gradlew build`)。 5. **运行 Minecraft:** 从你的开发环境运行 Minecraft(使用 MCP 运行配置)。 确保你同时运行客户端和服务器。 6. **检查日志:** 查看 Minecraft 客户端和服务器日志(通常在 `logs` 目录中)以查看 `System.out.println` 语句的输出。 你应该看到消息正在交换。 **解释:** * **`CommonConstants`:** 保存共享信息,例如 Mod ID、名称、版本和服务器的端口号。 * **`ServerProxy`:** 此类在*服务器*端运行。 它创建一个 `ServerSocket` 以侦听指定端口上的传入连接。 当客户端连接时,它从客户端读取消息并发送响应。 服务器在单独的线程中运行,以避免阻塞主 Minecraft 服务器线程。 * **`ClientProxy`:** 此类在*客户端*端运行。 它创建一个 `Socket` 以连接到服务器。 它向服务器发送消息,然后等待响应。 客户端也在单独的线程中运行。 * **`SimpleMCPMod`:** 这是主 Mod 类。 `@Mod` 注释告诉 Forge 这是一个 Mod。 `@SidedProxy` 注释告诉 Forge 根据代码是在客户端还是服务器上运行来加载 `ClientProxy` 或 `ServerProxy`。 `init` 方法在 Minecraft 初始化过程中被调用。 * **`mcmod.info`:** 提供关于你的 Mod 的元数据。 **重要提示:** * **线程处理:** 使用 `new Thread(() -> ...).start()` 是一种在单独的线程中处理网络的基本方法。 在真实的 Minecraft Mod 中,你应该使用 Forge 的内置线程机制,以便更好地与游戏集成。 * **错误处理:** 此示例中的错误处理非常基本。 你应该添加更强大的错误处理来捕获异常并防止崩溃。 * **Forge 网络:** 对于真实的 Mod,*使用 Forge 的网络系统*。 它提供了一种更可靠和高效的方式来在客户端和服务器之间进行通信。 查找 `SimpleNetworkWrapper` 和消息处理程序。 * **安全性:** 非常小心你在客户端和服务器之间发送的数据。 永远不要信任来自客户端的数据。 在服务器端验证所有数据以防止漏洞利用。 * **同步:** 如果你要从网络线程修改 Minecraft 数据(例如,玩家库存、世界数据),你将需要使用适当的同步来避免竞争条件和数据损坏。 在客户端上使用 `Minecraft.getMinecraft().addScheduledTask()`,在服务器上使用 `MinecraftServer.addScheduledTask()` 以在主线程上执行代码。 This translation should be helpful. Remember to adapt the code and comments to your specific needs and Minecraft version. Good luck!
muralianand12345
README
MCP-ChatBot
一个多功能的聊天机器人应用程序,使用 MCP(模块化能力协议)与多个服务后端进行交互。
概述
MCP-ChatBot 是一个容器化的应用程序,演示了如何使用模块化能力协议 (MCP) 来实现 LLM 与外部服务的交互。此实现包括一个天气服务后端和一个基于 Streamlit 的前端,允许用户通过自然语言查询天气信息。
特性
- 容器化架构: MCP 服务器和客户端应用程序的独立容器
- 天气服务集成: 使用 WeatherAPI 的实时天气数据
- Streamlit UI: 简洁、响应式的用户界面,用于与聊天机器人交互
- 可扩展设计: 随时可以添加更多 MCP 服务器以获得更多功能
- GPT-4o 集成: 由 OpenAI 的 GPT-4o 模型驱动,用于自然语言理解
架构
该应用程序由两个主要组件组成:
- MCP 服务器: 一个基于 FastMCP 的服务,用于处理天气数据检索
- Streamlit 客户端: 一个基于 Web 的 UI,用于与聊天机器人交互
快速开始
前提条件
- Docker 和 Docker Compose
- WeatherAPI 密钥(在 WeatherAPI 注册)
- OpenAI API 密钥(在 OpenAI 注册)
安装
- 克隆存储库:
git clone https://github.com/yourusername/MCP-ChatBot.git
cd MCP-ChatBot
- 基于示例创建一个
.env文件:
cp .env.example .env
- 编辑
.env文件并添加您的 API 密钥:
PYTHONUNBUFFERED=1
OPENAI_API_KEY=your_openai_api_key_here
WEATHER_API_KEY=your_weather_api_key_here
- 使用 Docker Compose 启动应用程序:
docker-compose up --build
- 在以下地址访问 Streamlit UI:
http://localhost:8501
用法
应用程序运行后,您可以通过 Streamlit 界面与聊天机器人交互:
- 在文本输入中键入有关天气的自然语言查询
- 示例:
- "纽约的天气怎么样?"
- "东京现在有多热?"
- "告诉我伦敦的天气"
扩展应用程序
添加新的 MCP 服务器
- 在
servers目录中创建一个新的服务器文件 - 将新服务添加到
docker-compose.yml文件 - 更新 client.py 以在代理配置中包含新服务器
在 client.py 中添加新服务器的示例:
server_1 = MCPServerHTTP(url="http://mcp_server:8001/sse")
server_2 = MCPServerHTTP(url="http://new_server:8002/sse") # 新服务器
return Agent("openai:gpt-4o", mcp_servers=[server_1, server_2])
开发
项目结构
MCP-ChatBot/
├── .env.example # 示例环境变量
├── .gitignore # Git 忽略文件
├── client.py # Streamlit 客户端应用程序
├── docker-compose.yml # Docker Compose 配置
├── Dockerfile.client # Streamlit 客户端的 Dockerfile
├── Dockerfile.server # MCP 服务器的 Dockerfile
├── LICENSE # MIT 许可证
├── README.md # 项目文档
└── servers/ # MCP 服务器实现
└── server.py # 天气服务实现
技术栈
- FastMCP: 用于创建 MCP 服务器的框架
- Streamlit: 用于 UI 的 Web 框架
- Pydantic-AI: 用于 LLM 交互的代理系统
- Docker: 容器化平台
- OpenAI GPT-4o: 用于自然语言处理的 LLM
故障排除
常见问题
-
连接失败: 确保所有服务都已启动并正在运行。 客户端具有重试机制,但如果失败,请重新启动应用程序。
-
API 密钥错误: 验证您是否已将有效的 API 密钥添加到
.env文件。 -
Docker 网络问题: 如果容器无法通信,请检查 Docker 网络配置并确保服务名称在代码中匹配。
许可证
该项目根据 MIT 许可证获得许可 - 有关详细信息,请参阅 LICENSE 文件。
致谢
- FastMCP 用于 MCP 服务器实现
- Streamlit 用于前端框架
- WeatherAPI 用于天气数据
由 Murali Anand © 2025 创建
推荐服务器
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
MCP Package Docs Server
促进大型语言模型高效访问和获取 Go、Python 和 NPM 包的结构化文档,通过多语言支持和性能优化来增强软件开发。
Claude Code MCP
一个实现了 Claude Code 作为模型上下文协议(Model Context Protocol, MCP)服务器的方案,它可以通过标准化的 MCP 接口来使用 Claude 的软件工程能力(代码生成、编辑、审查和文件操作)。
@kazuph/mcp-taskmanager
用于任务管理的模型上下文协议服务器。它允许 Claude Desktop(或任何 MCP 客户端)在基于队列的系统中管理和执行任务。
mermaid-mcp-server
一个模型上下文协议 (MCP) 服务器,用于将 Mermaid 图表转换为 PNG 图像。
Jira-Context-MCP
MCP 服务器向 AI 编码助手(如 Cursor)提供 Jira 工单信息。
Linear MCP Server
一个模型上下文协议(Model Context Protocol)服务器,它与 Linear 的问题跟踪系统集成,允许大型语言模型(LLM)通过自然语言交互来创建、更新、搜索和评论 Linear 问题。
Sequential Thinking MCP Server
这个服务器通过将复杂问题分解为顺序步骤来促进结构化的问题解决,支持修订,并通过完整的 MCP 集成来实现多条解决方案路径。
Curri MCP Server
通过管理文本笔记、提供笔记创建工具以及使用结构化提示生成摘要,从而实现与 Curri API 的交互。