将远程工具贡献给ToolUniverse

本指南介绍了如何向 ToolUniverse 仓库贡献远程工具。远程工具运行在独立的服务器上,并通过 MCP(模型上下文协议)或 REST API 进行访问。

备注

关键区别:远程工具无需修改``__init__.py``,但您必须提供一个可公开访问的服务器或详细的部署说明。

快速概览

贡献远程工具的10个步骤:

  1. 环境设置 - 分叉、克隆、安装依赖项

  2. 选择实现方式 - 独立服务器 vs register_mcp_tool

  3. 创建 MCP 服务器 - 使用您的工具逻辑实现服务器

  4. 创建配置 - JSON 文件位于 data/remote_tools/xxx_tools.json

  5. 部署服务器 - 使其公开可访问

  6. 编写测试 - 使用模拟服务器的集成测试

  7. 代码质量 - 预提交钩子(自动)

  8. 文档 - 服务器README和API文档

  9. 创建示例 - 在``examples/``中创建工作示例

  10. 提交 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

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协议 - 检查响应是否符合预期的架构 - 验证工具参数的有效性

下一步

成功提交您的远程工具后:

小技巧

成功提示:从简单的服务器开始,使用真实部署进行充分测试,并提供清晰的文档以帮助用户运行您的服务!