MCP Starter Project

MCP Starter Project

Okay, here's a breakdown of how to set up an MCP (Mod Configuration Protocol) server and client, along with explanations and considerations: **Understanding MCP (Mod Configuration Protocol)** MCP is a protocol used in Minecraft modding to allow mods to communicate configuration information between the server and the client. This is particularly useful for: * **Synchronizing Configuration:** Ensuring that both the server and client are using the same settings for a mod. This prevents inconsistencies and potential errors. * **Server-Side Configuration:** Allowing the server administrator to control certain aspects of a mod's behavior, even for clients. * **Dynamic Configuration:** Enabling mods to change their behavior based on server-side settings. **General Steps (Conceptual)** The exact implementation of MCP varies depending on the modding framework you're using (Forge, Fabric, etc.) and the specific mod. However, the general steps are: 1. **Mod Implementation:** * **Server-Side:** The mod needs to have code that defines the configuration options it wants to synchronize. This code will typically: * Define the configuration options (e.g., using a configuration file or a data structure). * Implement logic to send these configuration options to connected clients. * Handle changes to the configuration on the server. * **Client-Side:** The mod needs to have code that: * Receives the configuration options from the server. * Applies these options to the mod's behavior. * Potentially allows the client to override certain options (if the mod allows it). 2. **Networking:** * MCP relies on a networking channel between the server and the client. This channel is used to send the configuration data. * The mod needs to register a channel with the modding framework (Forge, Fabric) and define how data is serialized and deserialized for transmission. 3. **Configuration Management:** * The mod needs a way to store and manage the configuration options. This could involve: * Configuration files (e.g., `.cfg` files). * In-memory data structures. * Databases (for more complex configurations). **Example (Conceptual - Forge)** This is a simplified example to illustrate the concepts. The actual code will be more complex. **Server-Side (Example - Forge)** ```java import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLServerStartingEvent; import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; import net.minecraftforge.fml.relauncher.Side; @Mod(modid = "mymod", name = "My Mod", version = "1.0") public class MyMod { public static SimpleNetworkWrapper network; @Mod.EventHandler public void serverStarting(FMLServerStartingEvent event) { network = NetworkRegistry.INSTANCE.newSimpleChannel("mymod_channel"); network.registerMessage(ConfigMessage.Handler.class, ConfigMessage.class, 0, Side.CLIENT); // Register message for client // Load configuration from file (example) MyConfig.loadConfig(); // Send config to all players when they join (example) event.getServer().getPlayerList().addListener(new ServerPlayerListListener()); } public static class MyConfig { public static int myValue = 10; // Example config value public static void loadConfig() { // Load from config file (implementation omitted) // Example: myValue = ConfigHandler.getInt("myValue", 10); } } } // Message class to send config data public class ConfigMessage implements IMessage { public int myValue; public ConfigMessage() {} // Required empty constructor public ConfigMessage(int myValue) { this.myValue = myValue; } @Override public void fromBytes(ByteBuf buf) { myValue = buf.readInt(); } @Override public void toBytes(ByteBuf buf) { buf.writeInt(myValue); } public static class Handler implements IMessageHandler<ConfigMessage, IMessage> { @Override public IMessage onMessage(ConfigMessage message, MessageContext ctx) { // This is executed on the CLIENT side Minecraft.getMinecraft().addScheduledTask(() -> { MyModClient.myValue = message.myValue; // Update client-side config }); return null; } } } // Listener to send config to players when they join public class ServerPlayerListListener implements IPlayerListListener { @Override public void playerLoggedOut(EntityPlayerMP player) {} @Override public void playerLoggedOut(ITextComponent chatComponent) {} @Override public void playerLoggedIn(EntityPlayerMP player) { // Send the config to the player MyMod.network.sendTo(new ConfigMessage(MyMod.MyConfig.myValue), player); } @Override public void playerLoggedIn(ITextComponent chatComponent) {} } ``` **Client-Side (Example - Forge)** ```java import net.minecraft.client.Minecraft; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLInitializationEvent; @Mod(modid = "mymod_client", name = "My Mod Client", version = "1.0", clientSideOnly = true) public class MyModClient { public static int myValue = 0; // Default value @Mod.EventHandler public void init(FMLInitializationEvent event) { // No need to register the channel here, it's already registered on the server. // The ConfigMessage.Handler will be executed when the message is received. } } ``` **Explanation of the Forge Example:** * **`SimpleNetworkWrapper`:** Forge's class for managing network channels. * **`registerMessage`:** Registers a message type (`ConfigMessage`) with the network channel. It specifies the handler class, the message class, a message ID, and the side (client or server) where the handler should run. * **`ConfigMessage`:** A class that implements `IMessage`. It contains the data you want to send (in this case, `myValue`). It also has `fromBytes` and `toBytes` methods to serialize and deserialize the data. * **`ConfigMessage.Handler`:** A class that implements `IMessageHandler`. This is where you handle the received message. In this example, it updates the client-side `myValue` with the value received from the server. **Important:** The handler runs on the *client* side. You need to use `Minecraft.getMinecraft().addScheduledTask()` to ensure that the update happens on the main client thread. * **`ServerPlayerListListener`:** A listener that is triggered when a player joins the server. It sends the current server-side configuration to the newly joined player. * **`sendTo`:** Sends the `ConfigMessage` to a specific player. **Key Considerations:** * **Modding Framework:** The specific classes and methods you use will depend on the modding framework you're using (Forge, Fabric, etc.). Refer to the documentation for your framework. * **Message IDs:** Each message type needs a unique ID. These IDs are used to identify the message when it's received. * **Serialization:** You need to carefully serialize and deserialize the data you're sending. Use the `ByteBuf` class to read and write data. * **Thread Safety:** Minecraft is a multi-threaded environment. Make sure your code is thread-safe, especially when updating client-side data. Use `Minecraft.getMinecraft().addScheduledTask()` to execute code on the main client thread. * **Configuration Files:** Use a configuration library (e.g., Forge's configuration system) to manage your configuration files. * **Error Handling:** Implement proper error handling to catch exceptions and prevent crashes. * **Security:** Be careful about what data you send over the network. Don't send sensitive information. **Fabric Example (Conceptual)** Fabric uses a different approach to networking. Here's a conceptual outline: ```java import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.fabricmc.fabric.api.networking.v1.ClientPlayNetworking; import net.minecraft.util.Identifier; import net.minecraft.network.PacketByteBuf; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.client.MinecraftClient; public class MyMod implements ModInitializer { public static final String MOD_ID = "mymod"; public static final Identifier CONFIG_SYNC_ID = new Identifier(MOD_ID, "config_sync"); public static int myValue = 10; // Example config value @Override public void onInitialize() { // Server-side ServerPlayNetworking.registerGlobalReceiver(CONFIG_SYNC_ID, (server, player, handler, buf, responseSender) -> { // This is executed on the SERVER thread int receivedValue = buf.readInt(); server.execute(() -> { // Update server-side config (if needed) // MyMod.myValue = receivedValue; // Example }); }); // Client-side ClientPlayNetworking.registerGlobalReceiver(CONFIG_SYNC_ID, (client, handler, buf, responseSender) -> { // This is executed on the CLIENT thread int receivedValue = buf.readInt(); client.execute(() -> { // Update client-side config MyModClient.myValue = receivedValue; }); }); } // Method to send config to a player (server-side) public static void sendConfigToPlayer(ServerPlayerEntity player) { PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer()); buf.writeInt(MyMod.myValue); ServerPlayNetworking.send(player, CONFIG_SYNC_ID, buf); } } // Client-side class public class MyModClient { public static int myValue = 0; } ``` **Explanation of the Fabric Example:** * **`Identifier`:** Used to uniquely identify the network channel. * **`ServerPlayNetworking.registerGlobalReceiver`:** Registers a handler for incoming packets on the server. * **`ClientPlayNetworking.registerGlobalReceiver`:** Registers a handler for incoming packets on the client. * **`PacketByteBuf`:** Fabric's equivalent of Forge's `ByteBuf`. Used for serializing and deserializing data. * **`server.execute()` and `client.execute()`:** Used to execute code on the main server or client thread, respectively. **Steps to Set Up (General):** 1. **Set up your mod development environment:** Install the appropriate modding framework (Forge, Fabric) and set up your IDE (IntelliJ IDEA, Eclipse). 2. **Create your mod project:** Create a new mod project using the framework's tools. 3. **Define your configuration options:** Decide what configuration options you want to synchronize. 4. **Implement the server-side code:** Implement the code to load the configuration, register the network channel, and send the configuration to clients. 5. **Implement the client-side code:** Implement the code to receive the configuration and apply it to the mod's behavior. 6. **Test your mod:** Test your mod in a single-player and multiplayer environment to ensure that the configuration is synchronized correctly. **Important Notes:** * **Refer to the documentation:** The documentation for your modding framework is your best resource for detailed information and examples. * **Start simple:** Start with a simple configuration option and gradually add more complexity. * **Debug carefully:** Use debugging tools to identify and fix any issues. This information should give you a good starting point for setting up an MCP server and client. Remember to adapt the code to your specific needs and the modding framework you're using. Good luck!

sharmatriloknath

开发者工具
访问服务器

README

MCP 启动项目

什么是 MCP?

模型上下文协议 (MCP) 是一个用于构建可以与外部工具和 API 交互的 AI 应用程序的标准。它由两个主要组件组成:

  1. MCP 服务器: 一个 Python 服务,用于定义和暴露可以被 AI 模型调用的工具/函数
  2. MCP 客户端: 一个 TypeScript/JavaScript 客户端,用于连接到 MCP 服务器并管理 AI 模型和工具之间的交互

项目结构

mcp_starter/
├── mcp-server/           # Python MCP 服务器实现
│   ├── main.py          # 带有文档搜索工具的服务器
│   └── pyproject.toml   # Python 依赖
└── mcp-clients/         # TypeScript MCP 客户端实现
    ├── index.ts         # 带有 HuggingFace 集成的 Express 服务器
    └── package.json     # Node.js 依赖

快速开始

前提条件

设置服务器

  1. 创建一个 Python 虚拟环境并激活它:
cd mcp-server
python -m venv .venv
# 在 Windows 上
.venv\Scripts\activate
  1. 安装依赖:
pip install -e .
  1. mcp-server 目录中创建一个 .env 文件:
SERPER_API_KEY=your_serper_api_key_here

设置客户端

  1. 安装 Node.js 依赖:
cd mcp-clients
npm install
  1. mcp-clients 目录中创建一个 .env 文件:
HUGGINGFACE_API_KEY=your_huggingface_api_key_here
  1. 构建 TypeScript 代码:
npm run build

运行应用程序

  1. 启动 MCP 服务器:
cd mcp-server
python main.py
  1. 在一个新的终端中,启动客户端服务器:
cd mcp-clients
node build/index.js ../mcp-server/main.py

使用 API

客户端暴露了两个端点:

  • 健康检查: GET http://localhost:3000/health
  • 聊天: POST http://localhost:3000/chat

聊天请求示例:

{
  "query": "Search the langchain docs for RAG",
  "sessionId": "user123"
}

功能特性

  • 文档搜索工具: 搜索流行的 AI 库的文档:

    • LangChain
    • LlamaIndex
    • OpenAI
  • 会话管理: 维护每个会话的聊天记录

  • 工具集成: 将 AI 模型响应与工具调用无缝集成

  • 错误处理: 针对 API 调用和工具执行的强大错误处理

工作原理

  1. MCP 服务器定义可以被 AI 模型调用的工具
  2. 客户端连接到 MCP 服务器并检索可用的工具
  3. 当用户发送查询时:
    • 客户端格式化会话历史
    • 将其发送到 Hugging Face 模型
    • 从模型的响应中提取并执行工具调用
    • 返回包含工具结果的最终响应

环境变量

服务器

  • SERPER_API_KEY: 用于 Google 搜索功能的 API 密钥

客户端

  • HUGGINGFACE_API_KEY: 用于访问 Hugging Face 模型的 API 密钥

许可证

MIT 许可证

推荐服务器

Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
MCP Package Docs Server

MCP Package Docs Server

促进大型语言模型高效访问和获取 Go、Python 和 NPM 包的结构化文档,通过多语言支持和性能优化来增强软件开发。

精选
本地
TypeScript
Claude Code MCP

Claude Code MCP

一个实现了 Claude Code 作为模型上下文协议(Model Context Protocol, MCP)服务器的方案,它可以通过标准化的 MCP 接口来使用 Claude 的软件工程能力(代码生成、编辑、审查和文件操作)。

精选
本地
JavaScript
@kazuph/mcp-taskmanager

@kazuph/mcp-taskmanager

用于任务管理的模型上下文协议服务器。它允许 Claude Desktop(或任何 MCP 客户端)在基于队列的系统中管理和执行任务。

精选
本地
JavaScript
mermaid-mcp-server

mermaid-mcp-server

一个模型上下文协议 (MCP) 服务器,用于将 Mermaid 图表转换为 PNG 图像。

精选
JavaScript
Jira-Context-MCP

Jira-Context-MCP

MCP 服务器向 AI 编码助手(如 Cursor)提供 Jira 工单信息。

精选
TypeScript
Linear MCP Server

Linear MCP Server

一个模型上下文协议(Model Context Protocol)服务器,它与 Linear 的问题跟踪系统集成,允许大型语言模型(LLM)通过自然语言交互来创建、更新、搜索和评论 Linear 问题。

精选
JavaScript
Sequential Thinking MCP Server

Sequential Thinking MCP Server

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

精选
Python
Curri MCP Server

Curri MCP Server

通过管理文本笔记、提供笔记创建工具以及使用结构化提示生成摘要,从而实现与 Curri API 的交互。

官方
本地
JavaScript