将远程工具贡献给ToolUniverse¶
本指南介绍了如何向 ToolUniverse 仓库贡献远程工具。远程工具运行在独立的服务器上,并通过 MCP(模型上下文协议)或 REST API 进行访问。
备注
关键区别:远程工具无需修改``__init__.py``,但您必须提供一个可公开访问的服务器或详细的部署说明。
快速概览¶
贡献远程工具的10个步骤:
环境设置 - 分叉、克隆、安装依赖项
选择实现方式 - 独立服务器 vs register_mcp_tool
创建 MCP 服务器 - 使用您的工具逻辑实现服务器
创建配置 - JSON 文件位于
data/remote_tools/xxx_tools.json部署服务器 - 使其公开可访问
编写测试 - 使用模拟服务器的集成测试
代码质量 - 预提交钩子(自动)
文档 - 服务器README和API文档
创建示例 - 在``examples/``中创建工作示例
提交 PR - 包括服务器代码和部署文档
分步指南¶
步骤 1:环境设置¶
# Fork the repository on GitHub first
git clone https://github.com/yourusername/ToolUniverse.git
cd ToolUniverse
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install development dependencies
pip install -e ".[dev]"
# Install pre-commit hooks
./setup_precommit.sh
步骤 2:选择实施方案¶
选项A:独立的MCP服务器(推荐) - 创建独立服务器(任意语言) - 更灵活且易于维护 - 服务器代码存放于``src/tooluniverse/remote/``
选项 B:register_mcp_tool 装饰器 - Python 类同时作为本地工具和 MCP 工具 - 更简单但灵活性较低 - 适用于简单工具
本指南重点介绍**选项A**(独立服务器)。
步骤 3:创建 MCP 服务器¶
创建服务器目录:src/tooluniverse/remote/my_service/
服务器结构: .. code-block:: text
src/tooluniverse/remote/my_service/ ├── __init__.py ├── server.py # 主服务器文件 ├── tools.py # 工具实现 ├── requirements.txt # 服务器依赖项 ├── README.md # 部署说明 └── docker-compose.yml # 可选:Docker 设置
示例 server.py: .. code-block:: python
从 fastapi 导入 FastAPI 从 tooluniverse.smcp 导入 SMCP 导入 uvicorn
app = FastAPI(title=”我的服务MCP服务器”) mcp = SMCP()
@mcp.tool(“my_remote_tool”) def my_remote_tool(input_text: str, operation: str = “uppercase”) -> dict:
“””使用指定的操作转换文本。””” 如果操作 == “uppercase”:
result = input_text.upper()
- elif 操作 == “小写”:
result = input_text.lower()
- 否则:
raise ValueError(f”未知操作: {operation}”)
- 返回 {
“result”: 结果, “operation”: 操作, “success”: True
请提供具体的英文文本内容,我将为您进行翻译。
@mcp.tool(“health_check”) def health_check() -> dict:
“””健康检查端点。””” return {“status”: “健康”, “service”: “my_service”}
# 挂载 MCP 端点 app.mount(“/mcp”, mcp.app)
- 如果 __name__ == “__main__”:
uvicorn.run(app, host=”0.0.0.0”, port=8000)
requirements.txt: .. code-block:: text
fastapi>=0.100.0 uvicorn>=0.20.0 tooluniverse>=1.0.0
步骤 4:创建配置文件¶
创建 src/tooluniverse/data/remote_tools/my_service_tools.json:
[
{
"type": "RemoteTool",
"name": "my_remote_tool",
"description": "Convert text using various operations via remote service",
"parameter": {
"type": "object",
"properties": {
"input_text": {
"type": "string",
"description": "Text to process"
},
"operation": {
"type": "string",
"enum": ["uppercase", "lowercase"],
"default": "uppercase",
"description": "Operation to perform on the text"
}
},
"required": ["input_text"]
},
"remote_info": {
"server_type": "MCP",
"transport": "http",
"url": "https://my-service.example.com/mcp",
"code_url": "https://github.com/yourusername/ToolUniverse/tree/main/src/tooluniverse/remote/my_service"
},
"examples": [
{
"description": "Convert text to uppercase",
"arguments": {
"input_text": "hello world",
"operation": "uppercase"
}
}
],
"tags": ["text", "remote", "mcp"],
"author": "Your Name <your.email@example.com>",
"version": "1.0.0"
}
]
步骤 5:部署服务器¶
选项A:云部署(推荐) - 部署至云平台(AWS、GCP、Azure、Heroku等) - 提供公共URL - 包含部署文档
选项 B:自托管与文档支持 - 提供详细的设置说明 - 包括 Docker 配置 - 记录需求和依赖项
示例部署文档 (README.md): .. code-block:: markdown
# 我的服务 MCP 服务器
## 快速开始
`bash # 安装依赖项 pip install -r requirements.txt `## Docker 部署
`bash # 构建镜像 docker build -t my-service . `# 运行容器 docker run -p 8000:8000 my-service ```
## 环境变量
PORT: 服务器端口(默认值:8000)
HOST: 服务器主机(默认值:0.0.0.0)
## API 端点
GET /mcp/tools - 列出可用工具
POST /mcp/tools/my_remote_tool - 执行工具
步骤 6:编写测试¶
创建 tests/integration/test_my_remote_tool.py:
import pytest
from unittest.mock import patch, Mock
from tooluniverse import ToolUniverse
class TestMyRemoteTool:
def setup_method(self):
self.tu = ToolUniverse()
self.tu.load_tools()
@patch('requests.post')
def test_remote_tool_success(self, mock_post):
"""Test successful remote tool execution."""
# Mock server response
mock_response = Mock()
mock_response.json.return_value = {
"result": "HELLO",
"operation": "uppercase",
"success": True
}
mock_response.status_code = 200
mock_post.return_value = mock_response
# Test tool execution
result = self.tu.run({
"name": "my_remote_tool",
"arguments": {
"input_text": "hello",
"operation": "uppercase"
}
})
assert result["success"] is True
assert result["result"] == "HELLO"
@patch('requests.post')
def test_remote_tool_error(self, mock_post):
"""Test remote tool error handling."""
# Mock server error
mock_response = Mock()
mock_response.json.return_value = {
"error": "Unknown operation: invalid",
"success": False
}
mock_response.status_code = 400
mock_post.return_value = mock_response
result = self.tu.run({
"name": "my_remote_tool",
"arguments": {
"input_text": "hello",
"operation": "invalid"
}
})
assert result["success"] is False
assert "error" in result
def test_tool_discovery(self):
"""Test that tool is discovered correctly."""
assert "my_remote_tool" in self.tu.all_tool_dict
运行测试:.. code-block:: bash
pytest tests/integration/test_my_remote_tool.py -v
第七步:代码质量检查(自动)¶
在提交代码时,预提交钩子会自动运行:
git add .
git commit -m "feat: add MyRemoteTool service"
# Pre-commit will run: Black, Flake8, Ruff, etc.
步骤 8:文档编制¶
服务器文档 (README.md): .. code-block:: markdown
工具文档: 在服务器代码中的工具函数添加全面的文档字符串。
步骤9:创建示例¶
创建 examples/my_remote_tool_example.py:
"""Example usage of MyRemoteTool."""
from tooluniverse import ToolUniverse
def main():
# Initialize ToolUniverse
tu = ToolUniverse()
tu.load_tools()
# Test the remote tool
test_cases = [
{"input_text": "hello world", "operation": "uppercase"},
{"input_text": "HELLO WORLD", "operation": "lowercase"},
{"input_text": "Python", "operation": "uppercase"},
]
for i, test_case in enumerate(test_cases, 1):
print(f"\nTest {i}: {test_case}")
result = tu.run({
"name": "my_remote_tool",
"arguments": test_case
})
if result.get("success"):
print(f"✅ Result: {result['result']}")
else:
print(f"❌ Error: {result.get('error', 'Unknown error')}")
if __name__ == "__main__":
main()
第10步:提交拉取请求¶
# Create feature branch
git checkout -b feature/add-my-remote-tool
# Add all files
git add src/tooluniverse/remote/my_service/
git add src/tooluniverse/data/remote_tools/my_service_tools.json
git add tests/integration/test_my_remote_tool.py
git add examples/my_remote_tool_example.py
# Commit with descriptive message
git commit -m "feat: add MyRemoteTool MCP service
- Implement MCP server with text processing tools
- Add comprehensive integration tests
- Include deployment documentation and examples
- Support uppercase/lowercase text conversion
Closes #[issue-number]"
# Push and create PR
git push origin feature/add-my-remote-tool
PR模板: .. code-block:: markdown
## 描述
此PR新增了MyRemoteTool,一个用于文本处理的MCP服务器。
## 修改内容
✅ MCP 服务器:完整的服务器实现位于 remote/my_service/
✅ 配置:位于 data/remote_tools/ 的 JSON 配置
✅ 测试:使用模拟服务器进行集成测试
✅ 文档:服务器README和API文档
✅ 示例:工作使用示例
✅ 部署:Docker 和云部署说明
## 服务器信息
协议:MCP(模型上下文协议)
传输:HTTP
部署:[云平台 / 自托管]
## 测试
`bash pytest tests/integration/test_my_remote_tool.py python examples/my_remote_tool_example.py `## 部署
请参阅 src/tooluniverse/remote/my_service/README.md 了解部署说明。
## 清单
[x] 测试在本地通过
[x] 服务器可公开访问或已提供部署文档
[x] 代码遵循项目风格指南
[x] 文档已完成
[x] 示例按预期运行
与本地工具的主要区别¶
|--------|————-|--------------|
| __init__.py | Must modify 4 locations | No modification needed |
| File Location | src/tooluniverse/xxx_tool.py | src/tooluniverse/remote/xxx/ |
| Config Location | data/xxx_tools.json | data/remote_tools/xxx_tools.json |
| Server Deployment | Not needed | Must provide public access |
| Testing | Unit tests | Integration tests (mock server) |
| Dependencies | Python only | Server + dependencies |
常见错误¶
** Server not accessible** - Tool will fail with connection errors - Solution: Ensure server is publicly accessible or provide clear deployment docs
** Wrong config location**
- Config must be in data/remote_tools/
- Not in data/
** Missing server code** - Include complete server implementation - Don’t just provide config
** No deployment documentation** - Users need to know how to run the server - Include setup and deployment instructions
** Poor error handling** - Server should return proper error responses - Tool should handle network failures gracefully
故障排除¶
连接错误:服务器无法访问 .. code-block:: python
# 测试服务器连接 import requests response = requests.get(”https://your-server.com/mcp/tools”) print(f”状态码: {response.status_code}”) print(f”响应内容: {response.json()}”)
在 ToolUniverse 中未找到工具 .. code-block:: python
# 检查是否已加载配置 从 tooluniverse 导入 ToolUniverse tu = ToolUniverse() tu.load_tools()
print(“my_remote_tool” in tu.all_tool_dict) # Should be True
服务器返回意外格式 - 确保服务器遵循MCP协议 - 检查响应是否符合预期的架构 - 验证工具参数的有效性
下一步¶
成功提交您的远程工具后:
Local Tools: 将本地工具贡献至 ToolUniverse - Learn about contributing local tools
MCP Integration: MCP Integration - MCP integration patterns
Architecture: ToolUniverse 架构 - Understand ToolUniverse internals
Comparison: Review the tool type comparison table in Contributing to ToolUniverse
小技巧
成功提示:从简单的服务器开始,使用真实部署进行充分测试,并提供清晰的文档以帮助用户运行您的服务!