Scnet 文档转换 MCP 服务
基于 Scnet 文档格式转化 API 实现的 MCP(Model Context Protocol)服务,提供 stdio 通信模式。
功能
convert_document:提交文档转换任务(PDF→Word,图片→Word/PPT)query_task:批量查询任务状态、结果下载链接或错误信息
环境要求
- Python 3.10+
- 有效的 Scnet API Key
安装与运行
作为 Python 包安装
pip install -e . # 开发模式安装
# 或使用 uvx 直接运行(无需安装)
uvx scnet-document-convert
MCP 客户端配置
将以下内容添加到 MCP 客户端配置中(如 mcp.json / claude_desktop_config.json):
{
"mcpServers": {
"scnet-document-convert": {
"command": "uvx",
"args": ["scnet-document-convert"],
"env": {
"SCNET_API_KEY": "sk-your-api-key-here",
"SCNET_API_URL": "https://api.scnet.cn/api/llm/v1"
},
"description": "Scnet 文档转换 MCP 服务:支持 PDF/图片转 Word/PPT,并查询任务结果。"
}
}
}
环境变量说明
| 变量名 | 必填 | 默认值 | 说明 |
|---|---|---|---|
SCNET_API_KEY |
是 | - | Scnet API Key(Bearer Token) |
SCNET_API_URL |
否 | https://api.scnet.cn/api/llm/v1 |
Scnet API 基础地址 |
支持的文件类型
文档格式
| 类型 | 扩展名 |
|---|---|
.pdf |
图片格式
| 类型 | 扩展名 |
|---|---|
| JPEG | .jpg / .jpeg |
| PNG | .png |
| BMP | .bmp |
| TIFF | .tiff / .tif |
| WebP | .webp |
说明:请根据转换类型(
ocrType)选择对应的输入文件:
PDF_TO_WORD:输入 PDFIMAGE_TO_WORD/IMAGE_TO_PPT:输入图片
接口说明
1. convert_document —— 提交文档转换任务
提交文档转换任务到 Scnet 服务,返回 task_id 用于后续结果查询。
请求参数
必填参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
ocrType |
string |
是 | 转换类型:PDF_TO_WORD、IMAGE_TO_WORD、IMAGE_TO_PPT |
filePath |
string |
否 | 本地待转换文件绝对路径,与 fileUrl 二选一 |
fileUrl |
string |
否 | 公网可访问的文件下载地址,与 filePath 二选一 |
filePath与fileUrl必须至少提供一个,否则返回参数错误。
可选参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
pageIndex |
string |
否 | 页码范围,如 "1" 或 "1-5",默认全部解析 |
isTableCls |
boolean |
否 | 是否开启表格细分处理,默认 false |
isDocOri |
boolean |
否 | 是否开启文档方向矫正,默认 false |
enforceSeal |
boolean |
否 | 是否开启强制二次印章检测,默认 false |
isInlineFormula |
boolean |
否 | 是否开启行内公式检测,默认 false |
返回结构
| 字段名 | 类型 | 说明 |
|---|---|---|
output |
object |
任务提交结果 |
output.task_status |
string |
任务状态:pending / running / succeeded / failed / unknown |
output.task_id |
string |
任务唯一标识,用于后续结果查询 |
request_id |
string |
请求唯一标识 |
响应示例
成功响应
{
"output": {
"task_status": "pending",
"task_id": "0385dc79-5ff8-4d82-bcb6-xxxxxx"
},
"request_id": "4909100c-7b5a-9f92-bfe5-xxxxxx"
}
失败响应
{
"error": "Burst rate limit exceeded for model xxx",
"raw_response": {
"code": "10011",
"msg": "Burst rate limit exceeded for model xxx"
}
}
2. query_task —— 查询任务状态和结果
批量查询一个或多个文档转换任务的状态、结果下载链接或错误信息。
请求参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_ids |
list[string] |
是 | 任务 ID 列表(从 convert_document 返回的 task_id) |
返回结构
| 字段名 | 类型 | 说明 |
|---|---|---|
data |
array |
任务结果列表,每个 task_id 对应一个元素 |
data[].request_id |
string |
请求唯一标识 |
data[].output |
object |
任务结果 |
data[].output.task_id |
string |
任务唯一标识 |
data[].output.task_status |
string |
任务状态 |
data[].output.submit_time |
string |
任务提交时间 |
data[].output.end_time |
string |
任务结束时间(成功/失败时返回) |
data[].output.results |
array[string] |
结果文件下载地址列表(成功时返回) |
data[].output.error_code |
string |
错误码(失败时返回) |
data[].output.error_message |
string |
错误信息(失败时返回) |
响应示例
任务成功
{
"data": [
{
"output": {
"results": [
"https://minio.example.com/.../document.docx?X-Amz-Signature=xxxxxx"
],
"task_id": "2056703208598626305",
"task_status": "succeeded",
"submit_time": "2026-05-19 19:47:11",
"end_time": "2026-05-19 19:47:40"
},
"request_id": "5e726f4f7d518259"
}
]
}
任务进行中
{
"data": [
{
"request_id": "8ae698ba-df2d-966c-abcf-xxxxxx",
"output": {
"task_id": "e56d806f-76f9-4037-aefa-xxxxxx",
"task_status": "running",
"submit_time": "2026-04-20 19:33:50.425"
}
}
]
}
任务失败
{
"data": [
{
"request_id": "c61fe158-c0de-40f0-b4d9-964625119ba4",
"output": {
"task_id": "86ecf553-d340-4e21-xxxxxxxxx",
"task_status": "failed",
"submit_time": "2025-11-11 11:46:28.116",
"end_time": "2025-11-11 11:46:28.255",
"error_code": "10011",
"error_message": "Burst rate limit exceeded for model xxx"
}
}
]
}
任务状态说明
| 状态 | 描述 |
|---|---|
pending |
任务已提交,等待处理 |
running |
任务处理中 |
succeeded |
任务处理成功(results 包含下载地址) |
failed |
任务处理失败(error_code 和 error_message 提供详情) |
unknown |
任务不存在或未知状态 |
错误码说明
| 错误码 | 描述 |
|---|---|
10001 |
Unknown error |
10002 |
Unsupported modal type xxx |
10003 |
Unsupported provider xxx |
10004 |
Unsupported model xxx |
10005 |
Model xxx not found |
10006 |
Task not found |
10007 |
Concurrency conflict for request, please try again later |
10008 |
Provider xxx process error |
10009 |
Model xxx route failed |
10010 |
Illegal content detected by content approval |
10011 |
Burst rate limit exceeded for model xxx |
10012 |
An system error has occurred, please try again later |
10013 |
Parameter illegal |
10014 |
Incorrect API key provided |
10015 |
Task timeout, please try again later |
使用示例
本地调用示例
# 安装依赖
pip install -e .
# 设置环境变量并启动服务
export SCNET_API_KEY="sk-your-api-key-here"
python server.py
Python 客户端调用
参考项目中的 client_test.py,示例如下:
import asyncio
import json
import os
from mcp.client.stdio import stdio_client, StdioServerParameters
from mcp.client.session import ClientSession
async def main():
server_params = StdioServerParameters(
command="python",
args=["server.py"],
env={**os.environ, "SCNET_API_KEY": "sk-your-api-key-here"},
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
# 提交任务
result = await session.call_tool(
"convert_document",
arguments={
"ocrType": "PDF_TO_WORD",
"fileUrl": "https://example.com/document.pdf",
"pageIndex": "1-3",
},
)
resp = json.loads(result.content[0].text)
task_id = resp["output"]["task_id"]
print(f"Task ID: {task_id}")
# 查询任务
query_result = await session.call_tool(
"query_task",
arguments={"task_ids": [task_id]},
)
print(query_result.content[0].text)
asyncio.run(main())
注意事项
filePath与fileUrl二选一,必须至少提供一个。- 转换后的文件下载地址为临时授权链接,请及时下载使用。
- 任务提交后需要通过
query_task轮询查询结果。 - 请根据
ocrType选择正确的输入文件类型。
Metadata
Release files for scnet-document-convert 1.0.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| scnet_document_convert-1.0.5.tar.gz | 7.6 kB | Without provenance | Details for scnet_document_convert-1.0.5.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| scnet_document_convert-1.0.5-py3-none-any.whl | Python 3 | none | any | Details for scnet_document_convert-1.0.5-py3-none-any.whl |
Total release size: 15.1 kB
Release files / scnet_document_convert-1.0.5.tar.gz
| Download URL | scnet_document_convert-1.0.5.tar.gz |
|---|---|
| Size | 7.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8c8ebe9b195e101d51b21a6068abe62d1f01b9a5bc6741e8d591cc5ad31da46d
|
|
BLAKE2b-256 checksum How to use checksums |
df88be6663bd957cbb06f6f5bdfbbae30589508084f4e8c15099900ea3880b4d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / scnet_document_convert-1.0.5-py3-none-any.whl
| Download URL | scnet_document_convert-1.0.5-py3-none-any.whl |
|---|---|
| Size | 7.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5b241197a8ce373bcdbdb32566d44882d8da09bac4c802b30035eaabc7e627c5
|
|
BLAKE2b-256 checksum How to use checksums |
42cad363c18d52dc2dd354945f956d106a316b54ef076dcd43648721d992ece4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for scnet-document-convert 1.0.5
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.