Metadata-Version: 2.5
Name: thiter-mcp
Version: 0.1.0
Summary: thiter MCP 服务：把魔搭 ModelScope 大模型包装成 MCP 工具（OpenAI 兼容 messages 格式）
Author: thiter
License: MIT
Keywords: llm,mcp,modelscope,proxy
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Requires-Dist: mcp<3,>=2.3
Description-Content-Type: text/markdown

# thiter MCP（thiter-mcp）

把魔搭 ModelScope 的大模型（默认 `qwen/qwen3.5-35b-a3b`）包装成 **MCP 工具**的代理服务，是原 OpenAI 兼容代理 `proxy.py` 的 MCP 化改造版。通过 ModelScope MCP 广场「可托管部署」后，可获得 7×24 小时稳定运行的云端 MCP 端点，不再受 Notebook 实例 8 小时到期回收的限制。

## 项目简介

thiter MCP 基于 MCP 官方 Python SDK（`mcp` 2.x，`MCPServer`）实现，暴露两个工具：

| 工具 | 说明 |
| --- | --- |
| `chat` | 与魔搭大模型对话，入参为 OpenAI 兼容的 `messages` 列表，返回 `content` / `model` / `finish_reason` / `usage` |
| `list_models` | 列出当前令牌可调用的模型 |

特性：

- **默认 stdio 传输**：满足魔搭托管部署要求（PyPI 包 + `uvx` 拉起）
- **配置全走环境变量**：令牌不落代码，`MAS_TOKEN` 等在平台侧配置注入
- **访问密钥保护**：配置 `CHUNMIAO_API_KEY` 后，所有工具调用必须携带匹配的 `key` 参数，托管端点公开可达也不会被他人白嫖额度
- **无状态、不落盘**：适配 serverless 托管环境
- **可选 HTTP 自托管**：`--transport streamable-http` 可起 Streamable HTTP 服务

## 部署指南

### 方式一：魔搭 MCP 广场托管部署（推荐，7×24 运行）

托管部署要求服务已发布到 PyPI，通过 `uvx` 拉起。步骤如下：

1. **发布到 PyPI**（需 PyPI 账号与 API Token）：

   ```bash
   uv build                      # 生成 dist/*.whl 与 *.tar.gz
   uv publish --token <你的PyPI Token>
   ```

2. **在魔搭 MCP 广场创建服务**：打开 <https://modelscope.cn/mcp/servers/create?template=customize>
   - 创建类型：自定义创建
   - 英文名称：`thiter`（将作为服务 ID 的一部分）
   - 托管类型：**可托管部署**
   - 服务配置（第二步填写）：

     ```json
     {
       "mcpServers": {
         "thiter": {
           "command": "uvx",
           "args": ["thiter-mcp"],
           "env": {
             "MAS_TOKEN": "ms-你的魔搭令牌",
             "CHUNMIAO_API_KEY": "自己定一个强随机密钥"
           }
         }
       }
     }
     ```

   - 环境变量：`MAS_TOKEN` 必填；强烈建议同时配置 `CHUNMIAO_API_KEY`（托管端点公开可达，见下方安全说明）；可选 `CHUNMIAO_MODEL`、`CHUNMIAO_BASE_URL`、`CHUNMIAO_TIMEOUT`
   - 第三步：填写 README 内容

3. 点击创建后，平台会自动执行部署检测（`uvx` 安装包 → 连接 → `list_tools`），通过后即获得托管端点（形如 `https://mcp.api-inference.modelscope.net/<你的服务名>/mcp`），任意 MCP 客户端均可接入。

### 方式二：本地 / 自托管使用

```bash
# 直接运行（需 Python >= 3.10）
pip install thiter-mcp
export MAS_TOKEN="ms-你的魔搭令牌"
thiter-mcp        # stdio 模式
```

MCP 客户端配置（Claude Desktop / Cursor / Cherry Studio 等）：

```json
{
  "mcpServers": {
    "thiter": {
      "command": "uvx",
      "args": ["thiter-mcp"],
      "env": {
        "MAS_TOKEN": "ms-你的魔搭令牌",
        "CHUNMIAO_API_KEY": "自己定一个强随机密钥"
      }
    }
  }
}
```

> 注意：客户端连接托管端点（`https://mcp.api-inference.modelscope.net/<服务名>/mcp`）时无需填 env，
> 但每次工具调用需在参数里带上 `"key": "<你的 CHUNMIAO_API_KEY>"`。

