将远程工具贡献给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/
Server Structure:
src/tooluniverse/remote/my_service/
├── __init__.py
├── server.py # Main server file
├── tools.py # Tool implementations
├── requirements.txt # Server dependencies
├── README.md # Deployment instructions
└── docker-compose.yml # Optional: Docker setup
Example server.py:
from fastapi import FastAPI
from tooluniverse.smcp import SMCP
import uvicorn
app = FastAPI(title="My Service MCP Server")
mcp = SMCP()
@mcp.tool("my_remote_tool")
def my_remote_tool(input_text: str, operation: str = "uppercase") -> dict:
"""Convert text using specified operation."""
if operation == "uppercase":
result = input_text.upper()
elif operation == "lowercase":
result = input_text.lower()
else:
raise ValueError(f"Unknown operation: {operation}")
return {
"result": result,
"operation": operation,
"success": True
}
@mcp.tool("health_check")
def health_check() -> dict:
"""Health check endpoint."""
return {"status": "healthy", "service": "my_service"}
# Mount MCP endpoints
app.mount("/mcp", mcp.app)
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
requirements.txt:
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 配置 - 记录需求和依赖项
Example deployment documentation (README.md):
# My Service MCP Server
## Quick Start
```bash
# Install dependencies
pip install -r requirements.txt
# Run server
python server.py
```
## Docker Deployment
```bash
# Build image
docker build -t my-service .
# Run container
docker run -p 8000:8000 my-service
```
## Environment Variables
- `PORT`: Server port (default: 8000)
- `HOST`: Server host (default: 0.0.0.0)
## API Endpoints
- `GET /mcp/tools` - List available tools
- `POST /mcp/tools/my_remote_tool` - Execute 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
Run tests:
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:文档编制¶
Server Documentation (README.md):
# My Service
Remote MCP server providing text processing tools.
## Features
- Text case conversion (uppercase/lowercase)
- Health check endpoint
- MCP protocol support
## API Reference
### my_remote_tool
Convert text using specified operation.
**Parameters:**
- `input_text` (string, required): Text to process
- `operation` (string, optional): Operation to perform (uppercase/lowercase)
**Returns:**
- `result` (string): Processed text
- `operation` (string): Operation performed
- `success` (boolean): Success status
工具文档: 在服务器代码中的工具函数添加全面的文档字符串。
步骤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 Template:
## Description
This PR adds MyRemoteTool, a new MCP server for text processing.
## Changes Made
- ✅ **MCP Server**: Complete server implementation in remote/my_service/
- ✅ **Configuration**: JSON config in data/remote_tools/
- ✅ **Testing**: Integration tests with mocked server
- ✅ **Documentation**: Server README and API docs
- ✅ **Examples**: Working usage examples
- ✅ **Deployment**: Docker and cloud deployment instructions
## Server Information
- **Protocol**: MCP (Model Context Protocol)
- **Transport**: HTTP
- **Deployment**: [Cloud platform / Self-hosted]
- **URL**: https://my-service.example.com/mcp
## Testing
```bash
pytest tests/integration/test_my_remote_tool.py
python examples/my_remote_tool_example.py
```
## Deployment
See `src/tooluniverse/remote/my_service/README.md` for deployment instructions.
## Checklist
- [x] Tests pass locally
- [x] Server is publicly accessible or deployment docs provided
- [x] Code follows project style guidelines
- [x] Documentation is complete
- [x] Examples work as expected
与本地工具的主要区别¶
Aspect |
Local Tools |
Remote Tools |
|---|---|---|
__init__.py |
Must modify 4 locations |
No modification needed |
File Location |
|
|
Config Location |
|
|
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
小技巧
成功提示:从简单的服务器开始,使用真实部署进行充分测试,并提供清晰的文档以帮助用户运行您的服务!