配置与部署
wrangler.toml(完整文件)
name = "plot-mcp-worker"
main = "src/index.ts"
compatibility_date = "2026-04-22"
workers_dev = true
[[routes]]
pattern = "your-worker.your-domain.com/*"
zone_name = "your-domain.com"
[[kv_namespaces]]
binding = "SHORT_LINKS"
id = "YOUR_KV_NAMESPACE_ID"
preview_id = "YOUR_KV_PREVIEW_NAMESPACE_ID"
[build]
command = ""
[[rules]]
type = "Data"
globs = ["**/*.ttf"]
fallthrough = trueKV 命名空间 SHORT_LINKS
这个绑定名叫 SHORT_LINKS,一共承担 3 类用途:
- 短链接记录——键名形如
short:{8-char-token},值是{path, payload}这样的 JSON,TTL 为 30 天 - 字体(关键资源)——键名包括
font:arial-unicode-cn-gb2312(TTF 字节)和font:arial-sans(TTF 字节),不设置 TTL - 还有别的内容吗?——没有了,
src/index.ts和src/render.ts中只引用了这两类键
上传字体(一次性初始化)
src/render.ts L79-97 中的 loadFonts 会在第一次渲染 PNG 时同时从 KV 拉取这两个字体文件。如果任意一个缺失,就会抛出 No CJK font loaded from KV (...)。字体必须以原始 arrayBuffer 的形式上传:
wrangler kv:key put --binding=SHORT_LINKS "font:arial-unicode-cn-gb2312" --path=./fonts/ArialUnicodeCN.ttf
wrangler kv:key put --binding=SHORT_LINKS "font:arial-sans" --path=./fonts/ArialSans.ttf第一个字体(CJK)还会被 opentype.js 解析,并由 pathifyCjkText 把中文字符以及 π、²、³、∫、√ 之类数学 Unicode 字符转换成 SVG 路径,然后再交给 resvg 渲染。如果缺少它,中文标签和数学符号通常会显示成 □。
[[rules]] 中针对 .ttf 的规则
Wrangler 默认会尝试把 TTF 文件直接打包进 Worker 脚本,这对大字体来说通常会失败。规则 { type = "Data", globs = ["**/*.ttf"], fallthrough = true } 的作用是告诉 wrangler:把所有 .ttf 当作数据资源处理,并继续让后续规则参与匹配。正是这一条规则,才让这些字体可以存储在 KV 中,而不是被直接内联进 Worker bundle。
常量(来自 src/constants.ts)
| 常量 | 值 | 用途 |
|---|---|---|
SERVER_NAME | "plot-mcp-worker" | health/init 响应 |
SERVER_VERSION | "0.4.14" | health/init 响应(与 package.json 不同) |
SHORT_LINK_PATH_PREFIX | "/s/" | 短链接路径前缀 |
SHORT_LINK_TOKEN_LENGTH | 8 | token 长度 |
SHORT_LINK_TTL_SECONDS | 2592000(30 天) | 短链接记录 TTL |
MIN_POINTS / MAX_POINTS | 10 / 20000 | 折线/散点采样点数钳制 |
DEFAULT_POINTS | 1000 | 调用方未指定时的默认采样点数 |
MAX_EXPR_LENGTH | 400 | 数学表达式最大长度 |
MAX_TITLE_LENGTH | 120 | 标题最大长度 |
MAX_LABEL_LENGTH | 80 | 坐标轴标签最大长度 |
MAX_SERIES | 12 | 单图最大数据系列数 |
MAX_FORCE_ITEMS | 16 | 单个受力体最大力矢量数 |
MAX_FORCE_BODIES | 8 | 单场景最大受力体数量 |
MAX_CIRCUIT_COMPONENTS | 24 | 单个电路图最大元件数 |
MAX_3D_SURFACES | 6 | 单个 3D 场景最大曲面数 |
DEFAULT_WIDTH / DEFAULT_HEIGHT | 1200 / 720 | SVG/PNG 默认画布尺寸 |
DEFAULT_FONT_FAMILY | "ArialUnicodeCN" | resvg 字体查找默认值 |
DEFAULT_PALETTE | 8 种颜色(蓝/红/绿/琥珀/紫/青/橙/粉) | 调用方未指定颜色时的数据系列自动配色 |
TypeScript 配置(tsconfig.json)
{
"compilerOptions": {
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "Bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"types": ["@cloudflare/workers-types"]
},
"include": ["src/**/*.ts"]
}也就是说:目标运行时是 ES2022,启用了 strict 严格模式;skipLibCheck 会跳过对 @cloudflare/workers-types 的类型检查;Wrangler 的 Bundler 解析模式意味着你不需要为 npm 依赖写特别的路径处理。