自托管 Streamable HTTP 模式：

```bash
thiter-mcp --transport streamable-http --host 0.0.0.0 --port 8000
# 端点: http://<主机>:8000/mcp
```

## 使用示例

以 MCP 客户端调用 `chat` 工具为例：

```json
{
  "tool": "chat",
  "arguments": {
    "messages": [
      {"role": "system", "content": "你是thiter 助手"},
      {"role": "user", "content": "你好，介绍一下你自己"}
    ],
    "key": "你的 CHUNMIAO_API_KEY",
    "temperature": 0.7,
    "max_tokens": 1024
  }
}
```

返回示例：

```json
{
  "content": "你好！我是thiter 助手……",
  "model": "qwen/qwen3.5-35b-a3b",
  "finish_reason": "stop",
  "usage": {"prompt_tokens": 20, "completion_tokens": 50, "total_tokens": 70}
}
```

与原 `proxy.py` 的差异：原服务暴露 OpenAI HTTP 接口（`/v1/chat/completions`），本服务改为 MCP 工具。原使用 OpenAI SDK 的客户端需迁移为 MCP 调用，`messages` 入参格式保持不变，迁移成本低。

## 环境变量

| 变量 | 必填 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `MAS_TOKEN` | 是 | 无 | 魔搭 API 访问令牌（ms-xxx） |
| `CHUNMIAO_API_KEY` | 否 | 无（不启用） | 访问密钥；配置后所有工具调用必须携带匹配的 `key` 参数 |
| `CHUNMIAO_MODEL` | 否 | `qwen/qwen3.5-35b-a3b` | 默认模型 |
| `CHUNMIAO_BASE_URL` | 否 | `https://api-inference.modelscope.cn/v1` | 上游 API 地址 |
| `CHUNMIAO_TIMEOUT` | 否 | `120` | 上游超时（秒） |
| `CHUNMIAO_TRANSPORT` | 否 | `stdio` | 传输方式（stdio / streamable-http） |
| `CHUNMIAO_HOST` / `CHUNMIAO_PORT` | 否 | `127.0.0.1` / `8000` | HTTP 模式监听地址 |

## 安全与隐私说明

- **PyPI 是完全公开的**：包发布后，代码人人可查看、下载、安装，作者/描述等元信息也会公开展示。本包不包含任何密钥（`MAS_TOKEN` / `CHUNMIAO_API_KEY` 均走环境变量），公开代码不会泄露你的令牌；如不希望公开关联信息，请使用中性的包名与作者名。
- **平台级鉴权（推荐，首选防线）**：魔搭托管部署的「高级配置」中可选择 **鉴权类型：Bearer Token**，客户端连接托管端点时必须携带该令牌，连接层即完成校验——对任意 MCP 客户端透明，无需在工具参数里传 key。有效期可选「长期有效」（令牌本身是敏感信息，切勿外泄）或「24 小时」。传输协议支持 Streamable HTTP / SSE，部署在函数计算（FC）资源上。
- **工具级访问密钥（可选第二层）**：配置 `CHUNMIAO_API_KEY` 后，所有工具调用必须携带匹配的 `key` 参数。平台已开启 Bearer Token 时可留空（省去每次传 key）；追求纵深防御时两者可同时启用。
- **YOUR_API_KEY 这类变量是上游服务的凭证**：截图中天眼查 MCP 的 `YOUR_API_KEY` 是它调用上游要用的密钥，通过部署页环境变量注入——与本服务 `MAS_TOKEN` 同一模式。代码里不内置任何默认密钥，未配置即不启用。
- **如果连代码也不想公开**：托管部署（uvx + PyPI）就不适用，改用自托管：`thiter-mcp --transport streamable-http` 部署在自己控制的服务器上，前面再挂反代 + TLS + 鉴权，完全不经过 PyPI 和魔搭广场。
- **历史令牌处理**：原 `proxy.py` 中硬编码的魔搭令牌仅存在于私有 CNB 仓库内，未对外泄露；新包已彻底移除硬编码（零密钥），旧 proxy.py 退役后该令牌即不再随代码流转。如想更稳妥，仍可在魔搭后台轮换一次，属可选操作。

## 本地开发

```bash
git clone <仓库地址>
cd thiter
uv venv && source .venv/bin/activate
uv pip install -e .
python -m thiter_mcp --help

# 端到端测试（内置 stub 上游，无需真实令牌）
PYTHONPATH=src python tests/e2e_test.py
```
