Skip to main content
Glama

GJP 云打印模板样式 MCP

基于 AgentScope 2.0.4 的云打印 MCP 服务。对外只发布三个模板样式工具,供视觉 模型根据用户图片还原模板并保存到云打印业务系统。

MCP 工具

工具

业务 API

参数

getPrintInfo

/ElectronPrintApi/GetPrintInfo

无参数;reportType 固定为 1

newStyle

/ElectronPrintApi/NewStyle

report_typestyle_name

saveStyle

/ElectronPrintApi/SaveStyle

report_typestyle_namestyle_idstyle_content

工具名使用 camelCase 发布(通过 FunctionTool(name=) 显式覆盖),确保协议层、 系统提示词和模型可见名三者统一。

Token 和 reportName 都不属于工具参数。MCP 客户端通过 Authorization: Bearer <云打印Token>X-Report-Name: <URL编码的报表分类> 两个请求头动态传入,服务端 Adapter 再把 Token 注入三个业务 API 的请求体。

动态参数

对接方每次调用 MCP 时,同时提供当前用户的 Token 和本次的 reportName:Token 放在 Authorization 头中,reportName 放在 X-Report-Name 头中(URL 编码)。两者都是每次 请求动态传入,不进入工具参数、Tool Schema 或模型上下文。

业务字段

MCP 传入方式

来源

规则

token

HTTP Authorization: Bearer <Token>

对接方

每次请求动态注入,不出现在工具 Schema 中

reportName

HTTP X-Report-Name 头(URL 编码)

对接方按入口传入

服务端 unquote 解码一次还原原文

reportType

report_type 工具参数

业务上下文

GetPrintInfo 固定为 1;NewStyle/SaveStyle 动态传入

styleName

style_name 工具参数

用户命名

NewStyle 动态传入;SaveStyle 必须沿用 NewStyle 返回值

styleId

style_id 工具参数

NewStyle 响应

SaveStyle 动态传入,必须作为字符串保留

styleContent

style_content 工具参数

模板 JSON 生成/编辑逻辑

传入完整 JSON 对象,由服务端序列化

GetPrintInfo 的完整 MCP 调用形式:

POST /mcp
Authorization: Bearer <对接方本次动态传入的Token>
X-Report-Name: %E9%94%80%E5%94%AE%E5%8D%95
Mcp-Session-Id: <initialize返回的会话ID>
Content-Type: application/json
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "getPrintInfo",
    "arguments": {}
  }
}

MCP 服务从请求头取出 Token 和 reportName,再生成业务 API 请求:

{
  "token": "<本次请求的Token>",
  "reportName": "销售单",
  "reportType": 1,
  "styleName": "",
  "styleId": "",
  "styleContent": "",
  "isDynamicBaseStyle": "",
  "baseStyleContent": "",
  "isPublic": false
}

三个 MCP 工具的动态调用关系:

getPrintInfo()
  → 读取当前分类下已有样式和打印信息

newStyle(report_type, style_name)
  → 创建空白模板,返回 styleId/reportType/styleName

saveStyle(report_type, style_name, style_id, style_content)
  → 把生成的模板 JSON 保存到已创建的样式

图片还原流程

用户图片
  → 视觉模型识别报表名称、字段和布局
  → getPrintInfo()
  → 生成完整的云打印原生模板 JSON
  → newStyle(report_type, style_name)
  → saveStyle(
        使用 newStyle 返回的 reportType/styleName/styleId,
        style_content=生成的模板 JSON 对象
    )

style_id 始终作为字符串传递,避免超大整数精度丢失。newStylesaveStyle 不自动重试;创建成功后保存失败,应使用同一 style_id 重试保存, 不能重复创建空模板。

多轮编辑

服务端按 tenant_id / account_id / session_id / report_name 保存当前模板。 Streamable HTTP 初始化时服务端签发 Mcp-Session-Id,客户端后续自动 回传,因此同一 Token 下的不同对话也会隔离。未提供会话头时才回退为 Token 哈希会话。首次 newStyle 后记录模板身份,首次 saveStyle 后记录 完整 JSON;后续调用 getPrintInfo() 会同时返回:

{
  "currentStyle": {
    "reportName": "销售单",
    "reportType": 1,
    "styleName": "图片还原模板",
    "styleId": "2086707921336647680",
    "revision": 2,
    "hasContent": true,
    "styleContent": {"ReportName": "销售单", "Pages": []}
  }
}

