mcpField
E
Equation.io

Equation.io

远程服务
equation.io科研与教育4104 天前更新

关于 Equation.io

Equation.io 是内置计算机代数系统的在线绘图计算器,用于探索数学方程。它可渲染 2D 和 3D 图形,并将图形状态保存在可分享的 URL 中。

主要功能

  1. 01绘制 2D 曲线和 3D 曲面
  2. 02基于 GPU 的 WebGL 渲染
  3. 03内置计算机代数系统
  4. 04绘制向量场和 ODE
  5. 05可分享的方程 URL
  6. 06在 MCP 中渲染图形

适用场景

  1. 01绘制并分享方程
  2. 02探索向量场和微分方程
  3. 03可视化概率分布
  4. 04在 MCP Apps 中展示交互图形

MCP 相关

Equation.io 提供无状态的 Streamable HTTP MCP 服务,支持校验并编码图形 URL、解码 URL 以供编辑,以及在 MCP Apps 宿主中显示交互式绘图器。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://equation.io/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

工具

3
参数类型必填说明
equationsarray是图表中的每个方程,按显示顺序排列。每个字符串对应一个方程或定义——不要用 ";" 合并行(引号内的 ";" 属于数据,会保留)。

详细介绍

Equation.io

equation.io — 一款内置 CAS 的绘图计算器。输入方程,它们会编译成 GPU 着色器,并渲染为 2D 曲线、3D 曲面、向量场、ODE 相图、概率密度等。每张图都完全保存在其 URL 中,因此地址栏就是分享按钮。

graph.tk 的故事

这是 graph.tk 的继任项目。graph.tk 于 2010 年 5 月在此仓库中启动,最初是一款基于 HTML5 画布的绘图工具,多年来获得了 400 多颗星。网站运行在免费的 .tk 域名上——后来证明这是致命缺陷:注册商(Freenom)最终接管了该域名并在上面投放广告;Meta 起诉 Freenom 后,整个 .tk 注册局也随之崩溃,该域名彻底无法解析。

我们吸取了教训,从头重建了绘图工具——采用全新的解析器和 CAS,并使用 WebGL 替代画布进行渲染——运行在一个真正归我们所有的域名上:equation.io。原始代码保存在 legacy 分支(标签 graph.tk-final)中,遵循原有的 LGPL-3.0 条款;main 分支中的所有内容都是以 MIT 许可发布的全新重写版本。旧版界面仍可在 graph.equation.io 使用。

架构

部署为 Cloudflare Worker。页面位于 web/;数学功能位于 lib/。

  • lib/expr.ts 包含分词器、调度场解析器和表达式树。lib/defs.ts 负责解析名称和定义。解析时的展开逻辑与其实现的数学功能放在一起:vector-calculus.ts(梯度、散度、旋度)、sums.ts(Σ 和 Π),以及 integrate.ts、curves.ts 和 surface-geometry.ts 中的积分、曲线和曲面处理流程。
  • 分布相关代码位于 lib/dist.ts。它重新导出基本分布(dist-base.ts)、连续采样(dist-sample.ts)、离散分布(dist-discrete.ts)和随机变量系统(dist-system.ts)。分布族表位于 dist-families.ts。
  • 几何、张量、测度、列表和自动机组成了 lib/ 的其余部分:geom.ts、pga.ts、clifford.ts、tensor.ts、measure.ts、list.ts、automaton.ts 及其旁边的模块。compiler.ts 将分类后的行转换为 CPU 计划和 GLSL 计划(glsl.ts)。
  • web/main.ts 是方程编辑器和启动入口。web/session.ts 管理文档、面板和共享的 WebGL 渲染器。web/scene.ts 构建单帧并将其交给 2D 和 3D 渲染器。这三者共享的可变状态位于 web/app-state.ts。
  • 每个方程都会编译为 GLSL 标量场 F,其零点集就是图像:
    • 2D:全屏四边形片元着色器;当距离估计值 |F|/|∇F| 小于一个像素时绘制曲线,并通过双尺度一致性测试排除极点/渐近线处的假线(例如 y=tan(x))。
    • 3D(出现 z 时自动启用):射线步进隐式曲面——沿每条射线检测符号变化、通过二分法细化、使用有限差分计算法线,并设置 gl_FragDepth 以确保多个曲面能正确相交。不含 z 的方程会沿 R³ 中的真实轨迹延展。

