A Simple MCP Server and Client
Okay, here's a simple example of an MCP (Minecraft Communications Protocol) client and server in Python. This is a very basic example and doesn't implement the full MCP protocol, but it demonstrates the core concepts of sending and receiving data. **Important Considerations:** * **Security:** This example is *not* secure. It doesn't include any encryption or authentication. Do not use this in a production environment. * **Error Handling:** The error handling is minimal. A real-world implementation would need much more robust error handling. * **MCP Complexity:** The actual MCP protocol used by Minecraft is significantly more complex than this example. This is a simplified illustration. * **Python:** This example uses Python 3. **Server (server.py):** ```python import socket HOST = '127.0.0.1' # Standard loopback interface address (localhost) PORT = 25565 # Port to listen on (non-privileged ports are > 1023) def handle_client(conn, addr): print(f"Connected by {addr}") while True: try: data = conn.recv(1024) # Receive up to 1024 bytes if not data: break # Client disconnected decoded_data = data.decode('utf-8') print(f"Received from {addr}: {decoded_data}") # Echo the data back to the client (in uppercase) response = decoded_data.upper().encode('utf-8') conn.sendall(response) except ConnectionResetError: print(f"Client {addr} forcibly disconnected.") break except Exception as e: print(f"Error handling client {addr}: {e}") break conn.close() print(f"Connection with {addr} closed.") def main(): with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((HOST, PORT)) s.listen() print(f"Server listening on {HOST}:{PORT}") while True: conn, addr = s.accept() handle_client(conn, addr) # Handle each client in the main thread (for simplicity) if __name__ == "__main__": main() ``` **Client (client.py):** ```python import socket HOST = '127.0.0.1' # The server's hostname or IP address PORT = 25565 # The port used by the server def main(): with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: try: s.connect((HOST, PORT)) print(f"Connected to {HOST}:{PORT}") message = "Hello, MCP Server!" s.sendall(message.encode('utf-8')) data = s.recv(1024) print(f"Received: {data.decode('utf-8')}") except ConnectionRefusedError: print("Connection refused. Is the server running?") except Exception as e: print(f"An error occurred: {e}") print("Client finished.") if __name__ == "__main__": main() ``` **How to Run:** 1. **Save:** Save the server code as `server.py` and the client code as `client.py`. 2. **Run the Server:** Open a terminal or command prompt and navigate to the directory where you saved the files. Run the server: ```bash python server.py ``` 3. **Run the Client:** Open another terminal or command prompt (in the same directory) and run the client: ```bash python client.py ``` **Explanation:** * **`socket` Module:** The `socket` module is Python's standard library for network communication. * **Server:** * Creates a socket, binds it to an address (IP and port), and listens for incoming connections. * `s.accept()`: Accepts a connection, creating a new socket (`conn`) for communication with that specific client. * `conn.recv(1024)`: Receives data from the client (up to 1024 bytes at a time). * `conn.sendall(response)`: Sends data back to the client. * `conn.close()`: Closes the connection with the client. * **Client:** * Creates a socket and connects to the server's address. * `s.sendall(message.encode('utf-8'))`: Sends a message to the server. The message is encoded into bytes using UTF-8. * `s.recv(1024)`: Receives data from the server. * `data.decode('utf-8')`: Decodes the received bytes back into a string. * `s.close()`: Closes the connection. * **Encoding/Decoding:** Data sent over a socket must be in bytes. The `.encode('utf-8')` method converts a string to bytes using UTF-8 encoding. The `.decode('utf-8')` method converts bytes back to a string. * **`with socket.socket(...) as s:`:** This uses a context manager to ensure that the socket is properly closed when the `with` block exits, even if errors occur. **What you'll see:** * **Server Output:** The server will print "Server listening..." and then, when the client connects, it will print "Connected by..." and the client's address. It will then print the message received from the client and the address of the client. Finally, it will print "Connection with... closed." * **Client Output:** The client will print "Connected to..." and then "Received:..." followed by the uppercase version of the message it sent. Finally, it will print "Client finished." **To make it more like MCP (but still simplified):** 1. **Data Structures:** Instead of just sending strings, you'd need to define data structures (e.g., using `struct` module in Python) to represent the different types of packets that MCP uses. 2. **Packet IDs:** Each packet type has an ID. The client and server need to agree on these IDs. 3. **Handshaking:** MCP has a handshake process where the client and server exchange information about the protocol version they are using. 4. **State Management:** The server needs to keep track of the client's state (e.g., whether the client is logged in, what world the client is in). 5. **Compression/Encryption:** MCP uses compression and encryption for performance and security. This example provides a basic foundation. Building a real MCP implementation is a complex task. --- **Chinese Translation (Simplified Chinese):** 这是一个简单的 MCP (Minecraft 通讯协议) 客户端和服务器的例子,使用 Python 编写。 这是一个非常基础的例子,并没有实现完整的 MCP 协议,但它演示了发送和接收数据的核心概念。 **重要注意事项:** * **安全性:** 这个例子 *不* 安全。 它不包含任何加密或身份验证。 请勿在生产环境中使用它。 * **错误处理:** 错误处理非常少。 实际应用需要更强大的错误处理。 * **MCP 复杂性:** Minecraft 实际使用的 MCP 协议比这个例子复杂得多。 这是一个简化的说明。 * **Python:** 这个例子使用 Python 3。 **服务器 (server.py):** ```python import socket HOST = '127.0.0.1' # 标准回环接口地址 (localhost) PORT = 25565 # 监听端口 (非特权端口 > 1023) def handle_client(conn, addr): print(f"Connected by {addr}") while True: try: data = conn.recv(1024) # 接收最多 1024 字节 if not data: break # 客户端断开连接 decoded_data = data.decode('utf-8') print(f"Received from {addr}: {decoded_data}") # 将数据回显给客户端 (转换为大写) response = decoded_data.upper().encode('utf-8') conn.sendall(response) except ConnectionResetError: print(f"Client {addr} forcibly disconnected.") break except Exception as e: print(f"Error handling client {addr}: {e}") break conn.close() print(f"Connection with {addr} closed.") def main(): with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((HOST, PORT)) s.listen() print(f"Server listening on {HOST}:{PORT}") while True: conn, addr = s.accept() handle_client(conn, addr) # 在主线程中处理每个客户端 (为了简单起见) if __name__ == "__main__": main() ``` **客户端 (client.py):** ```python import socket HOST = '127.0.0.1' # 服务器的主机名或 IP 地址 PORT = 25565 # 服务器使用的端口 def main(): with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: try: s.connect((HOST, PORT)) print(f"Connected to {HOST}:{PORT}") message = "Hello, MCP Server!" s.sendall(message.encode('utf-8')) data = s.recv(1024) print(f"Received: {data.decode('utf-8')}") except ConnectionRefusedError: print("Connection refused. Is the server running?") except Exception as e: print(f"An error occurred: {e}") print("Client finished.") if __name__ == "__main__": main() ``` **如何运行:** 1. **保存:** 将服务器代码保存为 `server.py`,将客户端代码保存为 `client.py`。 2. **运行服务器:** 打开终端或命令提示符,导航到保存文件的目录。 运行服务器: ```bash python server.py ``` 3. **运行客户端:** 打开另一个终端或命令提示符(在同一目录下),然后运行客户端: ```bash python client.py ``` **解释:** * **`socket` 模块:** `socket` 模块是 Python 的标准库,用于网络通信。 * **服务器:** * 创建一个套接字,将其绑定到地址(IP 和端口),并监听传入的连接。 * `s.accept()`:接受连接,创建一个新的套接字 (`conn`) 用于与该特定客户端通信。 * `conn.recv(1024)`:从客户端接收数据(一次最多 1024 字节)。 * `conn.sendall(response)`:将数据发送回客户端。 * `conn.close()`:关闭与客户端的连接。 * **客户端:** * 创建一个套接字并连接到服务器的地址。 * `s.sendall(message.encode('utf-8'))`:向服务器发送消息。 该消息使用 UTF-8 编码转换为字节。 * `s.recv(1024)`:从服务器接收数据。 * `data.decode('utf-8')`:将接收到的字节解码回字符串。 * `s.close()`:关闭连接。 * **编码/解码:** 通过套接字发送的数据必须是字节。 `.encode('utf-8')` 方法使用 UTF-8 编码将字符串转换为字节。 `.decode('utf-8')` 方法将字节转换回字符串。 * **`with socket.socket(...) as s:`:** 这使用上下文管理器来确保在 `with` 块退出时正确关闭套接字,即使发生错误也是如此。 **你会看到什么:** * **服务器输出:** 服务器将打印 "Server listening...",然后,当客户端连接时,它将打印 "Connected by..." 和客户端的地址。 然后它将打印从客户端收到的消息和客户端的地址。 最后,它将打印 "Connection with... closed." * **客户端输出:** 客户端将打印 "Connected to...",然后打印 "Received:...",后跟它发送的消息的大写版本。 最后,它将打印 "Client finished." **为了使其更像 MCP(但仍然简化):** 1. **数据结构:** 不是只发送字符串,你需要定义数据结构(例如,使用 Python 中的 `struct` 模块)来表示 MCP 使用的不同类型的包。 2. **数据包 ID:** 每种数据包类型都有一个 ID。 客户端和服务器需要就这些 ID 达成一致。 3. **握手:** MCP 有一个握手过程,客户端和服务器交换有关他们正在使用的协议版本的信息。 4. **状态管理:** 服务器需要跟踪客户端的状态(例如,客户端是否已登录,客户端位于哪个世界)。 5. **压缩/加密:** MCP 使用压缩和加密来提高性能和安全性。 这个例子提供了一个基本的基础。 构建真正的 MCP 实现是一项复杂的任务。
logesh-kumar
README
一个简单的 MCP 服务器和客户端
这是一个简单的模型上下文协议 (MCP) 服务器和客户端实现,演示了如何公开和访问天气信息。
服务器
服务器在 server.js 中实现。它提供以下功能:
-
资源:
city://NewYork: 关于纽约市的基本信息city://London: 关于伦敦的基本信息city://Tokyo: 关于东京的基本信息
-
工具:
get-weather: 获取城市的天气预报,带有城市名称和天数参数
-
提示:
weather-advice: 根据天气状况获取旅行建议
客户端
客户端在 client.js 中实现。它演示了如何:
- 连接到 MCP 服务器
- 列出可用资源
- 读取特定的城市资源
- 调用天气预报工具
- 获取天气建议提示
JSON-RPC 通信
此实现使用 JSON-RPC 2.0 作为客户端和服务器之间底层通信协议。使用的关键 JSON-RPC 概念:
- 方法: 标准方法名称,如
resources/list、resources/read、tools/call和prompts/get - 参数: 与方法调用一起发送的输入数据
- 请求 ID: 用于将请求与响应匹配的唯一标识符
- 结果/错误: 结构化的响应数据或错误信息
MCP SDK 抽象了大部分内容,但了解协议有助于调试和自定义。您可以通过检查控制台输出来查看原始 JSON-RPC 消息。
运行服务器和客户端
-
启动客户端:
node client.js启动客户端将自动启动服务器作为子进程。客户端将连接到服务器并执行所有示例操作。
-
要独立启动服务器:
node server.js
传输机制
此示例使用 stdio(标准输入/输出)作为客户端和服务器之间的传输机制。当客户端启动时,它会生成服务器作为子进程,并通过 stdin/stdout 流与其通信。
实现了一个自定义日志记录传输,以显示客户端和服务器之间交换的消息。这些消息以人类可读的格式记录到控制台,这有助于理解协议。
故障排除
如果您遇到资源或提示请求超时的的问题,请检查服务器实现。该示例包括对某些请求类型的直接消息处理,以解决当前 SDK 版本中的限制。
推荐服务器
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 的交互。