关于 sheetrender-mcp
sheetrender-mcp 是通过 SheetRender 模板将电子表格行生成为 PDF 的 MCP 服务,适用于批量制作证书、收据和信件等文档;无 API 密钥时也可使用精简的内置模板工具集。
主要功能
- 01每个电子表格行生成一份 PDF
- 02填充内置或已保存模板
- 03使用 HTML 模板和数据集
- 04通过 API 密钥运行批处理
- 05返回预览和 PDF 链接
适用场景
- 01根据完成记录制作证书
- 02为电子表格条目生成捐赠收据
- 03根据申请人数据制作录用信
- 04用已保存模板批量生成文档
MCP 相关
通过托管的 Streamable HTTP 或本地 stdio 包向 MCP 客户端提供 SheetRender 文档生成工具。无 API 密钥时提供精简的内置模板工具集;有效密钥可启用完整工具集。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://mcp.sheetrender.com/mcpclaude mcp add --transport http sheetrender-sheetrender https://mcp.sheetrender.com/mcp{"mcpServers":{"sheetrender-sheetrender":{"type":"http","url":"https://mcp.sheetrender.com/mcp"}}}在 Cursor 中打开{"servers":{"sheetrender-sheetrender":{"type":"http","url":"https://mcp.sheetrender.com/mcp"}}}在 VS Code 中打开{"mcpServers":{"sheetrender-sheetrender":{"type":"http","url":"https://mcp.sheetrender.com/mcp"}}}{"mcpServers":{"sheetrender-sheetrender":{"serverUrl":"https://mcp.sheetrender.com/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
https://mcp.sheetrender.com/mcp需要授权工具
3此工具无需参数。
详细介绍
@sheetrender/mcp
SheetRender 的 MCP 服务:将电子表格中的每一行转换为一个 PDF,例如证书、信件、捐款收据和录用信。
最快的入门方式无需账号,也无需安装。将托管服务 https://mcp.sheetrender.com/mcp 添加为 ChatGPT、Claude 或任何接受 Streamable HTTP URL 的客户端中的连接器,然后粘贴或描述你的数据行。它会填充 SheetRender 内置的模板,并为每一行返回预览和 PDF(详情)。
使用 SheetRender API 密钥后,你便可使用完整的工具集:自己的已保存模板、HTML 模板、数据集和批处理任务。你可以通过下方的 npm 包或同一个托管 URL 使用这些功能。
设置
在 sheetrender.com 的 Settings → API keys 中获取 API 密钥,然后将以下内容添加到 MCP 客户端配置中:
{
"mcpServers": {
"sheetrender": {
"command": "npx",
"args": ["-y", "@sheetrender/mcp"],
"env": { "SHEETRENDER_API_KEY": "sr_live_..." }
}
}
}
也会读取 SHEETRENDER_API_URL,其默认值为 https://sheetrender.com。仅在连接到可自托管实例或暂存实例时才设置它。
托管端点
同一服务也通过 Streamable
HTTP 运行于 https://mcp.sheetrender.com/mcp,因此无法启动本地进程的客户端也可以使用。无需安装任何内容;每个请求都会携带你的 API 密钥:
Authorization: Bearer sr_live_...
未携带此请求头的请求会获得较小的无密钥工具集,详见下文。密钥会直接传递给 SheetRender API,仅用于该请求,且绝不会存储——服务不保留会话,因此每个请求都是独立的。
密钥的传递方式取决于客户端:
-
Claude Code:
claude mcp add --transport http sheetrender https://mcp.sheetrender.com/mcp --header "Authorization: Bearer sr_live_..." -
Cursor、Windsurf、VS Code 及其他使用
mcp.json的客户端:{ "mcpServers": { "sheetrender": { "url": "https://mcp.sheetrender.com/mcp", "headers": { "Authorization": "Bearer sr_live_..." } } } } -
Claude API(Messages API 的 MCP 连接器):将
{"type": "url", "url": "https://mcp.sheetrender.com/mcp", "name": "sheetrender", "authorization_token": "sr_live_..."}添加到mcp_servers。 -
claude.ai、Claude Desktop 和 ChatGPT 自定义连接器需要服务器 URL 和 OAuth 客户端,而不是静态请求头。在该端点支持 OAuth 之前,请在那里使用上文的 stdio 包——工具相同,密钥放在
env中——或者使用以下命令通过npx mcp-remote https://mcp.sheetrender.com/mcp --header "Authorization: Bearer sr_live_..."桥接。
由于进程不在你的机器上运行,远程服务与 stdio 服务有两处不同。渲染后的 PDF 会以内联 base64 资源的形式返回(最大 8 MB;更大的文件会报告其大小,并留给 Web 应用处理),而不再返回临时文件路径;另外,不提供 upload_dataset,因为没有本地文件可供读取——请改用 create_dataset 发送行数据。
GET /healthz 无需凭据即可返回 200。请求体上限为
25 MB;超过此大小的请求会返回 413。
仅凭密钥以 sr_ 开头并不能证明其有效,因此服务会等待 SheetRender API 接受该密钥。在使用该密钥成功发起调用之前(通常是第一次工具调用,例如 list_templates),使用该密钥的请求与无密钥请求遵循相同的限制,详见下文:请求体最大为 2 MB,每批最多 4 条 JSON-RPC 消息,并且每条消息都会计入网络级别的限额。API 接受密钥后,服务会在该密钥最近一次成功调用后的 1 小时内记住其哈希值(绝不保存密钥本身),此时请求体上限为 25 MB,每批最多 20 条消息。MCP 客户端每个请求只发送一条消息,因此批次上限只影响手动编写的客户端。如果第一次调用的请求体超过 2 MB(例如大型 create_dataset),请求会收到 413,并提示先进行一次较小的调用再重试。所有请求,无论是否携带密钥,都会计入服务全局并发请求上限。
携带已接受密钥时,单次工具调用的参数最多可包含 600,000 个值(数组元素与对象字段合计),足以满足 create_dataset 的 500,000 个单元格;尚未接受的密钥最多可包含 20,000 个值。匿名调用的上限略高于最大实际调用所需的值。
超过 2 MB 的请求体还会占用少数几个服务全局的大请求体名额,默认数量为 1(LARGE_BODY_MAX_IN_FLIGHT)。如果 Content-Length 声明请求体超过此大小,或流式请求体一旦超过 2 MB,服务就会在读取前占用一个名额,并一直保留到响应结束。名额全部占用时,请求会收到带有 Retry-After: 5 的 503,且其余请求体不会被读取。一个 25 MB 的请求体在解码、解析和转发过程中可能占用约 100 MB 堆内存,因此只有在堆内存充足时才应调高此值(托管容器的堆内存为 192 MB)。
无密钥(ChatGPT 和 Claude 目录列表)
当服务设置了 SHEETRENDER_DEMO_API_KEY 时,不带 Authorization 请求头的请求会获得另一套较小的工具,而不是收到 401。这些工具会通过专用渲染账户,使用聊天中的行数据填充 SheetRender 的内置模板(完成证书、信函、捐赠收据、工作邀请函):
list_document_templates:模板及其字段(key、label、required、example、字符数和行数限制)。render_documents:每次调用最多处理 25 行,每行生成一个 PDF;每份文档都会返回 PNG 预览和 PDF 链接(两者均在一小时后过期)、缺少必填字段的行,以及该用户当月 50 份文档(在 Claude 中按对话计算)还剩多少份。如果调用被与其他用户共享的限制截断或拒绝,会说明该限制为共享限制,而不显示剩余数量。调用被拒绝或截断时,还会说明可以通过继续链接将这些行带到网站。字段值超过字符数或行数限制时,会在调用 API 前拒绝;API 拒绝某些行时给出的原因(行号、字段和规则,绝不包含字段值)也会传回。create_continue_link:最多 100 行,保存 7 天,并返回一个指向网站上对应模板页面的链接,页面中已加载这些行。仅当用户想在那里继续操作时才调用。
render_documents 配有一个 MCP Apps 视图 ui://sheetrender/documents.html(text/html;profile=mcp-app):其中包含预览条、PDF 链接,以及一个“使用这些行在 SheetRender 中继续”按钮。其脚本 src/widget/documents.ts 会在 deno task build 期间由 esbuild 打包到 dist/widget/documents.js,并在读取资源时内联到页面中。
调用按用户计数:优先使用 ChatGPT 匿名化的 openai/subject,否则使用客户端 IP。任何调用方都可以发送 openai/subject,因此仅信任来自 OpenAI 公布的出口范围(chatgpt-connectors.json,可通过 OPENAI_EGRESS_CIDRS 覆盖)的此字段;其他来源的调用按 IP 计数。托管服务会在启动时及之后每 24 小时获取一次该列表;如果获取失败,或返回格式错误或空内容,则保留内置副本(之后则保留上一次成功获取的列表);每次刷新都会记录一行日志。它还会最多每小时记录一次:有多少次调用从列表范围之外发送了 openai/subject,以便发现列表过期的情况。
服务对每个 subject 或 IP 每小时允许 30 次渲染或继续调用(ANON_CALLS_PER_HOUR)。按 IP 计数的调用还会共享另一个按 IPv4 /24 或 IPv6 /48 网段划分的计数桶,每小时 300 次(ANON_NETWORK_CALLS_PER_HOUR),因此一组廉价地址会按一个调用方计数。来自 Claude 的 160.79.104.0/21 网络(Anthropic 公布的出站范围,Claude API 的 MCP 连接器也使用此范围)的所有流量,共享一个单独的每小时 3,000 次调用计数桶(CLAUDE_CALLS_PER_HOUR);每个发送了 Mcp-Session-Id 的 Claude 对话也会在此桶内获得按 subject 计数的 30 次调用额度。User-Agent 文本和 _meta 均无法声明加入或退出这些计数桶。
SheetRender API 仍会根据哈希后的 subject 或 IP 计算每月文档数量。subject 和 IP 仅以 SHA-256 哈希的形式发送到 API;请求日志仅包含指纹、检测到的客户端(chatgpt、claude 或 other)及行数,绝不包含各行内容。
匿名 HTTP 请求正文上限为 2 MB,足以容纳每个字段均达到限制的 25 行;继续链接中的行上限为 256 KB。私有地址的套接字对端会被视为代理,且只信任 X-Forwarded-For 中最后一个有效 IP。请按照部署的 Compose 拓扑,将此监听器置于 Caddy 后方,且不要公开容器端口。
匿名请求还受到另外三项限制,以防小型请求让服务生成大量输出。JSON-RPC 批次最多可包含 4 条消息(MCP 已在协议版本 2025-06-18 中取消批处理,ChatGPT 和 Claude 每个请求只发送一条消息);超过上限的批次会在其中任何内容运行前收到 400 错误。工具调用以外的消息(initialize、tools/list、resources/read 等)每小时按每个 IPv4 /24 或 IPv6 /48 计 600 条(ANON_RPC_PER_HOUR);来自 OpenAI 和 Claude 出口网段的流量不计入此项,因为每个地址承载许多用户。同时,最多同时响应 64 个请求,无论是否带密钥(ANON_MAX_IN_FLIGHT);这些网段以外的每个网络最多同时响应 8 个(ANON_NETWORK_MAX_IN_FLIGHT);超过任一上限时,响应为 503 或 429,并带有 Retry-After: 5。对于 SheetRender API 尚未接受的 API 密钥请求,三项限制均适用,工具调用也计入 600 条上限;密钥获接受后,这些请求仅受全局并发上限限制,批次最多可包含 20 条消息。
携带 SheetRender bearer 密钥的请求会使用上述 API 密钥工具。格式错误的 Authorization 标头会被拒绝。stdio 服务不会提供匿名工具。
自行运行
sheetrender-mcp-http 是软件包中的第二个二进制程序。它会读取 PORT(默认值为 8080)、HOST(默认值为 0.0.0.0)、SHEETRENDER_API_URL、MAX_BODY_BYTES 和 IDLE_TIMEOUT_MS(默认值为 60000),并为每个请求向 stdout 输出一行 JSON 日志,记录方法、路径、状态、耗时、JSON-RPC 方法和工具名称、密钥指纹(绝不记录密钥),以及 key_verified(表示 API 是否已接受该密钥)。
对于匿名工具以及上述请求限制(在未设置演示密钥时,也适用于带密钥的请求),它还会读取:
| 变量 | |
|---|---|
SHEETRENDER_DEMO_API_KEY | 专用渲染账户的 sr_ 密钥。未设置时:不提供匿名工具,不带密钥的请求会收到 401。 |
MCP_PUBLIC_URL | 用户粘贴的网址,逐字节保持原样,例如 https://mcp.sheetrender.com/mcp。设置视图的沙箱来源(Claude 会对这个精确字符串进行哈希)。 |
OPENAI_APPS_CHALLENGE | OpenAI 的域名验证令牌;通过 GET /.well-known/openai-apps-challenge 以纯文本形式提供(未设置时返回 404)。 |
ANON_CALLS_PER_HOUR | 每个主体或 IP 每小时的渲染和继续调用次数,默认值为 30。 |
ANON_NETWORK_CALLS_PER_HOUR | 按 IP 计数的调用方,每个 IPv4 /24 或 IPv6 /48 每小时的渲染和继续调用次数,默认值为 300。 |
CLAUDE_CALLS_PER_HOUR | 来自 160.79.104.0/21 的所有流量共享的每小时渲染和继续调用次数,默认值为 3000。 |
ANON_RPC_PER_HOUR | OpenAI 和 Claude 网段以外,每个 IPv4 /24 或 IPv6 /48 每小时允许的非工具调用匿名消息数,以及 API 尚未接受的密钥所发送的所有消息数,默认值为 600。 |
ANON_MAX_IN_FLIGHT | 所有调用方合计同时响应的请求数(无论是否带密钥),默认值为 64。 |
ANON_NETWORK_MAX_IN_FLIGHT | OpenAI 和 Claude 网段以外,每个 IPv4 /24 或 IPv6 /48 同时响应的匿名请求数,以及 API 尚未接受的密钥请求数,默认值为 8。 |
LARGE_BODY_MAX_IN_FLIGHT | 服务端同时处理的正文超过 2 MB 的请求数,默认值为 1。只有 API 已接受的密钥才能发送此类正文。 |
OPENAI_EGRESS_CIDRS | 以逗号或空格分隔的 CIDR,表示被认为具有 openai/subject 的网段,并替代内置副本和对 chatgpt-connectors.json 的实时获取;none 表示不认可任何 subject。 |
设置 SHEETRENDER_DEMO_API_KEY 后,如果缺少视图包(dist/widget/documents.js),服务将拒绝启动。本仓库中的 Dockerfile 会为其构建一个以非 root 用户运行的镜像:
docker build -t sheetrender-mcp .
docker run --rm -p 8080:8080 sheetrender-mcp
工具
design_template:根据且仅根据dataset_id、内联rows、data_base64加data_filename,或仅限 stdio 的data_path之一,以及示例、简介或样式进行设计。数据文件必须为 CSV 或 XLSX,大小不超过 10 MB。等待时间最长为 3 分钟,并返回状态、模板详情和经过身份验证的预览 URL。示例使用example_base64加example_filename,或仅限 stdio 的example_path。get_design:轮询design_id,获取其状态、模板 id、名称、列映射和预览 URL。
render_pdf
根据你提供的 HTML 渲染一个 PDF。
| 参数 | 类型 | |
|---|---|---|
html | string | 必填。完整的 HTML 文档。CSS 必须内联在 <style> 标签中;不会获取外部样式表、字体和脚本。 |
data | object | 可选。键会成为 Jinja 变量,因此 {"total": "42.00"} 会使 {{ total }} 可在 HTML 中使用。 |
page_settings | object | 可选,见下文。 |
返回已保存 PDF 的路径和大小。文件小于 512 KB 时,还会以内联 base64 资源的形式附加,因此支持显示附件的客户端可以直接显示文档。
HTML 超过 2 MB 时会被拒绝。大小会同时根据你发送的内容和替换 data 后的文档进行计算,因此即使你编写的标记未超过限制,扩展后的长数据集也可能导致模板超出限制。如果渲染帐户的设置要求添加“Made with SheetRender”页脚,则会添加该页脚。render_pdf 和 render_template 均适用此规则。
list_templates
不带参数。返回每个已保存模板的名称、id 和最后更新时间。调用此工具可将用户提到的模板名称转换为其他工具所需的 id。
render_template
根据帐户中已保存的模板渲染一个 PDF。
| 参数 | 类型 | |
|---|---|---|
template_id | string | 必填,取自 list_templates。 |
data | object | 必填。一行数据的值,以 Jinja 变量的形式提供。 |
page_settings | object | 可选。省略时保留模板自身已保存的页面设置;传入时会覆盖本次渲染所用设置。 |
返回内容与 render_pdf 相同。
create_dataset
将 JSON 行转换为可供批量任务渲染的数据集。这是启动批量任务的常用方式:整理好各行数据并发送,即可获得 dataset_id。
| 参数 | 类型 | |
|---|---|---|
template_id | string | 必填,取自 list_templates。数据集会存入该模板所属的项目。 |
rows | array of objects | 必填。每个文档对应一个扁平对象。 |
name | string | 可选标签,用作存储的文件名。 |
表头是所有行的键按首次出现顺序组成的并集,因此各行的键不必一致——缺失的键对应空单元格,而不会导致行错位。值必须是标量:字符串、数字、布尔值或 null。嵌套对象和数组会被拒绝,NaN、Infinity 以及超过 2^53 的整数也会被拒绝(请将这些整数作为字符串发送以确保精确)。每次调用最多支持 50,000 行和 500,000 个单元格。
返回数据集 id、行数,以及每列对应的清理后键名。模板占位符、filename_template 和 group_by 使用该键名;它通常与表头原文不同——Invoice No 会变为 invoice_no。请从此结果中读取键名,而不要猜测。
创建数据集不会消耗文档额度;只有渲染才会消耗。
upload_dataset
从已有文件执行相同操作。
| 参数 | 类型 | |
|---|---|---|
template_id | string | 必填,取自 list_templates。 |
file_path | string | 必填。在运行此服务的机器上(即用户的机器,而非 SheetRender 的机器)的 .csv 或 .xlsx 文件。会展开 ~。 |
第一行必须是表头。超过 20 MB 的文件、扩展名不正确的文件和空文件会在本地被拒绝,不会上传。返回内容与 create_dataset 相同。
list_datasets
接受 template_id,并按时间从新到旧列出该模板所属项目中的所有数据集,包含 ID、行数和列键。可用它查找用户已加载的数据,或在编写 filename_template 或选择 group_by 之前读取数据集的列键。
create_batch_job
将后台任务加入队列,为数据集的每一行生成一个 PDF。整个流程都从这里开始:list_templates → create_dataset 或 upload_dataset → create_batch_job → get_job → get_document。
| 参数 | 类型 | |
|---|---|---|
template_id | 字符串 | 必填,来自 list_templates。 |
dataset_id | 字符串 | 必填,来自 create_dataset、upload_dataset 或 list_datasets。必须与模板属于同一个项目。 |
filename_template | 字符串 | 可选。输出命名模式,例如 invoice-{{ invoice_no }}。 |
group_by | 字符串 | 可选。用于对行分组的列键,每个不同的值会生成一个多页 PDF。 |
返回可供 get_job 轮询的任务 ID。请注意:filename_template 和 group_by 会分别保存到模板和项目中,因此也会更改后续运行的默认值。
如果服务端版本早于公开批处理端点,工具会报告批处理任务不可用,而不会给出难以理解的错误。对于早于数据集端点的服务端,三个数据集工具也会如此处理。
get_job
接受 job_id。返回状态、已完成和失败的行数,以及每个已渲染文档的 ID 和文件名。当任务处于 queued、retry_queued 或 running 状态时,文档列表为空;任务达到 succeeded、partial、failed 或 cancelled 状态后,列表才会填充。这些文档 ID 可供 get_document 使用。
get_document
接受 document_id 并下载单个已渲染的 PDF。ID 来自已完成批处理任务的 get_job,没有其他获取方式。返回内容与 render_pdf 相同:路径、大小,以及小于 512 KB 的内嵌数据块。
如果需要整个批次,使用 Web 应用中的合并 PDF 和 ZIP,比逐个获取文档更方便。
page_settings
两个渲染工具共用。所有字段均为可选:
{
"page_size": "a4",
"orientation": "portrait",
"margins": { "top": 15, "right": 15, "bottom": 15, "left": 15 }
}
page_size 使用小写值:a3、a4、a5、letter、legal 或 tabloid。边距使用普通数字,单位为毫米,而非 CSS 长度单位。
已渲染的 PDF 会写入系统临时目录。API 错误(例如密钥错误、模板缺失或触发速率限制)会作为工具错误返回,并附带服务端提供的消息。
公共 API 的每个 API 密钥每分钟最多可发起 120 次请求。超过限制后会返回 429,工具会报告你已触发速率限制,应稍后重试。批处理任务的创建单独计量,限制也更严格。
开发
主机上无需安装 node 或 npm:先运行 scripts/dev.sh install,再运行 scripts/dev.sh deno task build 和 scripts/dev.sh deno task test。scripts/dev.sh node dist/http.js 会在主机网络上运行 HTTP 服务。
采用 MIT 许可。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。