MCP Chat with Claude
Okay, here's a TypeScript example for a web app (acting as the host) connecting to a Node.js MCP (Microcontroller Platform) server. This example focuses on the core communication and assumes you have a basic understanding of TypeScript, web development, and Node.js. **Conceptual Overview** 1. **Web App (Host - TypeScript/HTML/JavaScript):** * Uses WebSockets to establish a persistent connection with the MCP server. * Sends commands/data to the MCP server. * Receives data/responses from the MCP server. * Updates the UI based on the received data. 2. **MCP Server (Node.js):** * Listens for WebSocket connections from the web app. * Receives commands/data. * Processes the commands (e.g., interacts with hardware, performs calculations). * Sends responses back to the web app. **Example Code** **1. MCP Server (Node.js - `mcp-server.js` or `mcp-server.ts`)** ```typescript // mcp-server.ts import { WebSocketServer, WebSocket } from 'ws'; const wss = new WebSocketServer({ port: 8080 }); // Choose your port wss.on('connection', ws => { console.log('Client connected'); ws.on('message', message => { try { const data = JSON.parse(message.toString()); // Parse JSON data console.log('Received:', data); // **Process the received data/command here** // Example: if (data.command === 'getSensorData') { // Simulate sensor data const sensorValue = Math.random() * 100; const response = { type: 'sensorData', value: sensorValue }; ws.send(JSON.stringify(response)); } else if (data.command === 'setLed') { // Simulate setting an LED const ledState = data.state; console.log(`Setting LED to: ${ledState}`); const response = { type: 'ledStatus', state: ledState }; ws.send(JSON.stringify(response)); } else { ws.send(JSON.stringify({ type: 'error', message: 'Unknown command' })); } } catch (error) { console.error('Error parsing message:', error); ws.send(JSON.stringify({ type: 'error', message: 'Invalid JSON' })); } }); ws.on('close', () => { console.log('Client disconnected'); }); ws.on('error', error => { console.error('WebSocket error:', error); }); }); console.log('MCP Server started on port 8080'); ``` **To run the server:** 1. **Install `ws`:** `npm install ws` 2. **If using TypeScript:** * Compile: `tsc mcp-server.ts` * Run: `node mcp-server.js` (or `node mcp-server.ts` if you're using `ts-node`) 3. **If using JavaScript (after compiling from TypeScript):** * Run: `node mcp-server.js` **2. Web App (Host - TypeScript/HTML/JavaScript)** * **HTML (`index.html`):** ```html <!DOCTYPE html> <html> <head> <title>MCP Host</title> </head> <body> <h1>MCP Host</h1> <button id="getSensorData">Get Sensor Data</button> <p>Sensor Value: <span id="sensorValue"></span></p> <button id="ledOn">LED On</button> <button id="ledOff">LED Off</button> <p>LED Status: <span id="ledStatus"></span></p> <script src="app.js"></script> </body> </html> ``` * **TypeScript (`app.ts`):** ```typescript // app.ts const socket = new WebSocket('ws://localhost:8080'); // Replace with your server address socket.addEventListener('open', () => { console.log('Connected to MCP Server'); }); socket.addEventListener('message', event => { try { const data = JSON.parse(event.data); console.log('Received:', data); if (data.type === 'sensorData') { const sensorValueElement = document.getElementById('sensorValue'); if (sensorValueElement) { sensorValueElement.textContent = data.value.toFixed(2); } } else if (data.type === 'ledStatus') { const ledStatusElement = document.getElementById('ledStatus'); if (ledStatusElement) { ledStatusElement.textContent = data.state ? 'On' : 'Off'; } } else if (data.type === 'error') { console.error('Error from server:', data.message); alert(`Error: ${data.message}`); // Or display in a more user-friendly way } } catch (error) { console.error('Error parsing message:', error); } }); socket.addEventListener('close', () => { console.log('Disconnected from MCP Server'); }); socket.addEventListener('error', error => { console.error('WebSocket error:', error); }); // Button event listeners document.getElementById('getSensorData')?.addEventListener('click', () => { socket.send(JSON.stringify({ command: 'getSensorData' })); }); document.getElementById('ledOn')?.addEventListener('click', () => { socket.send(JSON.stringify({ command: 'setLed', state: true })); }); document.getElementById('ledOff')?.addEventListener('click', () => { socket.send(JSON.stringify({ command: 'setLed', state: false })); }); ``` * **Compile TypeScript:** `tsc app.ts` * **JavaScript (`app.js` - the compiled output):** (This will be generated by the TypeScript compiler) **How to Run the Web App:** 1. **Serve the HTML:** You'll need a web server to serve the `index.html` file. You can use a simple one like `http-server` (install with `npm install -g http-server` and then run `http-server .` in the directory containing `index.html`). Alternatively, use any web server you prefer (e.g., a more complex Node.js server, Python's `http.server`, etc.). 2. **Open in Browser:** Open `http://localhost:8080` (or the address your web server is using) in your web browser. **Explanation and Key Points** * **WebSockets:** WebSockets provide a persistent, full-duplex communication channel between the web app and the MCP server. This is ideal for real-time data exchange. * **JSON:** JSON (JavaScript Object Notation) is used to serialize and deserialize data being sent over the WebSocket connection. This makes it easy to work with data in both the web app and the Node.js server. * **Error Handling:** The code includes basic error handling to catch potential issues like invalid JSON or WebSocket errors. Robust error handling is crucial in real-world applications. * **Command Structure:** The example uses a simple command structure where the web app sends JSON objects with a `command` property to indicate the desired action. The server then processes the command and sends back a response. * **TypeScript:** TypeScript adds static typing to JavaScript, which helps catch errors early in the development process and improves code maintainability. * **Event Listeners:** The web app uses event listeners to handle WebSocket events like `open`, `message`, `close`, and `error`. * **DOM Manipulation:** The web app updates the HTML elements (e.g., `sensorValue`, `ledStatus`) to display the data received from the MCP server. * **Server-Side Logic:** The MCP server's `message` handler is where you would implement the core logic for interacting with your microcontroller or other hardware. The example provides placeholders for simulating sensor data and LED control. **Important Considerations for Real-World Applications** * **Security:** If you're dealing with sensitive data, use secure WebSockets (WSS) with TLS/SSL encryption. Implement authentication and authorization mechanisms to protect your MCP server from unauthorized access. * **Scalability:** For high-traffic applications, consider using a more scalable WebSocket server implementation (e.g., using a load balancer and multiple server instances). * **Data Validation:** Validate the data received from the web app and the MCP server to prevent unexpected errors or security vulnerabilities. * **Error Handling:** Implement comprehensive error handling and logging to diagnose and resolve issues quickly. * **Reconnect Logic:** Implement automatic reconnect logic in the web app to handle cases where the WebSocket connection is lost. * **State Management:** Consider using a state management library (e.g., Redux, Zustand) in the web app to manage the application's state more effectively, especially as the application grows in complexity. * **Hardware Interaction:** The MCP server will need to use appropriate libraries or APIs to communicate with your specific microcontroller or hardware. This will vary depending on the hardware platform you're using. * **Message Queues:** For more complex systems, consider using a message queue (e.g., RabbitMQ, Kafka) to decouple the web app and the MCP server and improve reliability and scalability. **Chinese Translation of Key Terms** * **Web App:** 网络应用程序 (wǎngluò yìngyòng chéngxù) * **Host:** 主机 (zhǔjī) * **MCP (Microcontroller Platform):** 微控制器平台 (wēi kòngzhìqì píngtái) * **Server:** 服务器 (fúwùqì) * **WebSocket:** WebSocket (pronounced the same) * **Connection:** 连接 (liánjiē) * **Data:** 数据 (shùjù) * **Command:** 命令 (mìnglìng) * **Sensor:** 传感器 (chuángǎnqì) * **LED:** LED (pronounced the same) or 发光二极管 (fāguāng èrjígǔan) * **Error:** 错误 (cuòwù) * **Message:** 消息 (xiāoxi) * **Client:** 客户端 (kèhùduān) * **JSON:** JSON (pronounced the same) * **Port:** 端口 (duānkǒu) This comprehensive example should give you a solid foundation for building a web app that communicates with a Node.js MCP server using WebSockets and TypeScript. Remember to adapt the code to your specific hardware and application requirements. Good luck!
jiangyan
README
MCP 与 Claude 聊天
一个完整的全栈应用程序,演示了模型上下文协议 (MCP) 与 Anthropic 的 Claude LLM 的集成,提供了一个利用 MCP 工具的交互式聊天界面。
项目概述
该项目由两个主要组件组成:
- MCP 服务器: 一个实现模型上下文协议的 Node.js 服务器,它为 LLM 提供了各种工具供其使用。
- 宿主应用: 一个作为聊天界面并充当用户、Claude AI 和 MCP 服务器之间中介的 Web 应用程序。
特性
- 与 Claude AI 的交互式聊天界面
- 双面板 UI,显示对话和工具执行详情
- 从 MCP 服务器动态发现工具
- 支持具有不同参数的多个工具
- 通过 MCP 正确处理 Claude 的工具使用
项目结构
├── client/ # 宿主应用 & Web 客户端
│ ├── dist/ # 编译后的 TypeScript
│ ├── host-app.ts # 宿主应用程序服务器
│ ├── chat.js # 前端聊天界面逻辑
│ ├── index.html # 主 Web 界面
│ ├── styles.css # Web 界面的样式
│ ├── package.json # 客户端依赖项
│ └── mcp-client-example.ts # 用于测试的 MCP 客户端示例
│
├── server/ # MCP 服务器
│ ├── dist/ # 编译后的 TypeScript
│ ├── mcp-server.ts # MCP 服务器实现
│ └── package.json # 服务器依赖项
│
├── .gitignore # Git 忽略文件
└── README.md # 项目文档
前提条件
- Node.js 17 或更高版本
- npm 或 yarn
- Anthropic API 密钥
安装
-
克隆存储库:
git clone https://github.com/yourusername/mcp-chat-with-claude.git cd mcp-chat-with-claude
-
安装客户端和服务器的依赖项:
cd server npm install cd ../client npm install
-
在客户端目录中创建
.env
文件,其中包含您的 Anthropic API 密钥:ANTHROPIC_API_KEY=your-api-key-here MCP_SERVER_HOST=localhost MCP_SERVER_PORT=8000 MCP_SERVER_PATH=/sse
设置和运行
步骤 1:启动 MCP 服务器
cd server
npm run build
npm start
MCP 服务器将默认在端口 8000 上启动。
步骤 2:启动宿主应用(Web 服务器)
cd client
npm run build
npm start
Web 服务器将默认在端口 3000 上启动。
步骤 3:访问聊天界面
打开您的浏览器并导航到:
http://localhost:3000
可用的 MCP 工具
MCP 服务器提供以下 Claude 可以使用的工具:
-
get-todo: 获取特定类别的待办事项
- 参数:
category
: 字符串(例如,“生活”、“工作”、“家庭”、“朋友”)
- 参数:
-
get-plan: 获取总体计划
- 参数:无
附加示例
该项目包含一个独立的 MCP 客户端示例 (mcp-client-example.ts
),演示了如何在没有 Web 界面的情况下以编程方式连接到 MCP 服务器。
要运行此示例:
cd client
npm run client
开发
MCP 服务器开发
要向 MCP 服务器添加新工具:
- 打开
server/mcp-server.ts
- 按照现有模式添加新的工具定义:
server.tool("tool-name", { param1: z.string() }, async ({ param1 }) => { // 工具实现 return { content: [{ type: "text", text: "Result" }] }; } );
- 重新构建并重启服务器
宿主应用开发
宿主应用包括:
- 后端 (
host-app.ts
): 与 Claude 和 MCP 服务器通信的 Express 服务器 - 前端 (
chat.js
,index.html
,styles.css
): 与后端通信的聊天界面
架构
┌─────────────┐ ┌────────────────┐ ┌───────────────┐
│ │ │ │ │ │
│ Web UI │◄─────►│ Host App │◄─────►│ MCP Server │
│ (Browser) │ │ (Express) │ │ (Node.js) │
│ │ │ │ │ │
└─────────────┘ └───────┬────────┘ └───────────────┘
│
▼
┌───────────────┐
│ │
│ Claude API │
│ (Anthropic) │
│ │
└───────────────┘
故障排除
-
连接问题: 确保两个服务器都在运行,并检查控制台中的错误消息。
-
找不到工具: 确保 MCP 服务器正在运行,并且工具名称完全匹配。
-
API 密钥错误: 验证您的 Anthropic API 密钥是否已在
.env
文件中正确设置。 -
工具使用错误: 检查响应面板以获取详细的错误信息。
许可证
致谢
推荐服务器
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 的交互。