MCP工具箱
有用的小型MCP服务器列表,包括: - docx_replace:替换Word文档中的标签 - yt-dlp:根据章节提取章节和字幕 - mermaid:使用mermaidchart.com API生成和渲染图像
服务介绍
有用的模型上下文协议服务器 (MCPS)
一系列独立的 Python 脚本,实现各种实用功能的模型上下文协议 (MCP) 服务器。每个服务器提供专门的工具,可以被支持 MCP 协议的 AI 助手或其他应用程序使用。
什么是 MCP?
模型上下文协议 (MCP) 是一种标准化的方式,用于 AI 助手与外部工具和服务进行交互。它允许 AI 模型通过调用由 MCP 服务器提供的专门函数来扩展其能力。通信通过标准输入/输出(stdio)使用 JSON 消息进行。
可用的服务器
每个 MCP 服务器设计为使用像 uv 这样的 Python 环境管理器运行。
YouTube 数据提取器 (ytdlp)
一个使用 yt-dlp 从 YouTube 视频中提取信息的服务器。
工具:
- 提取章节:从 YouTube 视频中获取章节信息。
- 提取字幕:从 YouTube 视频中获取特定章节或整个视频的字幕。
MCP 服务器配置:
"mcpServers": {
"ytdlp": {
"name": "youtube", // Optional friendly name for the client
"command": "uv",
"args": [
"run",
"--directory", "<path/to/repo>/useful-mcps/ytdlp", // Path to the MCP directory containing pyproject.toml
"--", // Separator before script arguments, if any
"ytdlp_mcp" // Match the script name defined in pyproject.toml [project.scripts]
]
// 'cwd' is not needed when using --directory
}
}
Word 文档处理器 (docx_replace)
一个用于处理 Word 文档的服务器,包括模板处理和 PDF 转换。
工具:
- 处理模板:替换 Word 模板中的占位符并管理内容块。
- 获取模板键:从 Word 文档模板中提取所有替换键。
- 转换为 PDF:将 Word 文档 (docx) 转换为 PDF 格式。
MCP 服务器配置:
"mcpServers": {
"docx_replace": {
"name": "docx", // Optional friendly name
"command": "uv",
"args": [
"run",
"--directory", "<path/to/repo>/useful-mcps/docx_replace", // Path to the MCP directory
"--",
"docx_replace_mcp" // Match the script name defined in pyproject.toml
]
}
}
PlantUML 渲染器 (plantuml)
一个使用 PlantUML 服务器(通常通过 Docker 运行)渲染 PlantUML 图表的服务器。
工具:
- 渲染图表:将 PlantUML 文本转换为图表图像(例如 PNG)。
MCP 服务器配置:
"mcpServers": {
"plantuml": {
"name": "plantuml", // Optional friendly name
"command": "uv",
"args": [
"run",
"--directory", "<path/to/repo>/useful-mcps/plantuml", // Path to the MCP directory
"--",
"plantuml_server" // Match the script name defined in pyproject.toml
]
}
}
(注意:需要一个可访问的正在运行的 PlantUML 服务器,可能通过 Docker 管理)。
Mermaid 渲染器 (mermaid)
一个使用 mermaidchart.com API 渲染 Mermaid 图表的服务器。
工具:
- 渲染 Mermaid 图表:通过在 mermaidchart.com 上创建文档,将 Mermaid 代码转换为 PNG 图像。
MCP 服务器配置:
"mcpServers": {
"mermaid": {
"name": "mermaid", // Optional friendly name
"command": "uv",
"args": [
"run",
"--directory", "<path/to/repo>/useful-mcps/mermaid", // Path to the MCP directory
"--",
"mermaid_mcp" // Match the script name defined in pyproject.toml
],
"env": { // Environment variables needed by the MCP
"MERMAID_CHART_ACCESS_TOKEN": "YOUR_API_TOKEN_HERE"
}
}
}
(注意:需要将 Mermaid Chart API 访问令牌设置为环境变量)。
RSS 提要转 Markdown (rss2md)
一个将 RSS 提要内容转换为带日期过滤的 Markdown 格式的服务器。
工具:
- fetch_rss_to_markdown:获取 RSS 提要,按日期过滤文章,并以 Markdown 列表格式返回匹配的文章。
MCP 服务器配置:
"mcpServers": {
"mermaid": {
"name": "rss2md", // Optional friendly name
"command": "uv",
"args": [
"run",
"--directory", "<path/to/repo>/useful-mcps/rss2md", // Path to the MCP directory
"--",
"rss2md_mcp" // Match the script name defined in pyproject.toml
],
"env": { // Environment variables needed by the MCP
}
}
}
安装
安装说明未提供,请参考具体项目的文档或 README 文件。
-
克隆仓库:
git clone https://github.com/daltonnyx/useful-mcps.git # 如果不同,请替换为实际的仓库URL cd useful-mcps -
安装
uv: 如果你还没有uv,请安装它:pip install uv # 或者按照 https://github.com/astral-sh/uv 的说明进行安装 -
依赖项: 依赖项是通过每个MCP的
pyproject.toml文件管理的。
当你第一次使用--directory参数运行MCP时,uv run通常会自动在虚拟环境中安装这些依赖项。
使用
运行服务器
建议使用 uv run --directory <路径> 指向特定MCP的目录来运行每个MCP服务器。uv 会根据该目录中的 pyproject.toml 文件处理虚拟环境和依赖项。
示例(从 useful-mcps 根目录开始):
# Run the YouTube MCP
uv run --directory ./ytdlp ytdlp_mcp
# Run the Mermaid MCP (ensure token is set in environment)
uv run --directory ./mermaid mermaid_mcp
或者,配置你的MCP客户端(如上面的JSON配置示例),直接执行 uv run --directory ... 命令。
连接到服务器
配置你的MCP客户端应用程序,使用 "MCP服务器配置" 示例中所示的 command 和 args 结构来启动所需的服务器。确保 command 指向你的 uv 可执行文件,并且 args 正确指定了带有MCP文件夹路径和要运行的脚本名称的 --directory。使用 env 属性传递必要的环境变量(如API令牌)。
特定工具的使用示例
这些示例展示了你会发送给相应MCP服务器的 call_tool 函数的 arguments。
YouTube 数据提取器
提取章节
{
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
}
提取字幕
{
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"language": "en",
"chapters": [
{
"title": "Introduction",
"start_time": "00:00:00",
"end_time": "00:01:30"
}
]
}
Word 文档处理器
处理模板
{
"template_file": "/path/to/template.docx",
"replacements": {
"name": "John Doe",
"date": "2023-05-15"
},
"blocks": {
"optional_section": true,
"alternative_section": false
},
"output_filename": "/path/to/output.docx"
}
(注意:template_file 和 docx_file 也可以接受base64编码的字符串而不是路径)
获取模板键
{
"template_file": "/path/to/template.docx"
}
转换为PDF
{
"docx_file": "/path/to/document.docx",
"pdf_output": "/path/to/output.pdf"
}
PlantUML 渲染器
渲染图表
{
"input": "participant User\nUser -> Server: Request\nServer --> User: Response",
"output_path": "/path/to/save/diagram.png"
}
(注意:input 也可以是一个 .puml 文件的路径)
Mermaid 渲染器
渲染Mermaid图表
{
"mermaid_code": "graph TD;\n A-->B;\n A-->C;\n B-->D;\n C-->D;",
"output_path": "/path/to/save/mermaid.png",
"theme": "default" // Optional, e.g., "default", "dark", "neutral", "forest"
}
开发
添加新的MCP服务器
- 为你的MCP创建一个新的目录(例如,
my_new_mcp)。 - 在目录内部,创建:
pyproject.toml:定义项目元数据、依赖项和脚本入口点(例如,[project.scripts]部分映射my_new_mcp = "my_new_mcp:main")。pyrightconfig.json:(可选)用于类型检查。- 你的主Python文件(例如,
my_new_mcp.py):使用mcp库实现MCP逻辑(参见下面的模板)。
- 实现所需的类和函数(
serve、list_tools、call_tool)。
基本模板(my_new_mcp.py):
import json
import logging
import asyncio
from typing import List, Dict, Any, Optional
# Assuming mcp library is installed or available
# from mcp import Server, Tool, TextContent, stdio_server
# Placeholder imports if mcp library structure is different
from typing import Protocol # Using Protocol as placeholder
# Placeholder definitions if mcp library isn't directly importable here
class Tool(Protocol):
name: str
description: str
inputSchema: dict
class TextContent(Protocol):
type: str
text: str
class Server:
def __init__(self, name: str): pass
def list_tools(self): pass # Decorator
def call_tool(self): pass # Decorator
def create_initialization_options(self): pass
async def run(self, read_stream, write_stream, options): pass
# Placeholder context manager
class stdio_server:
async def __aenter__(self): return (None, None) # Dummy streams
async def __aexit__(self, exc_type, exc, tb): pass
# Pydantic is often used for schema definition
# from pydantic import BaseModel
# class MyInput(BaseModel):
# param1: str
# param2: int
class MyInputSchema: # Placeholder if not using Pydantic
@staticmethod
def model_json_schema():
return {"type": "object", "properties": {"param1": {"type": "string"}, "param2": {"type": "integer"}}, "required": ["param1", "param2"]}
class MyTools:
TOOL_NAME = "my.tool"
class MyService:
def __init__(self):
# Initialize resources if needed
pass
def my_function(self, param1: str, param2: int) -> dict:
# Implement your tool functionality
logging.info(f"Running my_function with {param1=}, {param2=}")
# Replace with actual logic
result_content = f"Result: processed {param1} and {param2}"
return {"content": result_content}
async def serve() -> None:
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
server = Server("mcp-my-service")
service = MyService()
@server.list_tools()
async def list_tools() -> list[Tool]:
logging.info("list_tools called")
return [
Tool(
name=MyTools.TOOL_NAME,
description="Description of my tool",
# Use Pydantic's schema or manually define
inputSchema=MyInputSchema.model_json_schema(),
),
]
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
logging.info(f"call_tool called with {name=}, {arguments=}")
try:
if name == MyTools.TOOL_NAME:
# Add validation here if not using Pydantic
param1 = arguments.get("param1")
param2 = arguments.get("param2")
if param1 is None or param2 is None:
raise ValueError("Missing required arguments")
result = service.my_function(param1, int(param2)) # Ensure type conversion if needed
logging.info(f"Tool executed successfully: {result=}")
return [TextContent(type="text", text=json.dumps(result))] # Return JSON string
else:
logging.warning(f"Unknown tool requested: {name}")
raise ValueError(f"Unknown tool: {name}")
except Exception as e:
logging.error(f"Error executing tool {name}: {e}", exc_info=True)
# Return error as JSON
error_payload = json.dumps({"error": str(e)})
return [TextContent(type="text", text=error_payload)]
options = server.create_initialization_options()
logging.info("Starting MCP server...")
async with stdio_server() as (read_stream, write_stream):
await server.run(read_stream, write_stream, options)
logging.info("MCP server stopped.")
def main():
# Entry point defined in pyproject.toml `[project.scripts]`
try:
asyncio.run(serve())
except KeyboardInterrupt:
logging.info("Server interrupted by user.")
if __name__ == "__main__":
# Allows running directly via `python my_new_mcp.py` for debugging
main()
测试
从根目录运行测试:
pytest tests/
(确保已安装测试依赖项,可能通过 uv pip install pytest 或将 pytest 添加到某个 pyproject.toml 文件中的开发依赖项中)。
许可证
贡献
欢迎贡献!请随时提交 Pull Request。