模型以 currentStyle.styleContent 为基线,只修改用户本轮指定内容,再使用同一个 styleId 调用 saveStyle。只有用户明确要求另存为新模板时才调用 newStyle

参考实现使用进程内状态(BearerConnectionStoreTemplateConversationStore), 支持同一服务进程内多轮对话;通过 TTL 自动清理过期会话(默认 2 小时),避免内存 无限增长。服务重启会丢失状态,多副本部署应把会话存储替换为 Redis 或数据库共享状态。

快速启动

运行要求:Python 3.11 或更高版本,并已安装 uv

1. 安装依赖

cd /path/to/gjp-print-mcp
uv sync

本地开发和执行测试时使用:

uv sync --extra dev

2. 配置服务

可在项目根目录创建 .env

YUNPRINT_BASE_URL=https://yunprint.gmgrasp.com.cn
YUNPRINT_TIMEOUT_SECONDS=30
GJP_LOG_ENABLED=true
GJP_LOG_LEVEL=INFO

也可以使用同名进程环境变量;进程环境变量优先于 .env

变量

必填

默认值

说明

YUNPRINT_BASE_URL

-

云打印平台 HTTPS 根地址,不包含三个 API 路径

YUNPRINT_TIMEOUT_SECONDS

30

三个业务 API 的超时时间(秒)

GJP_LOG_ENABLED

false

是否开启终端日志

GJP_LOG_LEVEL

INFO

DEBUG / INFO / WARNING / ERROR

云打印 Token 不写入 .env,而是由每个 MCP 客户端连接通过 Authorization 请求头动态传入。

3. 启动 MCP

本地启动:

uv run python -m yunprint --host 127.0.0.1 --port 8931

容器、服务器或局域网启动:

uv run uvicorn yunprint.app:app --host 0.0.0.0 --port 8931 --workers 1

启动后的首选 MCP 地址为 http://127.0.0.1:8931/mcp,传输类型为 Streamable HTTP。生产环境应在反向代理层配置 HTTPS。

当前多轮模板状态保存在进程内存中,因此必须使用单 worker。 启用 Redis/数据库共享状态后才能安全扩展为多 worker 或多副本。

Linux 服务器部署见 Linux 服务器部署与更新指南

连接 MCP

支持 Streamable HTTP 的 Agent 平台使用以下配置:

{
  "mcpServers": {
    "yunprint-print": {
      "type": "streamable-http",
      "url": "http://127.0.0.1:8931/mcp",
      "headers": {
        "Authorization": "Bearer <云打印Token>",
        "X-Report-Name": "%E9%94%80%E5%94%AE%E5%8D%95"
      }
    }
  }
}

X-Report-Name 值需 URL 编码(如 销售单%E9%94%80%E5%94%AE%E5%8D%95), 且只编码一次,禁止双重编码。

不同 Agent 平台的配置字段名可能不同,但必须保持以下三项:

配置项

传输

Streamable HTTP

URL

http(s)://<MCP服务地址>/mcp

Header

Authorization: Bearer <云打印Token> + X-Report-Name: <URL编码分类>

MCP 服务在 initialize 响应中签发 Mcp-Session-Id。标准 MCP 客户端会在 后续请求中自动携带它,不要在配置文件里写死该请求头。同一轮对话 必须复用同一 MCP 会话,才能继续编辑 currentStyle

连接成功后应只能发现:

  1. getPrintInfo

  2. newStyle

  3. saveStyle

连接排查

现象

检查项

404

URL 必须以 /mcp 结尾

MCP_UNAUTHORIZED

检查 Authorization 是否为 Bearer <Token>

缺少或无效 Mcp-Session-Id

确认客户端支持有状态 Streamable HTTP,并复用初始化会话

BUSINESS_CONNECTION_INVALID

检查服务端 YUNPRINT_BASE_URL

YUNPRINT_REQUEST_FAILED

检查云打印 Token、网络和云打印 API 状态

更完整的部署、反向代理和手工握手验证方式见 SaaS 与三接口 MCP 接入

测试

uv run pytest -q

三个工具的请求契约、动态 Token 注入、权限和 Schema 测试位于 tests/printing/test_style_*.py

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/757607106/gjp-print-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server