关于 visimark
visimark 是用于校验 Markdown 数字与其公式是否一致的 MCP 服务和命令行工具,面向编辑带计算内容文档的 Agent、分析人员与工程师。它保留普通 Markdown 格式,并可在 CI 中发现数字漂移。
主要功能
- 01检查数字与公式是否一致
- 02从现有数字推导候选公式
- 03修复过期的计算值
- 04解释依赖关系与计算顺序
- 05模拟参数情景并读取结果
适用场景
- 01审查 Agent 编写的报告和预算
- 02在 CI 中检查文档的计算结果
- 03为现有 Markdown 表格添加公式
- 04对人员配置模型进行情景分析
MCP 相关
它提供 MCP 服务,让 Agent 检查文档中的数字、公式和计算结果。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
VisiMark
Markdown 文档的完整性保障层:它会检查文档中的每个数字是否仍与生成它的公式一致,确保 Agent 写出的正确公式不会搭配错误的总计发布。
VisiMark 会检查 Markdown 文档中的数字,尤其是 Agent 编写的文档。每个计算值都附带其公式,由机器证明两者仍然一致;若不一致,CI 就会失败。文档仍然是纯 Markdown。
这在 Markdown 由 AI Agent 编写或编辑时最为重要。
Agent 擅长编写公式,却不擅长计算这些公式描述的结果:Net = Price * Qty 是 Agent 能写对的内容,
而 50.00 则是它猜出来的数字。写出公式而非数字,数字就不再是一项主张,而成为一项推导——可在差异中审查、重新运行,并在 CI 中强制验证。Agent 负责编写,VisiMark 负责验证,Git 负责记录结果。
VisiMark 文档就是普通的 Markdown 文件。如今,它无需插件就能在 GitHub、VS Code 预览中正确渲染,也能通过 pandoc 转换为 HTML 和 Word; 这已经过验证,而非仅仅假设。VisiMark 带来的额外保障是:文档中的每个 计算数字都附带生成它的公式,机器可以证明两者仍然一致,而对任一内容的更改都会以简短、易读的差异呈现。
适用对象
目前涵盖六类用户,每类都有明确的入门方式。刻意保持简短——只有当其中某类用户真正开始使用时,才会扩展内容。
- Agent 和审阅者:验证模型刚刚编写的文档——使用 MCP 服务和Agent 技能。
- 分析师、创始人、产能规划人员:无需切换到第二个标签页或复制文件,就能进行假设分析——通过
eval --scenario,在docs/tutorial/runway.md中的人力规划模型中演示。 - 任何已经在检查 Markdown 代码风格的人——可使用
pre-commit 钩子、
remark-lint-visimark、markdownlint-rule-visimark和组合式 GitHub Action。 - 工程师、科学家及任何使用单位的人——在名称后的方括号中声明单位,如
Rate [PLN]或speed [m/s] = Distance / Duration;check会拒绝kg + m,并推导出km/h(参见 拒绝执行的操作)。 - 拥有大量数字的 Obsidian 用户——可使用 Obsidian 插件,在阅读模式和实时预览中标记每个计算值。
- 金融从业者——通过一项贷款和一项投资评估,了解
NPV、IRR、PMT,以及这三者要求声明的十进制精度。
渲染正常的错误发票
docs/example-invoice-drift.md 是一份真实的 B2B
发票:有人把待命工时从 12 调高到 20,却没有更新任何依赖该数值的内容。它在
GitHub、Markdown 预览及任何其他地方都呈现为一份干净、可信的发票——这正是本项目要解决的问题。文档中的每个数字都附带生成它的公式;语法将在下文介绍。以下是 visimark check 检查同一文件的结果,而审阅者刚刚才快速浏览并批准了这份文件:
$ visimark check docs/example-invoice-drift.md
docs/example-invoice-drift.md
STALE lines.Net · On-call support 3120.00 ≠ 5200.00 Qty * Rate
STALE lines.VAT · On-call support 717.60 ≠ 1196.00 Net * vat
STALE lines.Gross · On-call support 3837.60 ≠ 6396.00 Net + VAT
STALE lines.Gross · Discovery workshop 4428.50 ≠ 4428.00 Net + VAT
STALE lines.net_total 23300.00 ≠ 25380.00 SUM(Net)
STALE lines.vat_total 5359.00 ≠ 5837.40 SUM(VAT)
STALE lines.gross_total 28659.00 ≠ 31217.40 SUM(Gross)
STALE lines.gross_total 28659.00 ≠ 31217.40 SUM(Gross)
STALE schedule.Amount · Signature 8597.70 ≠ 9365.22 Share * lines.gross_total
STALE schedule.Amount · Delivery of backend 11463.60 ≠ 12486.96 Share * lines.gross_total
STALE schedule.Amount · Acceptance 8597.70 ≠ 9365.22 Share * lines.gross_total
STALE schedule.covered 28659.00 ≠ 31217.40 SUM(Amount)
STALE terms.early_pay_total 28085.82 ≠ 30593.05
STALE terms.early_pay_saved 573.18 ≠ 624.35
STALE 8 prose anchors bound to the values above
DATE schedule.Due · Delivery of backend "15.10.2026"
Dates must be ISO 8601 calendar dates: YYYY-MM-DD.
Unambiguous — `visimark fmt --fix-dates` rewrites it to 2026-10-15.
DATE schedule.Due · Acceptance "11/12/2026"
Dates must be ISO 8601 calendar dates: YYYY-MM-DD.
Ambiguous: 2026-12-11 or 2026-11-12, 29 days apart. Fix by hand.
NOTE schedule.Days · 2 rows not verified (upstream DATE errors)
UNDEF terms.eur_total unknown name `fx_rate`
did you mean `fx_eur`?
VECTOR recon.variance `schedule.Amount` is a column, not a value.
Wrap it in an aggregate: SUM(schedule.Amount)
CYCLE late_fees.base → late_fees.fee → late_fees.total → late_fees.base
27 problems (22 stale, 5 errors)
$ echo $?
1
共发现二十七个问题:付款日期存在二十九天的歧义、有人为让列看起来对齐而手动调整了某个单元格,以及循环引用——这些问题在渲染后的页面上全都不可见,却都能在人发现之前被捕获。
为什么现在这很重要
越来越多包含数字的文档以文本形式编写并保存在 Git 中:报告和研究笔记、估算和预算、报价和发票、项目计划、财务摘要。文本非常适合协作、审阅和版本控制。但普通 Markdown 无法表达这个数字由这些输入得出,并且必须始终与它们一致——因此,一旦某个输入发生变化,所有受其影响的数字在由人工重新核对之前都只能算是猜测。
VisiMark 补上了这一缺失层。与 Agent 协作时的工作栈,是在轻度格式化的文档上使用文本编辑器;Markdown 已经涵盖了文字内容,而 VisiMark 则涵盖计算。算术本身不是价值所在——审计轨迹才是。
效果示例
| Item | Price | Qty | Net |
|-------|------:|----:|------:|
| pen | 5.00 | 10 | 50.00 |
| paper | 0.10 | 100 | 10.00 |
```vmark #order
Net = Price * Qty
total = SUM(Net)
```
Order total: **60.00**
四个概念,这就是全部格式:
vmark块为上方的表格声明公式,并为工作表命名。- 列规则统一——
Net = Price * Qty是适用于每一行的一条规则,而不是每个单元格一个公式。没有规则的列是输入列,绝不会被覆盖。 - 聚合值是标量,并在旁边声明。这取代了总计行;表格始终保持矩形。
- 锚点将标量写入句子。HTML 注释在所有目标渲染器中都不可见,因此正文读起来一切正常,同时数字仍可由机器检查。
教程
docs/tutorial.md 是完整的端到端教程:二十八个简短章节,从普通 Markdown 表格开始,逐步构建出经过检查的文档、CI 任务,以及一个读取数值的脚本。它按照依赖顺序讲解这门语言、check 可以报告的每一项发现,以及让绿色检查始终有意义的一个习惯。教程中的每段操作记录都是真实的。
此外,还有一个并排对照的阅读版本:
docs/tutorial.html,
它会逐块并排显示 Markdown 源码和渲染结果。
示例
docs/example-invoice.md 是一份完整的 B2B 发票,所有内容都由计算得出:行项目、增值税、根据含税总额推导出的付款计划、提前付款条款、货币换算,以及证明分期付款总额等于发票金额的对账。附录解释了每种机制。
docs/example-invoice-drift.md 是同一份发票,并展示了本 README 顶部所示的偏差——上方的 27 problems 操作记录来自 check 对这个确切文件的检查,其附录逐一说明了全部 27 个问题。
docs/example-quote-plain.md 展示了另一种情况:一份完全不含 VisiMark 的报价——没有 vmark 块,没有锚点,只有一张表格和写在正文中的总额,就像 Agent 在有人为其添加规则之前交付的文档。visimark infer 会读取它,并提出能够重现其中所有现有数字的规则:
$ visimark infer docs/example-quote-plain.md
docs/example-quote-plain.md table at line 10 — 4 rows, 7 columns
column rules
Revenue = Seats * Fee 4/4 rows
Materials = Revenue * 0.08 4/4 rows
Delivered = Revenue + Materials 4/4 rows
constants worth naming
0.08 also appears as "8%" in prose, line 18
scalars matching figures in prose
72 line 17 = SUM(Seats) seats_total
27600.00 line 18 = SUM(Revenue) revenue_total
2208.00 line 19 = SUM(Materials) materials_total
29808.00 line 19 = SUM(Delivered) delivered_total
530.00 line 20 = AVG(Fee) fee_avg
no rule found — treating as inputs
Module, Format, Seats, Fee
also fits, not proposed
Delivered = Revenue * 1.08 prefers a rule over materialised columns
Delivered = Materials * 13.5 prefers a rule over materialised columns
docs/example-quote-plain.md table at line 24 — 3 rows, 4 columns
column rules
Amount = Share * unnamed1.delivered_total 3/3 rows
scalars matching figures in prose
29808.00 line 30 = SUM(Amount) amount_total
no rule found — treating as inputs
Stage, Share, Due
also fits, not proposed
Amount = Share * 29808 prefers a rule over materialised columns
4 rules, 0 aliases, 6 scalars, 6 anchors.
只有在某条规则能以该列自身的精度精确重现每一行时,才会提出这条规则——绝不采用最佳拟合,也不使用阈值;also fits, not proposed 会列出而不是悄然舍弃,因为让作用于物化列的规则胜过只有一个常数的规则,是值得展示的判断。--write 只会插入上方所示的块和锚点,不会改写其他内容。即使某条规则适用于除一行外的所有行,也绝不会将其写入;它会被报告为近似匹配——这相当于工具告诉你文档中已经有错误数字,而这发生在任何人运行 check 之前。文档自身的附录逐一说明了所有机制,包括近似匹配的情况。
infer 是处理这类文档的入口:对于这类文档,check 原本无事可查,因为它们完全没有公式。两者配合便形成闭环——infer 为普通表格添加规则,check 则确保规则持续生效。
工作原理
VisiMark 会解析文档,构建覆盖所有工作表的依赖图, 按拓扑顺序排序,并使用十进制算术进行计算。检测到循环 依赖时,会报告循环路径的完整内容。
flowchart LR
parse[Parse Markdown] --> deps[Build dependency graph]
deps --> sort[Topological sort]
sort --> evaluate[Evaluate in decimal]
evaluate --> cycle{"Cycle?"}
cycle -->|yes| report[Report the CYCLE path]
cycle -->|no| values[Computed values]
CLI 就是产品本身。Agent 必须能够在没有编辑器的情况下验证文档;VS Code 扩展只是之后再推出的轻量封装。
命令
一共有七个。check 最重要;其他命令用于让文档达到 check 能够严格检查的状态、说明它做了什么,或向它提出假设性问题。
flowchart LR
plain[Plain table] -->|"infer --write"| wired[Rules and anchors in the file]
wired -->|edit an input or a rule| stale[Stored values disagree]
stale -->|fmt| wired
stale -->|check| fail[Exit 1]
wired -->|check| pass[Exit 0]
wired -.-> evalCmd["eval / explain"]
| 命令 | 功能 | 选项 | 写入内容 | 退出代码 |
|---|---|---|---|---|
visimark check FILE... | 重新计算每个公式,并报告不再与公式结果一致的数值 | — | 从不写入任何内容 | 0 无问题 · 1 发现问题 · 2 用法错误或文件不可读 |
visimark fmt FILE... | 通过替换其负责的每个数值对应的字节,在原处修复过时的值 | --fix-dates 会重写含义明确的非 ISO 日期 | 仅写入计算单元格和锚定值——绝不修改输入、正文或标题 | 0 无问题 · 1 仍有无法修复的问题 · 2 用法错误或文件不可读 |
visimark infer FILE... | 推断出能复现文档现有数值的规则,并提出建议 | --write 会插入建议的规则 | 除非使用 --write,否则不写入任何内容;使用时也只会插入内容 | 0 无论发现什么都返回,因为此命令仅提供建议 · 2 用法错误或文件不可读 |
visimark eval FILE | 打印计算结果——全部结果,或按名称打印单个结果 | --get NAME、--json | 不写入任何内容 | 0 · 2 用法错误、文件不可读或不存在该名称 |
visimark explain FILE | 打印每个工作表的输入、规则和计算顺序 | #sheet 可将范围限制为一个工作表 | 不写入任何内容 | 0 · 2 用法错误、文件不可读或不存在该工作表 |
visimark ref [NAME] | 打印内置函数的说明——签名、参数、错误和示例——或列出全部 16 个函数 | --json | 不写入任何内容 | 0 · 2 不存在该函数 |
visimark simulate FILE... | 提出文档的 lattice 参数声明的所有问题以及默认问题,并打印其 report 语句要求的读数 | --fail-on-fault:当报告工作表无法启动时,让运行失败 · --progress:将进度报告写入 stderr | 不写入任何内容 | 0 已打印读数,即使断言失败也如此 · 1 任何位置都没有 report,或在使用 --fail-on-fault 时有工作表无法启动 · 2 用法错误或文件不可读 |
docs/cli-reference.md 汇总了所有选项、退出代码,以及 check 可能报告的每一种问题。
check 只读,因此可以安全地用于任何内容。fmt 只会修复过时的值,仅限过时的值:其他所有问题都需要由人来判断,因此它只会报告这些问题,不会修改。
绿色勾号必须有意义
没有公式的文档无从产生不一致,因此只比较数字与规则的检查器会判定它没有问题——这是它可能给出的最误导性的答案。check 会将没有附加规则的表格本身报告为问题:
$ visimark check quote.md
quote.md
COVERAGE a table with no `vmark` rules — nothing in this document is checked
run `visimark infer` to derive them, or mark it ``
1 problem (0 stale, 1 error)
有两点能避免这种情况令人烦恼。首先,必须存在表格才会触发检查,因此不会要求散文内容——README、变更日志等——进行它们并不涉及的算术检查。其次,检查范围是整个文档,因此,作为输入的参考表即使确实没有规则,只要其他表格包含规则,就能通过检查。
如果文档确实没有任何可推导的内容,请在文档中说明:
这是唯一的豁免方式,而且是刻意如此。标记保存在文件中,而不是工作流标志里,因此会随内容一起流转、出现在审查中,也能通过 grep 找到。如果 visimark infer --write 没有找到任何可推导的内容,就会替你写入标记;但如果它发现了接近匹配的内容,或发现两条无法择一的规则,就会拒绝写入,因为这意味着文档确实包含算术内容,需要人工检查。标记和其他内容一样会被检查:如果之后给带有标记的文档添加了规则,check 会告诉你这个标记现在已经不正确。
在 CI 中
check 的意义就在于让它在人的判断之外运行,因此 CI 的配置只需一行:
npx visimark check **/*.md
首次发现不一致时,命令就会以非零状态退出,这正是大多数 CI 系统所需的行为。GitHub Actions 工作流也可以使用本仓库提供的组合式操作(action.yml)实现同样的检查,无需手动编写 npx 命令:
- uses: michal-niedzwiedzki/[email protected]
with:
files: "docs/**/*.md"
无需配置,也没有严格程度可调:指定一个 glob 就完成了全部设置。该 glob 下任何包含表格却没有规则的文档都会导致失败。这就是为什么上面的 `` 标记应放在文件中,而不是这个工作流里——这是针对文档本身的决定,而不是针对某次 CI 运行的决定。
已使用 remark/remark-lint 的项目可以改用 remark-lint-visimark 添加相同的检查,详见 docs/ci.md 第 25 章。
使用 markdownlint 的项目可以通过 markdownlint-rule-visimark 添加这些检查,详见 docs/ci.md 第 26 章。
Agent 可以通过 MCP 使用 visimark-mcp 访问同一个引擎:除 simulate 外,所有命令都作为工具提供;编写规范作为资源提供;只有操作员打开写入开关后才会写入任何内容:
npm i -g visimark-mcp # or: bun add -g visimark-mcp
npx visimark-mcp # or: bunx visimark-mcp
claude mcp add visimark -- npx -y visimark-mcp
完整功能说明见 docs/mcp.md;docs/ci.md 第 27 章介绍了如何在 CI 检查旁运行它。
从设计上即可进行差异比较
.xlsx 是一个 XML 压缩包:更改一个单元格,代码审查就能看出文件变了,而除此之外几乎看不出任何信息。VisiMark 文档像源代码一样可供审查,这是设计约束,而非文本格式带来的附带效果。
fmt 绝不会重新渲染 Markdown。它会根据位置找到自己负责的每个值,并在原始字节缓冲区中进行替换,因此重写只会改动那个数字的字符,不会改动其他内容——不会重新排版段落,不会重新规范化强调标记,不会重新对齐表格列,也不会产生经 Markdown 打印器往返处理后仅更改单元格就会带来的四百行差异。它也只写入自己负责的内容:计算单元格和锚定值。输入列、正文和标题都属于人工编辑的范围,绝不会被改动。
在示例发票中提高一项输入——将待命工时从 12 小时调至 20 小时,这正是上文漂移示例中未能传播的那项编辑——会使 fmt 更新 6 个单元格和 9 个锚定值,最终得到一个127 行文档中的 13 行差异。每一处变更都是确实依赖该输入的数值,因此差异本身就是传播过程:审查者能看到增值税、三期里程碑分期款、提前付款条款和欧元换算都随之变动,并能确认变动的原因正确。
另一方面,差异包含所有内容。公式就在文档中,因此规则变更会显示为规则变更。没有任何文件外部的因素能改变数字——没有插件、没有配置、也没有时钟。而且由于聚合接收的是列而不是表达式,每个中间值都会显示在页面上:总计永远是审查者看得见的数字之和。
它拒绝做什么
当一个值可能有两种含义时,VisiMark 会报错,而不是猜测。
日期只能采用 ISO 8601 格式,即 YYYY-MM-DD,共 10 个字符。15.10.2026 会被拒绝并提示修正,因为 15 不可能是月份。11/12/2026 则会直接被拒绝,因为根据作者所在地的不同,它可能是 12 月 11 日,也可能是 11 月 12 日,无论多么仔细,都无法仅凭阅读判断。出于同样的原因,千位分隔符也会被拒绝。
列可以带有货币符号或物理单位,例如 $5.50、12 N;VisiMark 会在计算时去掉它们,并在写入时加回。但它不会允许同一列表示两种含义:一列中同时有 $5.00 和 €5.00 会报错,而不会求和。单位写在方括号中时——例如标题中的 Weight [kg],或绑定中的 fx_eur [PLN/EUR]——单位会贯穿每个公式,因此把千克加到米上,或乘以汇率而不是除以汇率,都会导致 check 失败。系统绝不会按系数进行换算,也绝不会把 $ 读作 USD。
同一作用域中重复绑定名称会报错,而不会被静默覆盖。
没有布尔字面量。比较会生成布尔值,IF() 会使用这些布尔值,但布尔值绝不会写入单元格——物化值只能是数字、日期或字符串,因此列中的 true 会保持为它看起来的字符串。
这里没有插件架构,将来也不会有。 文档中的数字只取决于文档自身的文本,以及读取它的 VisiMark 版本,不受其他任何因素影响——没有扩展模块、配置文件、环境、网络或时钟。由宿主提供函数的注册表会生成无法根据文档检查其算术逻辑的文档,而防止这种情况正是该格式存在的唯一目的。如果内置词汇表太小,解决办法是在引擎中添加新的原语,让所有人都能阅读和运行;如果某个值确实来自外部,就应放在由人填写的输入列中。扩充词汇表的请求——以及任何其他语言或工具变更提案——都通过 docs/vocabulary-catalogue.md 提交,其中记录了每项请求及其决定;评审流程见 docs/issue-runbook.md。
这让格式变得更小,而不只是更严格:没有区域设置,没有配置,也没有关于单独出现的 / 表示什么的规则。
状态
七个命令均已用 TypeScript 实现。使用 npm i -g visimark 或 bun add -g visimark 安装 visimark
命令;它会在 PATH 中可用的 Node 或 Bun 下运行。若要不安装直接运行,请使用
npx visimark 或 bunx visimark。(在 Windows 上,npx / npm i -g 垫片需要 PATH 中有
sh,Git Bash 或 WSL 会提供此命令。)三个已完成的示例就是验收套件:对漂移发票运行
check 会逐字节复现上方的输出记录,fmt 不会更改格式正确的发票,而对 docs/example-quote-plain.md 运行
infer(这是一段完全不含公式的引文),会复现该文档附录中的输出记录。设计说明(包括暂缓的工作和已知的权衡)见 docs/visimark-design.md。
| 构件 | 发布位置 | 了解更多 |
|---|---|---|
visimark,命令行工具 | npm | docs/cli-reference.md |
visimark,库 | npm,同一软件包 | docs/library.md |
visimark-mcp,MCP 服务 | npm 和官方 MCP 注册表 | docs/mcp.md |
| 语言服务和 VS Code 扩展 | VS Code Marketplace 和 Open VSX | editors/vscode/README.md |
| Obsidian 插件 | Obsidian 社区插件,以及其自身的 GitHub releases(不带 v 的标签) | editors/obsidian/README.md |
| Joplin 插件 | 未发布;CI 构建生成的 .jpl 文件 | editors/joplin/README.md |
codemirror-visimark | npm,从包含它的首个标签开始发布 | packages/codemirror-visimark/README.md |
markdown-it-visimark | npm,从包含它的首个标签开始发布 | packages/markdown-it-visimark/README.md |
remark-lint-visimark | npm | packages/remark-visimark/README.md |
markdownlint-rule-visimark | npm | packages/markdownlint-visimark/README.md |
docs/distribution.md 记录了各构件发布到的所有注册表和目录。vX.Y.Z 标签会发布 npm 软件包、MCP 注册表条目和 VS Code 扩展;
docs/releasing.md 是发布检查清单,而
CONTRIBUTING.md 说明了如何从克隆的仓库构建并安装编辑器插件。
面向 Agent
skills/visimark/SKILL.md 是用于编写和验证这些文档的 Agent 技能。将其复制到 ~/.claude/skills/visimark/ 即可安装。这里也值得重申它的核心警告:绿色勾号只能证明结果一致,不能证明结果是推导出来的。修改一个输入,并确认检查器开始报错,然后再相信文档已正确接入。上文提到的 COVERAGE 检查结果旨在防止 Agent 在不包含构建内容的文档上报告构建通过,但养成这种习惯仍是更好的保障。
此外,还有一个 MCP 服务 visimark-mcp,供在陌生代码库中工作的 Agent 使用:可运行 npx visimark-mcp 或 bunx visimark-mcp,也可运行 claude mcp add visimark -- npx -y visimark-mcp。它会将上述技能作为资源提供,因此验证器会自带这套规范,无需另行配置。除非使用 --allow-write 启动,并且指定由宿主声明的根目录,否则它只读。
编辑器支持规范见
docs/visimark-editor-plugins-design.md:
一个语言服务器,支持将持续运行的 check 作为诊断、由编辑器自身的保存时格式化功能触发的 fmt、快速修复,以及显示计算结果但不改动字节的行内提示;首个客户端为 VS Code。
git clone … && cd visimark && bun install
bun run test # the full suite, the three examples included
bunx visimark check docs/example-invoice-drift.md
bun install 会构建引擎,并将 visimark 命令链接到
node_modules/.bin,因此在全新克隆的代码库中可以运行 bunx visimark。若要不经构建直接从源码运行 CLI,请使用 bun packages/visimark/src/cli/main.ts check FILE。
这个项目最初是基于 CSV 的构想,后来转为 Markdown,这样多个小表格就能放在同一份主文档中,而且文件呈现出来像一份文档,而非数据。这个名称向 VisiCalc 致意——它是首款电子表格软件,最初由 VisiCorp 为 Apple II 开发,后来移植到了 IBM PC。
不在范围内
VisiMark 有意不做电子表格的替代品。它没有网格、展示层、单元格样式、本地化,也不兼容 Excel 文件,更不会试图实现 Excel 的函数库。整洁美观的展示请使用其他工具;如果你想要的是电子表格,那就用电子表格。
如果你想要的是一份文档,就使用 VisiMark:纯文本,无需工具即可阅读,可在普通拉取请求中审阅,可由人或 Agent 编写,而且数字可以在每次提交时检查。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。