发现优秀的 MCP 服务器
通过 MCP 服务器扩展您的代理能力,拥有 86,267 个能力。
mysql-mcp-server-all
A read-only MySQL MCP server supporting stdio, SSE, and Streamable HTTP transports, enabling secure querying and schema inspection of MySQL databases from MCP clients.
mcp-software-design
Provides software design guidance via MCP, including SOLID principles, design patterns, pattern scaffolding, and heuristic code-smell detection to help review and refactor code.
companycam-mcp
Enables managing CompanyCam projects, photos, tags, comments, and users through natural language, using the CompanyCam API.
AI-Scholarly-Mode
Enables AI assistants to search and retrieve peer-reviewed academic articles exclusively from Springer Nature's open access collection. It provides a specialized mode for research-driven conversations, allowing users to toggle scholarly-only search and fetch full article content.
cockpit-mcp
Accounting automation MCP server for Japanese tax firms. Two-stage classifier (keyword + Claude AI) with TaxRuleEngine for consumption tax, withholding, invoice system, and confidence-based routing.
Wave MCP Server
MCP server for Wave accounting that provides tools for managing chart of accounts, invoices, customers, vendors, products, and reports via the Wave GraphQL API.
Terragrunt MCP Server
Enables analysis and validation of Terragrunt projects, including dependency mapping, stack structure, and optimization suggestions, directly in IDEs that support MCP.
graphql-agent-toolkit
Enables AI agents to interact with any GraphQL API by introspecting the schema and exposing queries and mutations as MCP tools, with built-in pagination, semantic search, and framework adapters.
rhr-mcp
MCP server that gives AI agents structured access to Public Procurement Registry data, allowing natural language queries for planned procurements, open tenders, contract awards, buyers, and winning suppliers.
CoinGecko MCP Server
An MCP server for CoinGecko that connects any MCP-compatible client to free crypto market data, providing tools for prices, market caps, trending coins, historical data, and global stats.
JSON MCP Server
Provides powerful JSON manipulation tools through Model Context Protocol, enabling complex queries, schema generation, and validation with jq notation and native Node.js operations.
GraphSense MCP Server
Enables natural language queries about JavaScript/TypeScript codebases using graph and vector search. Allows finding functions by semantic description, callers, callees, and function details.
flutterclimcp
好的,这是一个使用 Flutter CLI 和 MCP (Model Context Protocol) 服务器创建 Flutter 项目的有趣示例项目: **项目名称:** 猜数字游戏 (Guess the Number Game) **项目描述:** 这是一个简单的猜数字游戏,用户需要猜一个由计算机随机生成的数字。游戏会提供反馈,告诉用户猜的数字是太高还是太低,直到用户猜对为止。我们将使用 MCP 服务器来处理游戏逻辑,而 Flutter 应用将负责用户界面和与服务器的通信。 **技术栈:** * **Flutter:** 用于构建用户界面。 * **Flutter CLI:** 用于创建和管理 Flutter 项目。 * **MCP Server (Python):** 用于处理游戏逻辑,例如生成随机数、比较猜测和提供反馈。 * **HTTP:** 用于 Flutter 应用和 MCP 服务器之间的通信。 **步骤:** 1. **设置 MCP 服务器 (Python):** ```python from http.server import BaseHTTPRequestHandler, HTTPServer import json import random class RequestHandler(BaseHTTPRequestHandler): def do_POST(self): if self.path == '/guess': content_length = int(self.headers['Content-Length']) post_data = self.rfile.read(content_length) data = json.loads(post_data.decode('utf-8')) guess = data.get('guess') if not hasattr(self.server, 'secret_number'): self.server.secret_number = random.randint(1, 100) self.server.num_guesses = 0 self.server.num_guesses += 1 if guess is None: response = {'error': 'Missing guess parameter'} elif guess < self.server.secret_number: response = {'result': 'too_low'} elif guess > self.server.secret_number: response = {'result': 'too_high'} else: response = {'result': 'correct', 'guesses': self.server.num_guesses} del self.server.secret_number # Reset for next game del self.server.num_guesses self.send_response(200) self.send_header('Content-type', 'application/json') self.end_headers() self.wfile.write(json.dumps(response).encode('utf-8')) else: self.send_response(404) self.end_headers() def run(server_class=HTTPServer, handler_class=RequestHandler, port=8000): server_address = ('', port) httpd = server_class(server_address, handler_class) print(f'Starting server on port {port}') httpd.serve_forever() if __name__ == '__main__': run() ``` * 将此代码保存为 `mcp_server.py`。 * 运行服务器:`python mcp_server.py` 2. **创建 Flutter 项目:** ```bash flutter create guess_the_number cd guess_the_number ``` 3. **修改 `lib/main.dart`:** ```dart import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Guess the Number', theme: ThemeData( primarySwatch: Colors.blue, ), home: GuessTheNumberPage(), ); } } class GuessTheNumberPage extends StatefulWidget { @override _GuessTheNumberPageState createState() => _GuessTheNumberPageState(); } class _GuessTheNumberPageState extends State<GuessTheNumberPage> { final TextEditingController _guessController = TextEditingController(); String _message = ''; bool _gameOver = false; Future<void> _checkGuess(String guess) async { try { final int? parsedGuess = int.tryParse(guess); if (parsedGuess == null) { setState(() { _message = 'Please enter a valid number.'; }); return; } final response = await http.post( Uri.parse('http://localhost:8000/guess'), // Replace with your server address headers: {'Content-Type': 'application/json'}, body: jsonEncode({'guess': parsedGuess}), ); if (response.statusCode == 200) { final data = jsonDecode(response.body); final result = data['result']; setState(() { if (result == 'too_low') { _message = 'Too low! Try again.'; } else if (result == 'too_high') { _message = 'Too high! Try again.'; } else if (result == 'correct') { _message = 'Congratulations! You guessed the number in ${data['guesses']} tries.'; _gameOver = true; } else if (data.containsKey('error')) { _message = 'Error: ${data['error']}'; } else { _message = 'Unexpected response from server.'; } }); } else { setState(() { _message = 'Failed to connect to the server. Status code: ${response.statusCode}'; }); } } catch (e) { setState(() { _message = 'An error occurred: $e'; }); } } void _resetGame() { setState(() { _message = ''; _guessController.clear(); _gameOver = false; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Guess the Number'), ), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'I\'m thinking of a number between 1 and 100.', style: TextStyle(fontSize: 16), ), SizedBox(height: 20), TextField( controller: _guessController, keyboardType: TextInputType.number, decoration: InputDecoration( labelText: 'Enter your guess', border: OutlineInputBorder(), ), enabled: !_gameOver, ), SizedBox(height: 20), ElevatedButton( onPressed: _gameOver ? null : () { _checkGuess(_guessController.text); }, child: Text('Guess'), ), SizedBox(height: 20), Text( _message, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), textAlign: TextAlign.center, ), if (_gameOver) ElevatedButton( onPressed: _resetGame, child: Text('Play Again'), ), ], ), ), ); } } ``` 4. **添加 `http` 依赖:** ```bash flutter pub add http ``` 5. **运行 Flutter 应用:** ```bash flutter run ``` **解释:** * **MCP 服务器 (Python):** * 监听端口 8000 上的 HTTP POST 请求。 * 当收到 `/guess` 请求时,它会解析 JSON 数据,提取用户的猜测。 * 如果这是第一次猜测,它会生成一个 1 到 100 之间的随机数。 * 它会将用户的猜测与秘密数字进行比较,并返回 `too_low`、`too_high` 或 `correct`。 * 如果猜测正确,它会返回猜测次数并重置游戏。 * **Flutter 应用:** * 包含一个文本字段,用户可以在其中输入他们的猜测。 * 包含一个按钮,用户可以点击该按钮来提交他们的猜测。 * 使用 `http` 包向 MCP 服务器发送 POST 请求,并将用户的猜测作为 JSON 数据发送。 * 解析服务器的响应,并更新 UI 以显示反馈(太高、太低、正确)。 * 如果用户猜对了,它会显示一条祝贺消息和猜测次数。 * 包含一个“再玩一次”按钮,可以重置游戏。 **如何运行:** 1. 首先,运行 `mcp_server.py`。 2. 然后,运行 Flutter 应用。 3. 在 Flutter 应用中,输入你的猜测并点击“猜测”按钮。 4. 查看应用中的反馈,并继续猜测直到你猜对为止。 **改进:** * **错误处理:** 添加更健壮的错误处理,例如处理服务器连接错误。 * **UI 改进:** 改进 UI 以使其更具吸引力。 * **难度级别:** 添加难度级别,允许用户选择数字范围。 * **历史记录:** 显示用户的猜测历史记录。 * **使用更复杂的 MCP 协议:** 虽然这个例子使用简单的 HTTP,但你可以探索更复杂的 MCP 协议,例如 gRPC 或 Thrift,以获得更好的性能和类型安全。 这个示例展示了如何使用 Flutter CLI 和 MCP 服务器创建一个简单的 Flutter 项目。 你可以根据自己的需要修改和扩展此项目。 关键在于将 UI 逻辑与业务逻辑分离,并使用 MCP 服务器来处理业务逻辑。 **中文翻译:** 好的,这是一个使用 Flutter CLI 和 MCP (模型上下文协议) 服务器创建一个 Flutter 项目的有趣示例项目: **项目名称:** 猜数字游戏 (Guess the Number Game) **项目描述:** 这是一个简单的猜数字游戏,用户需要猜一个由计算机随机生成的数字。游戏会提供反馈,告诉用户猜的数字是太高还是太低,直到用户猜对为止。我们将使用 MCP 服务器来处理游戏逻辑,而 Flutter 应用将负责用户界面和与服务器的通信。 **技术栈:** * **Flutter:** 用于构建用户界面。 * **Flutter CLI:** 用于创建和管理 Flutter 项目。 * **MCP Server (Python):** 用于处理游戏逻辑,例如生成随机数、比较猜测和提供反馈。 * **HTTP:** 用于 Flutter 应用和 MCP 服务器之间的通信。 **步骤:** 1. **设置 MCP 服务器 (Python):** ```python from http.server import BaseHTTPRequestHandler, HTTPServer import json import random class RequestHandler(BaseHTTPRequestHandler): def do_POST(self): if self.path == '/guess': content_length = int(self.headers['Content-Length']) post_data = self.rfile.read(content_length) data = json.loads(post_data.decode('utf-8')) guess = data.get('guess') if not hasattr(self.server, 'secret_number'): self.server.secret_number = random.randint(1, 100) self.server.num_guesses = 0 self.server.num_guesses += 1 if guess is None: response = {'error': 'Missing guess parameter'} elif guess < self.server.secret_number: response = {'result': 'too_low'} elif guess > self.server.secret_number: response = {'result': 'too_high'} else: response = {'result': 'correct', 'guesses': self.server.num_guesses} del self.server.secret_number # Reset for next game del self.server.num_guesses self.send_response(200) self.send_header('Content-type', 'application/json') self.end_headers() self.wfile.write(json.dumps(response).encode('utf-8')) else: self.send_response(404) self.end_headers() def run(server_class=HTTPServer, handler_class=RequestHandler, port=8000): server_address = ('', port) httpd = server_class(server_address, handler_class) print(f'Starting server on port {port}') httpd.serve_forever() if __name__ == '__main__': run() ``` * 将此代码保存为 `mcp_server.py`。 * 运行服务器:`python mcp_server.py` 2. **创建 Flutter 项目:** ```bash flutter create guess_the_number cd guess_the_number ``` 3. **修改 `lib/main.dart`:** ```dart import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Guess the Number', theme: ThemeData( primarySwatch: Colors.blue, ), home: GuessTheNumberPage(), ); } } class GuessTheNumberPage extends StatefulWidget { @override _GuessTheNumberPageState createState() => _GuessTheNumberPageState(); } class _GuessTheNumberPageState extends State<GuessTheNumberPage> { final TextEditingController _guessController = TextEditingController(); String _message = ''; bool _gameOver = false; Future<void> _checkGuess(String guess) async { try { final int? parsedGuess = int.tryParse(guess); if (parsedGuess == null) { setState(() { _message = 'Please enter a valid number.'; }); return; } final response = await http.post( Uri.parse('http://localhost:8000/guess'), // Replace with your server address headers: {'Content-Type': 'application/json'}, body: jsonEncode({'guess': parsedGuess}), ); if (response.statusCode == 200) { final data = jsonDecode(response.body); final result = data['result']; setState(() { if (result == 'too_low') { _message = 'Too low! Try again.'; } else if (result == 'too_high') { _message = 'Too high! Try again.'; } else if (result == 'correct') { _message = 'Congratulations! You guessed the number in ${data['guesses']} tries.'; _gameOver = true; } else if (data.containsKey('error')) { _message = 'Error: ${data['error']}'; } else { _message = 'Unexpected response from server.'; } }); } else { setState(() { _message = 'Failed to connect to the server. Status code: ${response.statusCode}'; }); } } catch (e) { setState(() { _message = 'An error occurred: $e'; }); } } void _resetGame() { setState(() { _message = ''; _guessController.clear(); _gameOver = false; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Guess the Number'), ), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'I\'m thinking of a number between 1 and 100.', style: TextStyle(fontSize: 16), ), SizedBox(height: 20), TextField( controller: _guessController, keyboardType: TextInputType.number, decoration: InputDecoration( labelText: 'Enter your guess', border: OutlineInputBorder(), ), enabled: !_gameOver, ), SizedBox(height: 20), ElevatedButton( onPressed: _gameOver ? null : () { _checkGuess(_guessController.text); }, child: Text('Guess'), ), SizedBox(height: 20), Text( _message, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), textAlign: TextAlign.center, ), if (_gameOver) ElevatedButton( onPressed: _resetGame, child: Text('Play Again'), ), ], ), ), ); } } ``` 4. **添加 `http` 依赖:** ```bash flutter pub add http ``` 5. **运行 Flutter 应用:** ```bash flutter run ``` **解释:** * **MCP 服务器 (Python):** * 监听端口 8000 上的 HTTP POST 请求。 * 当收到 `/guess` 请求时,它会解析 JSON 数据,提取用户的猜测。 * 如果这是第一次猜测,它会生成一个 1 到 100 之间的随机数。 * 它会将用户的猜测与秘密数字进行比较,并返回 `too_low`、`too_high` 或 `correct`。 * 如果猜测正确,它会返回猜测次数并重置游戏。 * **Flutter 应用:** * 包含一个文本字段,用户可以在其中输入他们的猜测。 * 包含一个按钮,用户可以点击该按钮来提交他们的猜测。 * 使用 `http` 包向 MCP 服务器发送 POST 请求,并将用户的猜测作为 JSON 数据发送。 * 解析服务器的响应,并更新 UI 以显示反馈(太高、太低、正确)。 * 如果用户猜对了,它会显示一条祝贺消息和猜测次数。 * 包含一个“再玩一次”按钮,可以重置游戏。 **如何运行:** 1. 首先,运行 `mcp_server.py`。 2. 然后,运行 Flutter 应用。 3. 在 Flutter 应用中,输入你的猜测并点击“猜测”按钮。 4. 查看应用中的反馈,并继续猜测直到你猜对为止。 **改进:** * **错误处理:** 添加更健壮的错误处理,例如处理服务器连接错误。 * **UI 改进:** 改进 UI 以使其更具吸引力。 * **难度级别:** 添加难度级别,允许用户选择数字范围。 * **历史记录:** 显示用户的猜测历史记录。 * **使用更复杂的 MCP 协议:** 虽然这个例子使用简单的 HTTP,但你可以探索更复杂的 MCP 协议,例如 gRPC 或 Thrift,以获得更好的性能和类型安全。 这个示例展示了如何使用 Flutter CLI 和 MCP 服务器创建一个简单的 Flutter 项目。 你可以根据自己的需要修改和扩展此项目。 关键在于将 UI 逻辑与业务逻辑分离,并使用 MCP 服务器来处理业务逻辑。 This provides a complete, runnable example with explanations and improvements. Remember to replace `http://localhost:8000/guess` with the actual address of your MCP server if it's running on a different machine or port. Good luck!
Infrações da PRF
Consulta o histórico de multas de trânsito da Polícia Rodoviária Federal por RENAVAM, incluindo canceladas, em aberto ou pagas, via uma ferramenta somente leitura.
vision-mcp
Vision MCP enables text-only agents to understand images through any OpenAI-compatible vision model. It supports local images, URLs, screenshots, documents, charts, and code errors with tools like analyze_image and understand_image.
Security MCP Server
Enables security scanning of codebases through integrated tools for secret detection, SCA, SAST, and DAST vulnerabilities, with AI-powered remediation suggestions based on findings.
OfficeRnD MCP Server
A read-only MCP server that connects AI assistants to the OfficeRnD coworking and flex-space management platform. It enables natural language queries for community members, space bookings, billing records, and office resources.
Jira Data Center MCP Server
Enables AI assistants to deeply introspect Jira Data Center configurations — including workflows, schemes, automation, and Assets — through 76 read-only tools, without any modification capability.
filesystem
A minimal MCP server that exposes three file operations (read_file, write_file, list_directory) within a sandboxed workspace, enabling file management via natural language.
ddg-mcp-search
A minimal MCP server that provides a DuckDuckGo search tool with configurable region, time limit, and safe search options.
app.wishpool/czechia-payments-mcp
A remote MCP server that lets any AI agent accept payments in Czechia via Stripe's hosted checkout.
Filesystem MCP
安全地修改 MCP 服务器根目录下的文件,同时防止用户逃逸到根目录之外: 这里提供一些建议,结合了安全性和实用性: **核心原则:最小权限原则 (Principle of Least Privilege)** * **用户权限限制:** 这是最重要的一点。 运行 MCP 服务器的用户账户(例如,一个专门创建的 `mcp_user` 账户)**绝对不能**拥有 root 权限。 它应该只拥有修改根目录下特定文件和目录的权限。 * **chroot 环境 (Chrooted Environment):** 将 MCP 服务器限制在一个 chroot 环境中。 Chroot 会创建一个虚拟的根目录,让服务器认为它位于文件系统的顶层,即使它实际上位于更深的位置。 这可以防止用户访问 chroot 环境之外的文件。 * **输入验证和清理:** 对所有用户输入进行严格的验证和清理。 这可以防止命令注入攻击,攻击者可能会利用这些漏洞来执行任意代码。 * **输出编码:** 对所有输出进行编码,以防止跨站脚本攻击 (XSS)。 * **定期更新:** 保持 MCP 服务器软件和操作系统更新到最新版本,以修复已知的安全漏洞。 **具体实现方法:** 1. **创建用户和组:** ```bash sudo groupadd mcp_group sudo useradd -g mcp_group -d /path/to/mcp/root -s /bin/bash mcp_user sudo passwd mcp_user # 设置密码 ``` * `/path/to/mcp/root` 是你希望作为 MCP 服务器根目录的实际路径。 例如,`/opt/mcp_server`。 * `-s /bin/bash` 允许用户使用 bash shell。 如果不需要 shell 访问,可以设置为 `/bin/false` 或 `/usr/sbin/nologin`。 2. **设置目录权限:** ```bash sudo chown -R mcp_user:mcp_group /path/to/mcp/root sudo chmod -R 770 /path/to/mcp/root # 允许用户和组读写执行 ``` * 根据需要调整权限。 例如,如果用户只需要读取某些文件,则可以将其权限设置为 `440`。 * **重要:** 确保 `mcp_user` 拥有修改所需文件的权限,但不要授予不必要的权限。 3. **Chroot 环境 (推荐):** * **创建 chroot 环境:** 这需要一些手动操作,因为你需要复制所有必要的库和程序到 chroot 目录中。 可以使用 `debootstrap` (Debian/Ubuntu) 或 `yum install yum-utils; yumdownloader --resolve --destdir=/path/to/chroot/lib <program>` (CentOS/RHEL) 来简化这个过程。 ```bash # 示例 (Debian/Ubuntu) sudo apt-get install debootstrap sudo mkdir /path/to/chroot sudo debootstrap --arch amd64 stable /path/to/chroot http://httpredir.debian.org/debian ``` * `stable` 可以替换为 `testing` 或 `unstable`,但 `stable` 最安全。 * `amd64` 替换为你的架构 (例如 `i386`, `arm64`)。 * **重要:** 你需要复制 MCP 服务器依赖的所有库和程序到 `/path/to/chroot` 中。 这可能包括 `libc.so.6`, `libpthread.so.0`, 等等。 使用 `ldd <mcp_server_executable>` 来查看依赖项。 * **使用 `chroot` 命令:** 在启动 MCP 服务器之前,使用 `chroot` 命令将其限制在 chroot 环境中。 ```bash sudo chroot /path/to/chroot /path/to/mcp_server_executable ``` * **更高级的 chroot 管理工具:** 考虑使用 `jailkit` 或 `docker` 等工具来更轻松地管理 chroot 环境。 Docker 提供了一种更隔离和可移植的解决方案。 4. **输入验证和清理:** * **白名单:** 使用白名单来限制允许的输入。 例如,如果用户只能修改某些特定的文件,则只允许这些文件的名称作为输入。 * **正则表达式:** 使用正则表达式来验证输入的格式。 例如,如果用户必须输入一个数字,则可以使用正则表达式来确保输入只包含数字。 * **转义:** 转义所有特殊字符,以防止命令注入攻击。 例如,在 bash 中,可以使用 `\` 来转义特殊字符。 5. **输出编码:** * **HTML 编码:** 如果 MCP 服务器生成 HTML 输出,则对所有输出进行 HTML 编码,以防止 XSS 攻击。 * **URL 编码:** 如果 MCP 服务器生成 URL,则对所有 URL 进行 URL 编码。 6. **日志记录:** * 记录所有用户操作,以便进行审计和故障排除。 * 监控日志文件,以检测可疑活动。 7. **防火墙:** * 使用防火墙来限制对 MCP 服务器的访问。 只允许来自受信任的 IP 地址的连接。 **示例代码 (Python):** ```python import os import subprocess import re def modify_file(filename, content): """ 安全地修改文件。 Args: filename: 要修改的文件名 (相对于根目录). content: 要写入文件的内容. """ # 1. 白名单验证文件名 allowed_files = ["config.txt", "data.json"] # 允许修改的文件 if filename not in allowed_files: raise ValueError("Invalid filename") # 2. 构造完整路径 (相对于根目录) filepath = os.path.join("/path/to/mcp/root", filename) # 3. 检查文件是否存在 if not os.path.exists(filepath): raise FileNotFoundError("File not found") # 4. 输入验证 (例如,限制内容长度) if len(content) > 1024: raise ValueError("Content too long") # 5. 使用 subprocess 安全地写入文件 try: with open(filepath, "w") as f: f.write(content) except Exception as e: raise Exception(f"Error writing to file: {e}") # 示例用法 try: modify_file("config.txt", "new config value") print("File modified successfully") except ValueError as e: print(f"Error: {e}") except FileNotFoundError as e: print(f"Error: {e}") except Exception as e: print(f"An unexpected error occurred: {e}") ``` **重要注意事项:** * **测试:** 在生产环境中部署之前,彻底测试所有安全措施。 * **安全审计:** 定期进行安全审计,以识别和修复潜在的安全漏洞。 * **具体情况:** 以上建议只是一些通用的指导原则。 你需要根据你的具体情况进行调整。 * **复杂性:** 构建一个完全安全的系统非常复杂。 如果你不确定如何操作,请咨询安全专家。 **总结:** 通过结合最小权限原则、chroot 环境、输入验证和清理、输出编码、日志记录和防火墙,你可以大大提高 MCP 服务器的安全性,防止用户逃逸到根目录之外,并安全地修改文件。 记住,安全是一个持续的过程,需要不断地监控和改进。 --- **中文翻译:** 安全地修改 MCP 服务器根目录下的文件,同时防止用户逃逸到根目录之外: 这里提供一些建议,结合了安全性和实用性: **核心原则:最小权限原则 (Principle of Least Privilege)** * **用户权限限制:** 这是最重要的一点。运行 MCP 服务器的用户账户(例如,一个专门创建的 `mcp_user` 账户)**绝对不能**拥有 root 权限。它应该只拥有修改根目录下特定文件和目录的权限。 * **chroot 环境 (Chrooted Environment):** 将 MCP 服务器限制在一个 chroot 环境中。Chroot 会创建一个虚拟的根目录,让服务器认为它位于文件系统的顶层,即使它实际上位于更深的位置。这可以防止用户访问 chroot 环境之外的文件。 * **输入验证和清理:** 对所有用户输入进行严格的验证和清理。这可以防止命令注入攻击,攻击者可能会利用这些漏洞来执行任意代码。 * **输出编码:** 对所有输出进行编码,以防止跨站脚本攻击 (XSS)。 * **定期更新:** 保持 MCP 服务器软件和操作系统更新到最新版本,以修复已知的安全漏洞。 **具体实现方法:** 1. **创建用户和组:** ```bash sudo groupadd mcp_group sudo useradd -g mcp_group -d /path/to/mcp/root -s /bin/bash mcp_user sudo passwd mcp_user # 设置密码 ``` * `/path/to/mcp/root` 是你希望作为 MCP 服务器根目录的实际路径。例如,`/opt/mcp_server`。 * `-s /bin/bash` 允许用户使用 bash shell。如果不需要 shell 访问,可以设置为 `/bin/false` 或 `/usr/sbin/nologin`。 2. **设置目录权限:** ```bash sudo chown -R mcp_user:mcp_group /path/to/mcp/root sudo chmod -R 770 /path/to/mcp/root # 允许用户和组读写执行 ``` * 根据需要调整权限。例如,如果用户只需要读取某些文件,则可以将其权限设置为 `440`。 * **重要:** 确保 `mcp_user` 拥有修改所需文件的权限,但不要授予不必要的权限。 3. **Chroot 环境 (推荐):** * **创建 chroot 环境:** 这需要一些手动操作,因为你需要复制所有必要的库和程序到 chroot 目录中。可以使用 `debootstrap` (Debian/Ubuntu) 或 `yum install yum-utils; yumdownloader --resolve --destdir=/path/to/chroot/lib <program>` (CentOS/RHEL) 来简化这个过程。 ```bash # 示例 (Debian/Ubuntu) sudo apt-get install debootstrap sudo mkdir /path/to/chroot sudo debootstrap --arch amd64 stable /path/to/chroot http://httpredir.debian.org/debian ``` * `stable` 可以替换为 `testing` 或 `unstable`,但 `stable` 最安全。 * `amd64` 替换为你的架构 (例如 `i386`, `arm64`)。 * **重要:** 你需要复制 MCP 服务器依赖的所有库和程序到 `/path/to/chroot` 中。这可能包括 `libc.so.6`, `libpthread.so.0`, 等等。使用 `ldd <mcp_server_executable>` 来查看依赖项。 * **使用 `chroot` 命令:** 在启动 MCP 服务器之前,使用 `chroot` 命令将其限制在 chroot 环境中。 ```bash sudo chroot /path/to/chroot /path/to/mcp_server_executable ``` * **更高级的 chroot 管理工具:** 考虑使用 `jailkit` 或 `docker` 等工具来更轻松地管理 chroot 环境。Docker 提供了一种更隔离和可移植的解决方案。 4. **输入验证和清理:** * **白名单:** 使用白名单来限制允许的输入。例如,如果用户只能修改某些特定的文件,则只允许这些文件的名称作为输入。 * **正则表达式:** 使用正则表达式来验证输入的格式。例如,如果用户必须输入一个数字,则可以使用正则表达式来确保输入只包含数字。 * **转义:** 转义所有特殊字符,以防止命令注入攻击。例如,在 bash 中,可以使用 `\` 来转义特殊字符。 5. **输出编码:** * **HTML 编码:** 如果 MCP 服务器生成 HTML 输出,则对所有输出进行 HTML 编码,以防止 XSS 攻击。 * **URL 编码:** 如果 MCP 服务器生成 URL,则对所有 URL 进行 URL 编码。 6. **日志记录:** * 记录所有用户操作,以便进行审计和故障排除。 * 监控日志文件,以检测可疑活动。 7. **防火墙:** * 使用防火墙来限制对 MCP 服务器的访问。只允许来自受信任的 IP 地址的连接。 **示例代码 (Python):** ```python import os import subprocess import re def modify_file(filename, content): """ 安全地修改文件。 Args: filename: 要修改的文件名 (相对于根目录). content: 要写入文件的内容. """ # 1. 白名单验证文件名 allowed_files = ["config.txt", "data.json"] # 允许修改的文件 if filename not in allowed_files: raise ValueError("Invalid filename") # 2. 构造完整路径 (相对于根目录) filepath = os.path.join("/path/to/mcp/root", filename) # 3. 检查文件是否存在 if not os.path.exists(filepath): raise FileNotFoundError("File not found") # 4. 输入验证 (例如,限制内容长度) if len(content) > 1024: raise ValueError("Content too long") # 5. 使用 subprocess 安全地写入文件 try: with open(filepath, "w") as f: f.write(content) except Exception as e: raise Exception(f"Error writing to file: {e}") # 示例用法 try: modify_file("config.txt", "new config value") print("File modified successfully") except ValueError as e: print(f"Error: {e}") except FileNotFoundError as e: print(f"Error: {e}") except Exception as e: print(f"An unexpected error occurred: {e}") ``` **重要注意事项:** * **测试:** 在生产环境中部署之前,彻底测试所有安全措施。 * **安全审计:** 定期进行安全审计,以识别和修复潜在的安全漏洞。 * **具体情况:** 以上建议只是一些通用的指导原则。你需要根据你的具体情况进行调整。 * **复杂性:** 构建一个完全安全的系统非常复杂。如果你不确定如何操作,请咨询安全专家。 **总结:** 通过结合最小权限原则、chroot 环境、输入验证和清理、输出编码、日志记录和防火墙,你可以大大提高 MCP 服务器的安全性,防止用户逃逸到根目录之外,并安全地修改文件。记住,安全是一个持续的过程,需要不断地监控和改进。
eNSP Automation MCP
Generates eNSP network topologies, deploys Huawei VRP configurations, and provides verification plans for lab scenarios.
notepm-mcp-server
An unofficial MCP server that enables AI assistants to search, read, create, and update pages in your NotePM workspace.
logicmonitor-mcp
Exposes the LogicMonitor REST API as MCP tools with per-request LMv1 authentication, enabling querying of devices, alerts, reports, and more.
ncbi-mcp
美国国立卫生研究院 (NIH) 国家生物技术信息中心 (NCBI) 的 MCP 服务器
AdCrunch MCP Server
Enables querying ad campaign performance and setup across Meta, TikTok, and Google Ads using natural language through AI agents.
poc5-mcp-http-remote
This MCP server provides a Streamable HTTP endpoint with bearer token authentication, exposing echo and add tools, and an info resource for remote client integration.
agent-eyes
MCP server that wraps Playwright to give AI agents eyes on the web, enabling browser search, navigation, extraction, and interaction with intelligent LLM-based DOM extraction and skill caching.
Jira Local MCP
Local MCP server for Jira Server/Data Center providing read-only tools and queued write operations that require manual approval via a local web UI.