Seedance MCP
by dpspace2050
README.md
# Seedance MCP
火山方舟 Seedance 2.0 视频生成 MCP Server,支持 Claude Code 和 Codex。
项目真实测试经验、故障判断和 Prompt 约定见 [PROJECT_KNOWLEDGE.md](PROJECT_KNOWLEDGE.md)。
## 工具列表
| 工具 | 功能 |
|---|---|
| `seedance_create_video` | 创建视频生成任务 |
| `seedance_get_task` | 查询任务状态 |
| `seedance_wait_task` | 轮询等待任务完成或超时 |
| `seedance_download_video` | 下载生成视频到本地 |
| `seedance_create_and_wait` | 一步创建 + 等待完成 |
## API 格式
通过 `SEEDANCE_API_FORMAT` 支持两种 API 格式:
| 格式 | 适用场景 | 创建路径 | 请求体 | 成功状态 |
|---|---|---|---|---|
| `openai` | tokease.cn 等 OpenAI 兼容代理 | `POST /v1/videos/generations` | `{"model":..., "prompt":...}` | `completed` |
| `volcengine` | 火山方舟官方 API | `POST /contents/generations/tasks` | `{"model":..., "content":[...]}` | `succeeded` |
未设置 `SEEDANCE_API_FORMAT` 时,根据 `SEEDANCE_BASE_URL` 自动推断(含 `tokease` → `openai`,否则 → `volcengine`)。
## 环境变量
| 变量 | 必填 | 默认值 | 说明 |
|---|---|---|---|
| `SEEDANCE_API_KEY` | 是 | — | API Key |
| `SEEDANCE_BASE_URL` | 否 | `https://www.tokease.cn` | API 基础 URL |
| `SEEDANCE_MODEL` | 否 | `Seedance 2.0/uP` | 模型 ID |
| `SEEDANCE_API_FORMAT` | 否 | 自动推断 | `openai` 或 `volcengine` |
| `SEEDANCE_TRUST_ENV` | 否 | `false` | httpx 是否读取系统代理/证书环境变量 |
| `SEEDANCE_TIMEOUT` | 否 | `60` | HTTP 请求超时(秒) |
| `SEEDANCE_DOWNLOAD_DIR` | 否 | `outputs` | 视频下载目录(建议使用绝对路径) |
| `SEEDANCE_POLL_INTERVAL` | 否 | `10` | 轮询间隔(秒) |
| `SEEDANCE_WAIT_TIMEOUT` | 否 | `600` | 最大等待超时(秒) |
> ⚠️ **下载目录建议**:`SEEDANCE_DOWNLOAD_DIR` 为相对路径时,产物位置取决于 MCP 宿主的当前工作目录,不同宿主可能下载到不同位置。**建议在配置中显式指定绝对路径**,例如 `"SEEDANCE_DOWNLOAD_DIR": "D:/Neo/Neo/seedance-mcp/outputs"`。
## 安装
```bash
cd D:/Neo/Neo/seedance-mcp
pip install -e ".[dev]"
```
## 配置
### Claude Code(推荐:绝对 Python 路径)
```json
{
"mcpServers": {
"seedance": {
"command": "C:/Users/13056/AppData/Local/Programs/Python/Python314/python.exe",
"args": ["-m", "seedance_mcp"],
"cwd": "D:/Neo/Neo/seedance-mcp",
"env": {
"SEEDANCE_API_KEY": "YOUR_API_KEY",
"SEEDANCE_BASE_URL": "https://www.tokease.cn",
"SEEDANCE_MODEL": "Seedance 2.0/uP",
"SEEDANCE_API_FORMAT": "openai",
"SEEDANCE_TRUST_ENV": "false",
"SEEDANCE_DOWNLOAD_DIR": "D:/Neo/Neo/seedance-mcp/outputs"
}
}
}
}
```
### Codex(TOML 配置)
添加到 `~/.codex/config.toml`:
```toml
[mcp_servers.seedance]
command = "C:/Users/13056/AppData/Local/Programs/Python/Python314/python.exe"
args = ["-m", "seedance_mcp"]
cwd = "D:/Neo/Neo/seedance-mcp"
[mcp_servers.seedance.env]
SEEDANCE_API_KEY = "YOUR_API_KEY"
SEEDANCE_BASE_URL = "https://www.tokease.cn"
SEEDANCE_MODEL = "Seedance 2.0/uP"
SEEDANCE_API_FORMAT = "openai"
SEEDANCE_TRUST_ENV = "false"
SEEDANCE_DOWNLOAD_DIR = "D:/Neo/Neo/seedance-mcp/outputs"
```
### 火山方舟官方 API
切换 `SEEDANCE_API_FORMAT` 和 `SEEDANCE_BASE_URL`:
```json
{
"SEEDANCE_BASE_URL": "https://ark.cn-beijing.volces.com/api/v3",
"SEEDANCE_MODEL": "doubao-seedance-2-0-260128",
"SEEDANCE_API_FORMAT": "volcengine"
}
```
## 验证状态
| 能力 | 状态 |
|---|---|
| 文生视频(tokease + openai 格式) | ✅ 已通过真实 API 验证 |
| 文生视频(火山官方 volcengine 格式) | ⏳ 待验证(需要官方 key) |
| 图生视频(openai 格式) | ✅ 已通过真实 API 验证(task `task_hbcb54n6avFPb5JYP0zGaFuG30khCSmA`,顶层 `image_url` 字段可用) |
| 图生视频(volcengine 格式) | ⏳ 待验证 |
> ⚠️ **图生视频超时提示**:图生视频生成耗时约 130-150 秒,可能超过 MCP 宿主默认工具调用超时。调用 `seedance_create_and_wait` 时建议显式传 `timeout_seconds=180` 或更高,并确认宿主自身 tool timeout 足够长。代码层面 `SEEDANCE_WAIT_TIMEOUT` 默认 600 秒,不存在代码默认 120 秒的问题。
## 图生视频可选冒烟测试
默认不运行图生视频真实测试,避免消耗额度。需要时可手动触发:
**Linux / macOS:**
```bash
SEEDANCE_RUN_IMAGE_API=1 \
SEEDANCE_TEST_IMAGE_URL=https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/PNG_transparency_demonstration_1.png/280px-PNG_transparency_demonstration_1.png \
SEEDANCE_API_KEY=sk-xxx \
SEEDANCE_RUN_REAL_API=1 \
python test_official_api.py
```
**Windows PowerShell:**
```powershell
$env:SEEDANCE_API_KEY = "sk-xxx"
$env:SEEDANCE_RUN_REAL_API = "1"
$env:SEEDANCE_RUN_IMAGE_API = "1"
$env:SEEDANCE_TEST_IMAGE_URL = "https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/PNG_transparency_demonstration_1.png/280px-PNG_transparency_demonstration_1.png"
python test_official_api.py
```
| 参数 | 说明 |
|---|---|
| `SEEDANCE_RUN_IMAGE_API` | 设为 `1` 启用图生视频真实测试 |
| `SEEDANCE_TEST_IMAGE_URL` | 测试用图片 URL |
| 输出文件名 | `test_image_to_video.mp4` |
| 推荐超时 | `timeout_seconds >= 180` |
## 安全
- API Key 不完整打印(遮蔽为 `abcd...wxyz`)
- API Key 不写入 README 示例(使用 `YOUR_API_KEY` 占位)
- API Key 不出现在测试快照中
- `__repr__()` 遮蔽 key
- 下载文件名经过清洗:阻止路径穿越,强制 `.mp4` 扩展名
- `.mcp.json` 在 `.gitignore` 中,不会提交真实 key
## 故障排除
| 错误 | 原因 | 修复方式 |
|---|---|---|
| `401 Unauthorized` | API Key 无效或缺失 | 检查 env 配置中的 `SEEDANCE_API_KEY` |
| `429 Too Many Requests` | 请求频率超限 | 等待后重试,或减少并发请求 |
| `Timeout` | 网络或 API 响应慢 | 增大 `SEEDANCE_TIMEOUT` 或 `SEEDANCE_WAIT_TIMEOUT` |
| stdout 污染 | 服务端日志泄露到 stdout | 所有日志走 stderr;如 MCP 异常,检查是否有 `print()` 未指定 `file=sys.stderr` |
| `Model not authorized` | API Key 无模型权限 | 在火山方舟控制台启用 Seedance 模型 |
| `No task_id returned` | API 响应格式变更 | 检查响应中的 `raw` 字段,必要时更新解析逻辑 |
| `uv cache error` | uv 缓存目录不可写 | 改用绝对 Python 路径配置 |
| `Non-JSON response` | SSL/代理不匹配或 base URL 错误 | 设置 `SEEDANCE_TRUST_ENV=false` 或检查代理设置 |
| `completed` 状态未识别 | terminal_states 过期 | 确保 `tools.py` 的 terminal_states 包含 `"completed"` |
| 视频下载到意外目录 | `SEEDANCE_DOWNLOAD_DIR` 使用相对路径 | 配置中显式指定绝对路径 |
## 运行测试
```bash
cd D:/Neo/Neo/seedance-mcp
pip install -e ".[dev]"
pytest tests/ -v
```
## MCP 验证
使用 MCP Inspector 验证(推荐绝对 Python 路径):
```bash
npx @modelcontextprotocol/inspector C:/Users/13056/AppData/Local/Programs/Python/Python314/python.exe -m seedance_mcp
```
预期:服务启动,`tools/list` 返回 5 个工具,mock 调用返回清晰错误而不崩溃。
## 项目结构
```
D:\Neo\Neo\seedance-mcp\
pyproject.toml
README.md
.gitignore
.mcp.json # 本地专用,已 gitignore
.mcp.example.json # 可安全提交
src/seedance_mcp/
__init__.py
__main__.py # python -m seedance_mcp
server.py # FastMCP + 工具注册
config.py # 环境变量读取 + api_format 推断
client.py # HTTP 客户端 + 响应解析(双格式)
tools.py # 业务逻辑 + 终态处理
safe_path.py # 下载路径清洗
tests/
test_config.py
test_client_payload.py
test_response_parsing.py
test_safe_path.py
test_tools_schema.py # 含 completed 状态回归测试
test_mcp_smoke.py
test_download.py
test_http_requests.py
test_api_format.py # 双格式测试
test_wrapper_calls.py
```
## 冒烟测试产物
真实 API 冒烟测试会生成 `outputs/test_smoke.mp4`(文生视频)和 `outputs/test_image_to_video.mp4`(图生视频)。`outputs/` 目录已在 `.gitignore` 中,可手动删除整个 `outputs` 目录,或用命令:
```powershell
Remove-Item -LiteralPath "outputs" -Recurse -Force
```
TDQS
A4.1/5.0
Scored across 6 tools
Disambiguation5/5
Each tool has a distinct purpose: creating videos (two variants for combined vs. separate steps), downloading, querying status, waiting for completion, and retrieving configuration. No overlap.
Naming Consistency5/5
All tools follow a consistent 'seedance_verb_noun' pattern (e.g., seedance_create_video, seedance_download_video), making predictions easy.
Tool Count5/5
6 tools cover the essential workflow for a video generation service without being excessive or insufficient.
Completeness4/5
Covers the main create-poll-download cycle and config diagnostics. Missing a cancel or list operation, but the core lifecycle is well-supported.
Maintenance
ActivityInactive
ResponsivenessNo issues