概览

这是什么

一个 Cloudflare Worker,将 MCP(Model Context Protocol,模型上下文协议)服务器暴露给 AI 模型调用,用于绘制数学函数图形、生成 STEM(科学/技术/工程/数学)教学图表,并将渲染结果以 SVG 矢量图或 PNG 位图的格式返回。GitHub 仓库:lingion/plot-mcp-worker。111 次 commit,CC BY-NC-SA 4.0 开源协议。

技术栈(根据源码逐文件验证)

层级功能描述源码位置
运行时Cloudflare Workers(ES 模块格式),兼容性日期设置为 2026-04-22wrangler.toml
路由系统JSON-RPC 2.0 协议入口在 POST /mcp;Web 直接访问 URL 包括 /plot(函数图)、/png(PNG 渲染)、/s/{token}(短链接)、/force.svg(力分析图)、/force-analysis.svg(力分析详细版)、/circuit.svg(电路图)、/venn.svg(维恩图)、/c-memory.svg(C 语言内存布局图)、/shape3d.html(3D 几何体交互页面)、/multi_plot/multi_plot.png(子图面板)src/index.ts(主 handler 函数约在 L3290)
数学表达式引擎使用 expr-eval 这个 npm 库来解析用户输入的数学表达式,支持诸如 sin(x)(正弦)、x^2+1(幂运算和加法)、log(x)(对数)等标准数学语法src/plot.ts(文件第 1 行 import 导入)
SVG 渲染器纯手写的字符串拼接方案——不使用任何 SVG 生成库。包含:卡片式布局(带标题和元数据的外框)、网格和刻度线(使用 Nice 算法自动计算合适的刻度间距,支持 pi 感知和对数刻度)、注释标注(竖线/点/标签/区域四种类型)、以及柱状图/箱线图/饼图/直方图/散点图/折线图六种数据系列类型的渲染src/render.ts(共计 1123 行代码)
PNG 渲染器使用 @resvg/resvg-wasm 这个 Rust 库通过 WebAssembly 编译后在 Worker 的 V8 隔离环境中运行。流程是:先生成 SVG 字符串,然后从 Cloudflare KV 存储中加载 CJK(中日韩)字体文件,用 opentype.js 将 SVG 中的文字字形逐个转换为 SVG 路径(pathify),最后调用 resvg 将整个 SVG 栅格化为 PNG 位图数据src/render.ts 文件头 L1-3(import 声明)和 L1073-1112(PNG 渲染主函数)
CJK 字体处理opentype.js 库负责将 CJK 字符的字形轮廓和数学专用 Unicode 字符(如 π 圆周率、² 上标平方、∫ 积分号、√ 根号等)从字体文件中提取出来,转换为 SVG <path> 元素的 d 属性值。这样 resvg-wasm 才能在不需要系统安装中文字体的情况下正确渲染中文文本src/render.ts L139-159(pathifyCjkText 函数定义)
持久化存储Cloudflare KV 键值存储,绑定到命名空间 SHORT_LINKS。短链接记录(token → 完整参数)的过期时间(TTL)设为 30 天。短链接 token 为 8 个字符的随机字符串src/constants.ts L7-9(TTL 和 token 长度常量);wrangler.toml L11-13(KV 绑定配置)
图表生成器力分析图(8 种物理模板:斜面、悬挂、水平面、滑轮、弹簧、双块、滑轮组、弹簧振子)、电路图(10 种模板:串联、并联、开关灯、电源电阻、LED 电阻、仪表回路、晶体管开关、继电器驱动、蜂鸣器回路、运放跟随器)、维恩图(2 或 3 集合交集)、C 语言内存布局图(指针/结构体/数组的栈和堆布局)、3D 几何体(立方体/球体/圆柱体/圆锥体/向量/曲面/散点/线段)src/extras.ts(共计 1657 行代码);模板定义在 src/index.ts L902-1173

源码目录树

plot-mcp-worker/
|-- src/
|   |-- index.ts        3471 行  HTTP 入口 + 规范工具名分发器 + 短链接 KV 存储逻辑
|   |-- render.ts       1123 行  SVG 和 PNG 渲染管线(数学图表部分)
|   |-- plot.ts         1520 行  PlotSpec 构建器、数据变换函数、误差线计算、基础统计
|   |-- extras.ts       1657 行  力分析/电路图/维恩图/C 内存图/3D 图形 SVG 渲染器
|   |-- types.ts        136 行   冻结的接口定义(RenderFormat、PlotSeries 等)
|   |-- constants.ts    48 行    硬限制常量(CPU 时间/内存/请求体上限)、调色板颜色数组、默认值
|   |-- router.ts       94 行    兼容路由层——将旧工具名映射到新规范名
|   |-- compat.ts       80 行    旧工具名到规范名的静态映射表
|   |-- utils.ts        91 行    Base64 编解码/gzip 压缩解压工具、XML 转义、clamp 数值钳制、parseInteger 安全解析
|   |-- mcp.ts          26 行    CORS 跨域响应头 + JSON-RPC 2.0 标准错误格式工厂函数
|   |-- types.d.ts      9 行     额外的 TypeScript 类型声明文件
|-- scripts/                       12 个验证和快速部署脚本(详见本地开发页面)
|-- docs/                          README 素材图片(中英文展示截图、使用示例)
|-- capabilities.json              工具能力清单文件(旧格式,列出 22 个能力项)
|-- wrangler.toml                   Cloudflare Wrangler 部署配置文件(路由规则、KV 绑定、.ttf 文件规则)
|-- tsconfig.json                   TypeScript 编译配置(ES2022 严格模式、bundler 模块解析)
|-- package.json                   3 个依赖包:expr-eval、opentype.js、@resvg/resvg-wasm

总计 8255 行源代码,分散在 11 个 TypeScript 文件中。

两个版本号(故意设计的不一致)

  • package.json 中的 version 字段:0.2.0——这是 npm 包的发布版本号,遵循语义化版本规范
  • src/constants.ts 中的 SERVER_VERSION 常量:0.4.14——这是 Worker 部署实例的版本号,由 health 工具和 MCP initialize 响应中的 serverInfo.version 字段报告给调用方

两个版本号之间存在故意的不一致。原因是 SERVER_VERSION 独立追踪每一次部署到 Cloudflare 边缘节点的迭代次数——每次修改 Worker 代码并重新部署,这个版本号就可能递增——而 package.json 中的版本号只在正式发布新功能或修复时才会更新。这是"部署面"和"包面"之间有意为之的分离设计。不要试图手动对齐它们——它们追踪的是两个不同的生命周期。

实时 MCP 端点

https://your-worker.your-domain.com/mcp 发送 HTTP POST 请求,请求体为 JSON-RPC 2.0 格式。调用 initialize 方法后,服务器返回的响应中包含 protocolVersion: "2025-03-26"(MCP 协议版本)、serverInfo.name: "plot-mcp-worker"(服务器名称)、serverInfo.version: "0.4.14"(服务器版本号)。调用 tools/list 方法返回完整的 24 个工具列表(8 个规范名称加上 16 个为向后兼容而保留的旧版别名)。详见 Tools Reference 页面。

参见:技术博文:构建 plot-mcp-worker——深入解析数学表达式解析器的工作原理、5 步数据变换管线的内部实现、智能坐标轴的刻度选择算法、CJK 文字到 SVG 路径的转换过程、以及各类图表生成器的架构设计。