
Visimark
io.github.michal-niedzwiedzki由 GitHub 帳號 michal-niedzwiedzki 發布v0.4.1更新於 Oct 24, 2026
MCP server for VisiMark, a document integrity layer for Markdown: checks numbers against formulas.
概覽
VisiMark 的 MCP 伺服器,讓助理檢查、修復並推斷 Markdown 文件中數字背後的公式。
- 可以做什麼
- 檢查 Markdown 文件:重新計算所有公式並回報已不一致的數字,不寫入任何內容
- 就地修復過期數值,只更動計算儲存格與錨定值,不碰輸入欄與正文
- 推斷能重現一般表格中既有數字的規則,並可選擇寫入檔案
- 評估文件:輸出計算值、說明工作表的輸入與求值順序、查詢內建函式
- 以資源形式提供撰寫規範,寫入操作須由操作者開啟寫入閘門
- 適用情境
- 適合助理撰寫或修改帶有數字的 Markdown 文件(發票、報價、預算、報告)時,希望核對算術而非直接採信。也適合把這類文件放在 Git 中、希望在 CI 取得可核查稽核軌跡的團隊。
- 執行需求
- 以 npm 套件 visimark-mcp 透過 stdio 在本機執行,可全域安裝或以 npx/bunx 執行;PATH 中需有 Node 或 Bun。未宣告任何驗證、環境變數或標頭。在 Windows 上 npm/npx 的包裝指令需要 PATH 中有 sh,Git Bash 或 WSL 可提供。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Visimark,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
VisiMark
[visimark MCP server – quality and maintenance score on Glama]
A document integrity layer for Markdown: it checks that every number in a document still matches the formula that produced it, so an agent's correct formula can't ship with a wrong total.
VisiMark checks the numbers in Markdown documents, especially ones an agent wrote. Every computed value carries its formula, a machine proves the two still agree, and CI fails when they don't. The document stays plain Markdown.
This matters most when the Markdown is written or edited by an AI agent.
Agents are reliable at writing formulas and unreliable at the arithmetic those
formulas describe: Net = Price * Qty is something an agent gets right,
50.00 is something it guesses. Write the formula instead of the number and
the number stops being a claim and becomes a derivation — reviewable in a
diff, re-runnable, enforceable in CI. The agent writes, VisiMark verifies, Git
records the result.
A VisiMark document is an ordinary Markdown file. It renders correctly on GitHub, in VS Code preview, and through pandoc to both HTML and Word, today, with no plugin — verified, not assumed. What VisiMark adds is that every computed number in it carries the formula that produced it, that a machine can prove the two still agree, and that a change to either shows up as a small, readable diff.
Who it's for
Six audiences so far, each with a specific entry point. Kept short on purpose — it grows when one of these gets a real user, not before.
- Agents and reviewers verifying a document a model just wrote — the MCP server and the agent skill.
- Analysts, founders, capacity planners who want a what-if without a
second tab or a copy of the file —
eval --scenario, worked through on a headcount model indocs/tutorial/runway.md. - Anyone who already lints Markdown — the
pre-commit hook,
remark-lint-visimark,markdownlint-rule-visimark, and the composite GitHub Action. - Engineers, scientists, anyone with a unit — declare it in a bracket after
a name,
Rate [PLN]orspeed [m/s] = Distance / Duration, andcheckrefuseskg + mand deriveskm/h(see What it refuses to do). - Obsidian users with a vault of numbers — the Obsidian plugin, which marks every computed value in reading mode and Live Preview.
- Finance —
NPV,IRR,PMT, and the decimal precision the three of them force you to declare, worked through in a loan and an investment appraisal.
A wrong invoice that renders clean
docs/example-invoice-drift.md is a real B2B
invoice after someone raised the on-call hours from 12 to 20 and updated
nothing that depends on it. It renders as a clean, plausible invoice on
GitHub, in a Markdown preview, anywhere — which is the entire argument for
this project. Every number in it carries the formula that produced it; the
syntax follows further down. Here is visimark check reading the same file a
reviewer just skimmed and approved:
Twenty-seven problems: a payment date ambiguous by twenty-nine days, a cell someone nudged by hand to make a column look right, a circular reference — all invisible on the rendered page, all caught before a human had to notice.
Why this matters now
More and more of the documents that carry numbers are written as text and kept in Git: reports and research notes, estimates and budgets, quotes and invoices, project plans, financial summaries. Text is excellent for collaboration, review and version control. But ordinary Markdown has no way to say this number came from these inputs, and it must still agree with them — so the moment an input changes, every figure downstream of it is a guess until a human re-checks it by hand.
VisiMark adds that missing layer. The working stack for collaborating with an agent is a text editor over lightly formatted artifacts; Markdown already covers the prose, and this covers the calculation. The arithmetic is not the value — the audit trail is.
What it looks like
Four ideas, and that is the whole format:
- A
vmarkblock declares formulas for the table above it, and names the sheet. - Columns are uniform —
Net = Price * Qtyis one rule for every row, not a formula per cell. Columns with no rule are inputs, and are never overwritten. - Aggregates are scalars, declared alongside. This is what replaces the totals row; tables stay rectangular.
- An anchor materialises a scalar into a sentence. The HTML comment is invisible in every target renderer, so the prose reads normally while the number stays machine-checkable.
The tutorial
docs/tutorial.md is the end-to-end tutorial: twenty-eight
short chapters from a plain Markdown table to a checked document, a CI job and a
script reading values back out. It teaches the language in dependency order, every
finding check can report, and the one habit that keeps a green check meaningful.
Every transcript in it is real.
There is a side-by-side reader for it at
docs/tutorial.html,
which shows each block's Markdown source next to its rendering, in lockstep.
Worked examples
docs/example-invoice.md is a complete B2B invoice
that computes itself: line items, VAT, a payment schedule derived from the gross
total, early-payment terms, a currency conversion, and a reconciliation that
proves the instalments sum to the invoice. Its appendix explains each mechanism.
docs/example-invoice-drift.md is that same
invoice with the drift shown at the top of this README — the 27 problems
transcript above is check reading this exact file, and its appendix walks
through every one of the 27 problems.
docs/example-quote-plain.md is the other
direction: a quote with no VisiMark in it at all — no vmark block, no
anchor, just a table and a total written in prose, the way an agent hands one
over before anyone has wired it up. visimark infer reads it and proposes the
rules that reproduce every number already there:
A rule is proposed only if it reproduces every row exactly, at that column's
own precision — never a best fit, never a threshold, and also fits, not proposed is listed rather than silently dropped, because a rule over
materialised columns beating one with a bare constant is a judgment call worth
seeing. --write inserts exactly the blocks and anchors above and rewrites
nothing else. A rule that fits every row but one is never written; it is
reported as a near-miss instead — the tool telling you the document already
has a wrong number in it, before anyone runs check on it. The document's own
appendix walks through every mechanism, including that near-miss case.
infer is the way in for the document check would otherwise have nothing to
say about: one with no formulas at all. Pairing the two closes the loop —
infer gets a plain table wired up, and check keeps it that way.
How it works
VisiMark parses the document, builds a dependency graph across every sheet, sorts it topologically, and evaluates in decimal arithmetic. Circular dependencies are reported with the full path through the cycle.
The CLI is the product. An agent must be able to verify a document without an editor; a VS Code extension is a later, thin wrapper.
The commands
Seven of them. check is the one that matters; the rest exist to get a
document into a state check can be strict about, to explain what it did, or
to ask it what-if questions.
Every option, every exit code and every finding check can report is
tabulated in docs/cli-reference.md.
check is read-only, so it is safe to point at anything. fmt repairs stale
values and only stale values: every other kind of problem is a question a
person has to answer, so it reports those and leaves them alone.
A green check has to mean something
A document with no formulas in it has nothing to disagree with, so a checker
that only compares numbers to rules would call it clean — the most misleading
answer it could give. check reports a table with no rules attached to it as a
problem in its own right:
Two things keep that from being annoying. It needs a table to be present, so prose — a README, a changelog — is never asked for arithmetic it does not have. And it is counted across the whole document, so a reference table that really is all input passes as long as some other table carries a rule.
When a document genuinely has nothing to derive, say so in the document:
That marker is the only way out, and deliberately so. It lives in the file
rather than in a workflow flag, so it travels with the content, shows up in
review, and turns up in a grep. visimark infer --write writes it for you
when it finds nothing whatsoever to derive — and refuses to when it found a
near-miss or two rules it cannot choose between, because those mean the
document does have arithmetic and wants a person to look. The marker is
checked like anything else: add rules to a marked document later and check
tells you the marker is now wrong.
In CI
The whole point of check is that it runs somewhere other than a human's
judgment, so the CI story is one line:
That exits non-zero on the first disagreement, which is all most CI systems
need. A GitHub Actions workflow can do the same with the composite action
this repo ships (action.yml) instead of hand-rolling the
npx line:
There is nothing to configure and no strictness dial to find: pointing it at a
glob is the whole setup. Any document under that glob with a table and no rules
is a failure, which is why the <!--vmark:no-formulas--> marker above belongs
in the file rather than in this workflow — the decision is about a document,
not about a CI run.
A project already on remark/remark-lint adds the same checks with
remark-lint-visimark
instead — see docs/ci.md chapter 25.
A project on markdownlint adds
them with
markdownlint-rule-visimark
— see docs/ci.md chapter 26.
An agent reaches the same engine over
MCP with
visimark-mcp, which serves
every command except simulate as a tool, the authoring discipline as resources, and writes
nothing unless an operator opens the write gate:
The full surface is docs/mcp.md, and chapter 27 of
docs/ci.md covers running it beside a CI
check.
Diffable by construction
An .xlsx is a zip of XML: change one cell and code review can tell you the
file changed, and essentially nothing more. VisiMark documents review like
source, and that is a design constraint rather than a side effect of being
text.
fmt never re-renders the Markdown. It locates each value it owns by position
and splices the original byte buffer, so a rewrite touches the characters of
that number and nothing else — no reflowed paragraphs, no renormalised emphasis
markers, no realigned table columns, none of the four-hundred-line diff a
round-trip through a Markdown printer would produce for a one-cell change. It
also writes only what it owns: computed cells and anchored values. Input
columns, prose and headings are human territory and are never touched.
Raising one input in the worked invoice — on-call hours from 12 to 20, the
very edit the drift example above leaves unpropagated — makes fmt update 6
cells and 9 anchors, and the result is a 13-line diff in a 127-line
document. Every changed line is a figure that genuinely depends on that
input, so the diff is the propagation: a reviewer sees the VAT, the three
milestone instalments, the early-payment terms and the EUR conversion all move
together, and can check that they moved for the right reason.
The other half is that the diff contains everything. The formula lives in the document, so a changed rule shows up as a changed rule. Nothing outside the file can alter a number — no plugins, no config, no clock. And because an aggregate takes a column rather than an expression, every intermediate is materialised on the page: a total is always the sum of numbers the reviewer can see.
What it refuses to do
Where a value could mean two things, VisiMark errors rather than guesses.
Dates are ISO 8601 only — YYYY-MM-DD, ten characters. 15.10.2026 is
rejected with an offered fix, because 15 cannot be a month. 11/12/2026 is
rejected outright, because it is 11 December or 12 November depending on where
its author lives, and no amount of care catches that by reading. Thousands
separators are rejected for the same reason.
A column may carry a currency symbol or a physical unit — $5.50, 12 N —
and VisiMark strips it to compute and puts it back when it writes. What it will
not do is let one column mean two things: a column holding both $5.00 and
€5.00 is an error, not a sum. A unit declared in a bracket — Weight [kg] on
a header, fx_eur [PLN/EUR] on a binding — goes further: it propagates through
every formula, so adding kilograms to metres, or multiplying by an exchange rate
instead of dividing, fails check. Nothing is ever converted by a factor, and
$ is never read as USD.
A name bound twice in one scope is an error rather than a silent overwrite.
There are no boolean literals. Comparisons produce booleans and IF() consumes
them, but a boolean is never written into a cell — a materialised value is a
number, a date, or a string, so the word true in a column stays the string it
looks like.
There is no plugin architecture, and there will not be one. A document's
numbers depend on its own text and the version of VisiMark reading it, and on
nothing else — no extension modules, no config file, no environment, no
network, no clock. A registry of host-supplied functions would produce
documents whose arithmetic cannot be checked from the document, which is the
one thing the format exists to prevent. When the built-in vocabulary is too
small the answer is a new primitive in the engine, readable by everyone and
runnable by everyone; when a value genuinely comes from outside, it belongs in
an input column where a human wrote it down. Requests to grow that vocabulary —
and proposals for any other language or tooling change — go through
docs/vocabulary-catalogue.md, which records
every one and the decision on it; the review process is
docs/issue-runbook.md.
This makes the format smaller, not merely stricter: there is no locale, no
configuration, and no rule for what a bare / means.
Status
All seven commands are implemented, in TypeScript. Install the visimark
command with npm i -g visimark or bun add -g visimark; it runs under
whichever of Node or Bun is on your PATH. To run it without installing, use
npx visimark or bunx visimark. (On Windows the npx / npm i -g shims
need sh on PATH, which Git Bash or WSL provide.) The three worked examples
are the acceptance suite: check on the drift invoice reproduces the
transcript above byte-for-byte, fmt leaves the clean invoice untouched, and
infer on docs/example-quote-plain.md, a
quote with no formulas in it at all, reproduces the transcript in that
document's own appendix. The design, with the deferred work and the known
tensions, is docs/visimark-design.md.
docs/distribution.md is the record of every
registry and directory each artifact is listed in. A vX.Y.Z tag publishes
the npm packages, the MCP registry entry and the VS Code extension;
docs/releasing.md is the checklist, and
CONTRIBUTING.md says how to build and install the editor
plugins from a clone.
For agents
skills/visimark/SKILL.md is an agent skill for
authoring and verifying these documents. Copy it to ~/.claude/skills/visimark/
to install it. Its central warning is one worth stating here too: a green check
is evidence of agreement, not of derivation. Change an input and confirm the
checker starts complaining before believing a document is wired up. The
COVERAGE finding described above exists so that an agent cannot report a
green build on a document with no build in it, but the habit is still the
better safeguard.
There is also an MCP server, visimark-mcp, for an agent
working in a repository it has never seen: npx visimark-mcp or
bunx visimark-mcp, or claude mcp add visimark -- npx -y visimark-mcp. It
serves the skill above as a resource, so the discipline arrives with the
verifier rather than separately. It is read-only unless started with
--allow-write and given a host-declared root.
Editor support is specified in
docs/visimark-editor-plugins-design.md:
one language server — continuous check as diagnostics, fmt behind
the editor's own format-on-save, quick fixes, and inlay hints that show the
computed value without touching the bytes — with VS Code as the first client.
bun install builds the engine and links the visimark command into
node_modules/.bin, so bunx visimark works in a fresh clone. To run the CLI
straight from source without a build, use bun packages/visimark/src/cli/main.ts check FILE.
The project began as a CSV-based idea and moved to Markdown so that several small sheets can live inside one master document, and so that the file renders as a document rather than as data. The name is a nod to VisiCalc — the first spreadsheet software, originally developed for the Apple II by VisiCorp and later ported to the IBM PC.
Out of scope
VisiMark is deliberately not a spreadsheet replacement. No grid, no presentation layer, no cell styling, no locale, no Excel file compatibility, and no attempt at Excel's function library. Use other tools for neat presentation — and a spreadsheet when what you want is a spreadsheet.
Use VisiMark when what you want is a document: plain text, readable without the tool, reviewable in an ordinary pull request, writable by a human or an agent — with numbers that can be checked on every commit.
來源:README.md,提交 0283d16
工具
0版本歷史
5- v0.4.1最新Oct 17, 2026
- v0.4.0Oct 15, 2026
- v0.2.0Oct 4, 2026
- v0.1.11Oct 1, 2026
- v0.1.10Sep 28, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分