gemlBLOCK
One format, two readers. People and AI agents now co-write the same document. Legible for people; addressable, verifiable, and versioned for machines. GEML is plain text — organized by one typed block for everything, remembered by a .gemlhistory sidecar.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
[](https://mcptoplist.com/server/io.github.geml-spec%2Fgeml) [](https://glama.ai/mcp/servers/geml-spec/geml) [](https://github.com/hashgraph-online/awesome-ai-plugins#development--workflow) [](https://github.com/mundimark/awesome-markdown#beyond-markdown---lets-fix-markdown-quirks--oddities-and-lets-fill-in--add-the-missing-parts-tables-footnotes-generic-blocks-etc)
[](https://www.npmjs.com/package/@geml/geml) [](https://modelcontextprotocol.io) [](https://github.com/geml-spec/geml/actions/workflows/ci.yml) [](https://github.com/geml-spec/geml/actions/workflows/geml-check.yml) [](spec/GEML-spec.md) [](LICENSE) [](spec/LICENSE-spec.md)
English | 中文
GEML is a lightweight markup language with uniform, addressable blocks and standard verbs. Easy for humans to read, safe for agents to mutate. In agent-driven development and knowledge work, plain text and Markdown have no d
3dc7a8eb24ffOBSERVED · 2026-10-08Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add geml -- npx -y @geml/[email protected] mcp
Exposed tools (12)
9 read · 2 write · 1 destructive. Blast radius: 1 tool can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
geml_add | write | Insert new content — one or more blocks, or prose — at the end of the document ( |
geml_check | read | Validate a GEML document without changing it: returns every diagnostic with a stable |
geml_codemap_callchain | read | Walk the call graph SEVERAL hops from one symbol and get the whole chain back as an indented tree — |
geml_codemap_list | read | Browse the graph by MODULE. Called with no argument it lists every module with its document and symbol count — the map to open first on an unfamiliar repo, before you know any name to search for. Called with a |
geml_codemap_node | read | Open ONE node of the graph verbatim: a symbol |
geml_codemap_search | read | Find symbols in the code graph BY NAME — case-insensitive substring by default, or the whole name with |
geml_delete | destructive | Remove one or more blocks, each named by an id or any address geml_list prints; a filter ( |
geml_get | read | Read ONE block from a GEML document instead of the whole file: only that block comes back, typically a few percent of the document. Pass the |
geml_list | read | List every addressable block in a GEML document — its address, kind and heading text — in one call, with no paging. Call this FIRST: what it returns is what every other tool here addresses, and it is cheaper and more reliable than reading the file to see what is in it. Rows marked |
geml_rename | write | Rename a block id AND every reference to it in the same document, in one id-boundary-safe write. Use this rather than geml_set or a text search-and-replace, which would also hit ids that merely share a prefix. A Markdown heading |
geml_revert | read | Undo ONE block, leaving every other block byte-for-byte unchanged — recover a single block after a bad edit without losing the good edits around it. |
geml_to | read | Convert a WHOLE document and get the result back as text — the read half of the CLI |
Trust audit
BLOCKgrade D · trust 67/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | WARN |
| L2 | Instruction surface (what it tells the agent) | FAIL |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (5 observation(s))
- Network
- declared (9 observation(s))
- Shell
- declared (5 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- none-found
Findings (25)
assert parse(base) == parse("" + base) == parse(base.replace("\n", "\r\n")) == parse(base.replace("\n", "\r"))assert parse(base) == parse("" + base) == parse(base.replace("\n", "\r\n")) == parse(base.replace("\n", "\r"))const pre = await fetch(`http://127.0.0.1:${port}/`, { method: "HEAD" });const r = await fetch(`http://127.0.0.1:${port}/`, { method: "HEAD" });urlPath = decodeURIComponent(new URL(req.url, `http://127.0.0.1:${port}`).pathname);for (const block of text.replace(/^/, "").split(/\r?\n\s*\r?\n/)) {geml_delete
index.scip
.codexignore
.vscodeignore
assert_eq!(h.read("a/d.geml", "../../x.geml"), None);import { runConformance, manifest } from "../../geml-parser/test/conformance/_runner.mjs";import { manifest, runEdits } from "../../geml-parser/test/conformance/_edits.mjs";const spec = new URL("../../spec/", import.meta.url);...scipDoc("../../../src/helper.ts", ["index.geml#a": { n: "a", src: "https://evil.example/beacon#L1-L2" },const style = parseGraphStyle('=== style-rule {match="geml-code-graph" palette="#fff url(https://beacon.example/x) red rgb(1,2,3) #12345678 expression(x)"}\n===\n');const none = parseGraphStyle('=== style-rule {match="geml-code-graph" palette="url(https://beacon.example/x)"}\n===\n');"https://evil.example/beacon.mp4", "https:/evil.example/beacon.mp4", "//evil.example/x.mp4",
for (const [src, kindWord] of [["//evil/beacon", "image"], ["https://evil.example/x.png", "image"], ["https://evil.example/clip.mp4", "video"]]) {url: `http://127.0.0.1:${server.address().port}`,浏览器打开 `http://127.0.0.1:8765/scenes/stage.html?scene=s07&preview=1&d=14`,底部可拖。
"ϳavascript:alert(1)", // GREEK LETTER YOT homoglyph for `j`
"јavascript:alert(1)", // CYRILLIC SMALL LETTER JE
const normalized = src.replace(/^/, "").replace(/\r\n?/g, "\n").replace(/\u0000/g, "�");
Gates applied: no_behavioural_pass.
3dc7a8eb24fffull audit observations/trust-audit/mcp-server/geml-spec__geml.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-08 | 3dc7a8eb24ff | BLOCK | D | 67 | first audit |
Questions
What is the geml MCP server?
One format, two readers. People and AI agents now co-write the same document. Legible for people; addressable, verifiable, and versioned for machines. GEML is plain text — organized by one typed block for everything, remembered by a .gemlhistory sidecar.
What tools does geml expose?
12 in total: 9 read-only, 2 that write, and 1 that can delete or overwrite (geml_delete). Every one is listed on this page with its risk.
Is geml safe to connect to an agent?
No — not without reading the findings first. The audit graded it D (67/100) and found 2 critical or high issues in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 1 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does geml need?
It reads LOGSEQ_API_SERVER_TOKEN from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does geml run?
It speaks stdio, so it runs as a local process your client starts. It is published on npm as geml at 1.1.6.
How current is this page?
The grade is for one exact copy of the source (3dc7a8eb24ff), read on 2026-10-08. The repository is watched and re-audited when it changes.