整个图像状态都保存在 URL 中(/g/eq1;eq2;…,每个方程通过 lib/link.ts 进行百分号编码;该模块还会转义括号,避免聊天应用的链接识别器截断 URL;旧版 /#… 链接仍可加载),因此任意方程组都可以通过链接分享,地址栏就是分享方式。 面向 Agent 的接口:

  • /llms.txt — 链接格式和表达式语法参考 (web/public/llms.txt)
  • /g/<eqs> — 图像链接的分享形式;Worker 会注入 og:/twitter: 元标签(将图像中的方程作为标题,显示在网站卡片上)
  • /mcp — 无状态 MCP 服务(Streamable HTTP),提供 encode_graph_url(验证行并返回链接)、decode_graph_url(解码链接以便编辑)和 show_graph(在 MCP Apps 宿主中渲染交互式绘图器)。 请参阅 MCP Apps 集成与测试。
  • /.well-known/ard.json(也可通过旧版 /.well-known/ai-catalog.json 访问) — Agentic Resource Discovery 目录,列出 MCP 服务;/mcp/server-card — 其 MCP Server Card。两者均由 server.json 生成,生成逻辑位于 worker/discovery.ts。

使用方法

pnpm web        # dev server (grapher + worker API)
pnpm test       # vitest
pnpm typecheck  # lib + web + worker
pnpm web:build  # build to dist-web/ (client + worker)
pnpm deploy     # build and deploy to Cloudflare
流量和 MCP 使用情况
pnpm traffic 7     # needs `wrangler login`

网站访客数据来自 Cloudflare 自带的区域分析功能。脚本每天按页面统计独立 IP 数,仅使用浏览器 User-Agent,并按客户端列出 /mcp POST 请求。网站上没有任何内容会收集这些数据。

MCP 工具调用是 Cloudflare 无法看到的唯一内容,因为它不会记录请求正文。worker/mcp-usage.ts 会为每次 tools/call 写入一个 Analytics Engine 数据点:包括工具、客户端、图像类型、行数和错误数,但绝不记录方程文本。设置具有 Account Analytics: Read 权限的 CLOUDFLARE_API_TOKEN,脚本才会纳入这些数据。

示例

基础用法

  • y = x^2 · x^2+y^2=4 · y = tan(x) — 2D 曲线
  • y = sin(2πx) · θ = 1; r = θ x · y = x³ — Unicode 输入:π、 希腊字母名称、上标指数、下标(T₀ ≡ T_0,因此 a₃ 是数列项),以及 ·/×/÷/≤/≥/≠; 在编辑器中,输入 \pi、\theta、\nabla、……会插入相应符号,而在任意函数名称前输入 \ 会直接将其去掉(\trail → trail)
  • z = sin(x)cos(y) · x^2+y^2+z^2=9 — 3D 曲面(出现 z 时自动绘制)
  • y < x/2 + 1 — 不等式会为其区域着色;严格不等式 </> 不显示 边界,<=/>= 会绘制边界线,像 4 <= x^2 + y^2 <= 9 这样的链式不等式会按每个非严格界限绘制边缘
  • y = {x < 0: -x, x >= 0: x^2} — 分段函数:按顺序尝试 cond: value 条件,最后可选一个不带条件的值作为默认值;条件可以串联,例如 {0 < x < 1: 1, 0},不带条件的值按 1 计({x > 0, 5})
  • y = {0 < x < 2: x^2} — 定义域限制:没有默认值时,条件之外的值 未定义,因此不会在该处绘制
  • sin(x)cos(y) — 只含 x、y 的裸表达式是 2D 标量场;正值区域以行颜色着色, 负值区域则以其补色着色。sin(x) 也属于标量场(沿 y 方向恒定):曲线为 y = sin(x)
  • 2+2、sqrt(a)、|A - B| — 裸数值不会绘制图形,而会在行下方显示 = 4,并随滑块和 t 实时更新;要绘制直线,请写 y = 4

滑块和动画

  • a = 2 — 带滑块的命名常量;其他方程可以使用 a,它会编译为 uniform,因此拖动滑块时无需重新构建着色器。b = a^2 + t 定义一个计算得出的/动画常量
  • a := 2、f(x) := x^2 — 显式写出的相同定义。:= 也可以将 e、pi、 i、w 或 t 作为值(而非函数)接管,并应用于整个图形(e := 0.6 是滑块; t := 0.5 会停止所有动画);u 和 v 接受一个区间(u := interval(0, 2pi));x、y、z 和 d 仍是语言内置变量
  • (2, 3) / (3, 12, 0) — 点。在 2D 中,可以在画布上拖动由普通数值 或滑块名称组成的坐标,拖动时会重写这些坐标: a = 1; b = 2; (a, b) 会移动两个滑块,(2sin(t), 3) 只会移动其字面量高度
  • (2cos(t), 2sin(t)) — t 表示自加载以来经过的秒数,因此此点会绕圈运动

微积分

  • f(x) = x^3 - a x — 用户定义函数,会以符号形式内联展开
  • f(z) = {re(z) >= 1: 1, f(4 - 3(z^6)^(1/6))} 然后 f(x i - |y|) >= 0 — 尾递归函数(每次自调用都必须是其 {…} 中的完整分支) 会针对每个像素作为有界循环运行;此例会为科赫雪花着色
  • y = d/dx f(x) / d^2/dx^2 (x^4) — 符号化莱布尼茨导数;适用于 任意单字母变量,可以嵌套,也能在函数定义中传递: g(x) = d/dx f(x) 然后 y = f(a) + g(a)(x - a) 会生成实时切线

概率

  • X ~ Normal(0, a) — 随机变量;该行会绘制其概率密度,参数可以使用滑块。接着,P(X < b)、P(X > b) 或 P(-1 < X < 2) 会为密度曲线下的对应区域着色,并显示数值概率
  • 还支持 Uniform(lo, hi)、Exponential(rate)、Gamma(shape, rate)、Beta(a, b)、 ChiSquared(df)、StudentT(df)(或 T(5))、LogNormal(mu, sigma)、 Cauchy(location, scale)、Weibull(shape, scale) — 精确概率密度、精确的 P(…),以及在重尾分布无法报告 σ 时显示的中位数/四分位距读数
  • erf、normalpdf(x, mean, sd) 和 normalcdf(x, mean, sd) 也都是普通 函数,因此 y = normalcdf(x, 0, 1) 会绘制累积分布函数

向量场和常微分方程

  • (-y, x)——一个依赖于 x、y 的元组,是一个向量场,通过 GPU 线积分卷积渲染为动态流线;t 也可以: (cos(t)-y, x)
  • grad(x^2 + y^2)(或 ∇(…))——符号梯度,以元组表示,因此会绘制为向量场,也可用于 dot(grad(f), (1, 0))
  • dy/dx = x y / y' = sin(x) - y——ODE 会绘制斜率场/方向场 (1, f);点击画布可在该点生成一条 RK4 积分曲线,双击可清除
  • (x', y') = (y, -sin(x))——系统会绘制相图,同样可通过点击追踪轨迹

模拟(状态)

  • th' = om(角度),om' = -sin(th)(角速度),且 th(0) = 3——一个状态:自定义名称后的撇号表示该变量对 t 的导数;图表动画播放时,变量会以固定步长通过 RK4 向前积分——参见 lib/state.ts。在其他所有场景中,th 都与常量完全一样,具有均匀性等特性,因此绘制系统就是普通绘图: (sin(th), -cos(th)) 表示摆球,(u sin(th), -u cos(th)) 表示摆杆。它是图表中唯一一个不是关于 t 的公式的值,这正是双摆(混沌且无闭式解)得以实现的关键。初始值会显示一个滑块,可重新启动运行;面板中的 ↻ 可重启运行
  • r' = vel,vel' = -r/|r|^3,且 r(0) = (1, 0)——一个向量状态:导数为 2 或 3 维向量时,会按分量分别对 r_1、r_2(及 r_3)积分;裸名称会绘制为一个运动点,并参与点运算——在两行中表示一条轨道
  • label((2, 4), "peak") / label(A, "vertex")——在点旁显示文本,颜色与所在行相同;点会像其他点一样随滑块和 t 移动
  • y = x^2 #e24——以十六进制颜色开头的注释会使该行按此颜色绘制
  • trail(A)——在 2D 或 3D 点后留下动态运动轨迹。 例如,A = (cos(t), sin(t)); trail(A) 会在运行时绘制一条轨道; trail((cos(t), sin(t), t/5)) 会绘制一条上升螺旋线。向量状态也适用。 轨迹最多保留 30 秒/2048 个观测位置;方程或模拟重启时会重置,并且仅限当前会话使用。
  • p(0) = ([0..299]/30, 0, 0)——一个状态族:一组起始值会让系统针对每个元素各运行一次(最多 1024 次),与其耦合的状态也会随之运行。随后,p 会绘制一团运动点,mean(p_1) 会计算各次运行的均值。若从元组开始,p(0) = (sort([0..299])/30, 0, 0),各次运行会按顺序排列,p[1] 表示第一次运行
  • p(50..400)——一条轨道:表示状态在这些时刻之间的变化,会使用实时模拟自身的步长提前积分(lib/orbit.ts),使运动点沿轨道移动。状态族会为每次运行绘制一条路径(从元组开始运行时,p[1](50..400) 会绘制一条路径);标量状态会绘制其随时间的变化曲线,th(0..20) 即曲线 (t, th)。两者结合时,Rössler 吸引子会呈现为一条细带状轨道,粒子沿其流动

自定义坐标与复数根

  • r = sqrt(x^2+y^2); theta = atan2(y,x) 定义极坐标。 (r, theta) = (2, 9pi/4) 会绘制对应的点,角度会按 2π 取模。 使用右侧的字面值或滑块值,可在这些坐标中拖动该点。
  • (r, theta) = (3u, 6pi u) 描绘一个三圈螺旋; (r', theta') = (r(1-r), 1) 会绘制极坐标极限环场。
  • 1+2i 会绘制阿尔冈点;w^3 = 1 会绘制三个单位立方根。 系统会在当前视图中进行数值搜索;较小的解分支可能会遗漏。示例菜单中提供坐标示例。

矩阵

  • M = ((a, b), (c, d))——由行组成的元组是一个 2×2 或 3×3 矩阵(元组的方括号形式 [(a, b), (c, d)] 表示两个点);det(M)、trace(M)、矩阵向量乘法 M v 和 solve(M, v)(克莱姆法则)会在降级时进行符号展开,参见 lib/mat.ts。因此,(x', y') = A (x, y) 可以绘制一个可通过滑块调节矩阵各项的相图,而 om' = solve(M, f) 则会以推导出的拉格朗日形式 M(θ)ω′ = f 积分双摆

参数曲线和曲面

  • (2cos(2pi u), 2sin(2pi u), 3u)——参数曲线,u ∈ (0,1)
  • u^2——单独一行 u、v 中的表达式会绘制其取值:u 在 [0, 1] 上均匀分布时 u² 的密度
  • (cos(2pi u)(2+cos(2pi v)), sin(2pi u)(2+cos(2pi v)), sin(2pi v))——参数曲面,u,v ∈ (0,1);逐片元使用 Newton 法求射线与曲面的交点,并采用光泽镜面材质

序列和数据

  • a_n = 1/n^2——一个序列:在整数 n ≥ 0 处绘制点;行上的 Σ 开关可切换为部分和 S_N(此序列收敛到 π²/6)
  • a_{n+1} = r a_n (1 - a_n)——一个递推关系:绘制映射曲线、对角线 y = x,以及从初始值 a_0 开始的蛛网图路径(为滑块定义 a_0 = 0.2,默认值为 ½)。当右侧的 x 未定义时,x 会成为参数轴,图像则为轨道/分岔图: a_{n+1} = x a_n (1 - a_n) 是逻辑斯蒂分岔
  • [3, 1, 4, 1, 5]——一个数据列表:在数轴上绘制点图,每个值位于 x = value,其重复项沿竖直方向堆叠(1 出现两次:点位于 (1, 1) 和 (1, 2))。[(1, 2), (3, 4)] 是散点图

回归

  • P = [(0, 1), (1, 3), (2, 5), (3, 7)]; P.y ~ m P.x + b 会拟合一条穿过这些点的直线。P.x 和 P.y 是这些点坐标组成的列表,按数据文件列的方式逐点配对(分别编写的两个列表 X、Y 相互独立,因此 (X, Y) 会形成网格)。未绑定的名称 m 和 b 会成为拟合常数;y = m x + b 会绘制模型,而 (P.x, P.y - (m P.x + b)) 会绘制残差。拟合行会报告系数、RMSE、R²(适用时)和观测数。
  • P.y ~ a P.x^2 + b P.x + c 会拟合多项式;P.y ~ a exp(b P.x) 会拟合非线性模型。已定义的常数保持固定,并在更改这些常数时重新拟合其他系数。请在拟合式上方定义数据和固定常数。
  • data.height ~ m data.age + b 可用于 CSV 列。缺失或非有限的数据对会被跳过,并附带数量统计;长度不匹配和系数无法识别会报错。共享链接中的缺失 CSV 文件仍保留在本地设备上。
  • 拟合是静态的,最多支持 8 个系数和 10,000 个观测值(非线性模型为 2,000 个)。非线性拟合使用确定性初始值,并报告局部拟合结果;不保证得到全局最优解。

傅里叶分析

  • s = interval(0, 1); fourier(cos(4pi s) + 0.5sin(10pi s))——单边振幅谱。区间是信号的变量及其周期,因此频率的单位是该变量的周期数;函数会在一个周期内读取,如 fourier(f(s))。默认使用 256 个样本;fourier(f(s), 512) 可设置样本数。
  • N = clamp(round(5), 0, 48); y = reconstruct(f(s), N)——带符号的均值加前 N 个谐波,并保留相位。可在 N 后指定可选的样本数。傅里叶分析示例会在关联视图中显示原始信号、频谱和重构结果。
  • S = sort(data.signal, data.row); fourier(S)——按文件顺序排列的等间距 CSV 样本,覆盖 [0, 1);也可使用 fourier(S, interval(0, 10))。元组也适用,例如 fourier((0, 1, 0, -1));方括号列表没有顺序。样本必须是有限实数,且不能有间隙。两种操作都假定信号是周期延拓的静态信号;信号滑块变化时会重新计算系数。重构最多支持 128 个谐波;样本数范围为 2 到 4096。

上下文语法帮助 方程编辑器会在输入时建议函数、定义名称和已加载的 CSV 列,并在函数调用中显示签名。按 Tab 或单击可插入建议;使用方向键选择建议,再按 Enter 插入。其他情况下,按 Enter 会新建一行方程,按 Escape 会关闭帮助,补全会作为一次可撤销的文本编辑处理。注释和带引号的字符串不会触发建议。

数论与复分析

  • gcd(a, b) / isprime(n) — 数论;试试 a_n = isprime(n)
  • ln(w-2) - ln(w+2) — 复分析:i 是虚数单位,且 w = x + iy;复值表达式会绘制其虚部的等值线(电场线)和实部的等值线(等势线),因此可以直接用复势绘制静电场。re/im/arg/abs/conj 可将值转换回 ℝ,例如 im(ln(w)) = 1 会绘制成普通的隐式曲线

方程会保存在 URL 哈希中。拖动可平移/旋转,滚轮可缩放,在 3D 中右键拖动(或按住 Shift)可平移;单击颜色圆点可切换颜色。光标悬停在点和放置的 ODE 种子上时,它们会高亮显示,并可随光标拖动。方程面板是固定在角落的卡片:轻甩它——触摸卡片任意位置,或用鼠标沿卡片顶部边缘拖动握柄条——即可将它移到任意角落;也可以将它甩过任意边缘,彻底清空视图;面板会跟随指针,并沿甩动方向离开。留下的 y= 标签可用于恢复面板(轻触它,或拖动它将面板拉入),选定的角落会保持不变。

worker/ — Cloudflare Worker 入口:提供构建后的应用,并处理 /api/* 路由。

贡献

你需要 Node 24 和 pnpm。运行 pnpm install,然后运行 pnpm web 启动开发服务器。 提交 PR 前,请运行 CI 执行的相同检查:

pnpm typecheck    # tsc over lib, web and worker
pnpm lint         # Oxlint, including type-aware rules
pnpm fmt:check    # Oxfmt (pnpm fmt rewrites files in place)
pnpm vitest run   # unit tests

pnpm lint:fix 会应用 Oxlint 能自动修复的问题。在 VS Code 中,安装推荐的 Oxc 扩展,即可在输入时查看 lint 错误。

许可证

MIT — 参见 LICENSE。legacy 分支上 2026 年之前的 graph.tk 代码仍遵循其原有的 LGPL-3.0 条款;当前代码库未复用其中的任何代码。

坐标轴缩放

按住 Option/Alt 并拖动 2D 画布,可分别缩放各坐标轴:水平移动缩放 x 轴,垂直移动缩放 y 轴,缩放锚定在初始指针位置。普通缩放会保持比例。在视口行中设置 ratio = 1,即可恢复坐标轴单位等长。

缩放会创建或更新可分享的视口行: view(x = -10..10, y = -1..1, ratio = 5)。正值 ratio 表示每个 y 单位对应的像素数除以每个 x 单位对应的像素数;省略时默认为 1。系统会在保持该比例的同时调整边界范围,包括在不同屏幕尺寸下。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。