← The evidence ledger
Evidence row 221271
Observed , by probe.mcp/1.
- Kind
- mcp.tools
- About
- endpoint 10bc8036-3398-4995-8573-0b7ea5393357
- Recorded
- Previous row
- None: the first of its kind about this subject
- Body SHA-256
- 9cb899e0429126b7326fe53eabeeef6c0134723814def6f068ad4797a980b3a1
- Leaf
- 0xfa5435b0db37bf1f195f3de120e8dbf00ccd398c7295bcc2bd8ab7d2c783e1f3
What was observed
{
"count": 9,
"tools": [
{
"description": "Insert new content — one or more blocks, or prose — at the end of the document (`position: append`) or before/after the block named by `anchor`. Use this for content that does not exist yet; to change a block that does, use geml_set. Ids inside the content are kept. In a `.md` file Markdown lands as written, and GEML content is converted to Markdown as `to: \"md\"` converts it, the result's `notes` saying so; content Markdown cannot hold, such as a view without its source, is refused. Like every write here it is validated first: a missing anchor, an id that clashes with an existing one, or content that would break the document is refused. Returns `{ok, file, diagnostics, revision}`, with `notes` when the write did something to say out loud (a block it dropped, an address it changed); a refusal is `ok: false` with a `hint`, and the file is unchanged. This server is STATELESS: the document travels in `source` and a write comes back as `document` for you to save; it holds no other documents, so a cross-document reference such as `[[other.geml#id]]` cannot be resolved here and is reported as `unresolvable-document`.",
"inputSchema": {
"properties": {
"anchor": {
"description": "The block the insertion is relative to — an id, or any address geml_list prints; it must name one block. Required for before/after",
"type": "string"
},
"content": {
"description": "The GEML fragment to insert",
"type": "string"
},
"name": {
"description": "The document's file name, e.g. notes/spec.geml or README.md — it decides whether the text is read as GEML or as Markdown (a `.md` name), and it is how the document is called in messages. Default: document.geml.",
"type": "string"
},
"position": {
"description": "Where to insert",
"enum": [
"append",
"before",
"after"
],
"type": "string"
},
"source": {
"description": "The document's full text. This server keeps no files: what you send is the document.",
"type": "string"
}
},
"required": [
"source",
"content",
"position"
],
"type": "object"
},
"name": "geml_add"
},
{
"description": "Validate a GEML document without changing it: returns every diagnostic with a stable `code`, a severity and a line, and an empty list means the document is valid. Use it to confirm a document is sound before reporting work as finished. Every write through this server runs the same check before it lands, so a refused write already carries this information. This server is STATELESS: the document travels in `source` and a write comes back as `document` for you to save; it holds no other documents, so a cross-document reference such as `[[other.geml#id]]` cannot be resolved here and is reported as `unresolvable-document`.",
"inputSchema": {
"properties": {
"name": {
"description": "The document's file name, e.g. notes/spec.geml or README.md — it decides whether the text is read as GEML or as Markdown (a `.md` name), and it is how the document is called in messages. Default: document.geml.",
"type": "string"
},
"source": {
"description": "The document's full text. This server keeps no files: what you send is the document.",
"type": "string"
}
},
"required": [
"source"
],
"type": "object"
},
"name": "geml_check"
},
{
"description": "Remove one or more blocks, each named by an id or any address geml_list prints; a filter (`=== type`, `{key=value}`) removes every block it matches. Each block takes the blank line that separated it from its neighbours, so deleting what geml_add inserted leaves the file as it was. To undo a deletion, geml_revert the removed id; to change a block rather than remove it, use geml_set. References left pointing at a removed block come back as diagnostics but do NOT block the deletion — read them, then repair the references or revert. A selector that names nothing is skipped, so repeating a call changes nothing. Returns `{ok, file, diagnostics, revision}`, with `notes` when the write did something to say out loud (a block it dropped, an address it changed); a refusal is `ok: false` with a `hint`, and the file is unchanged. This server is STATELESS: the document travels in `source` and a write comes back as `document` for you to save; it holds no other documents, so a cross-document reference such as `[[other.geml#id]]` cannot be resolved here and is reported as `unresolvable-document`.",
"inputSchema": {
"properties": {
"ids": {
"description": "The blocks to remove: ids or addresses",
"items": {
"type": "string"
},
"type": "array"
},
"name": {
"description": "The document's file name, e.g. notes/spec.geml or README.md — it decides whether the text is read as GEML or as Markdown (a `.md` name), and it is how the document is called in messages. Default: document.geml.",
"type": "string"
},
"source": {
"description": "The document's full text. This server keeps no files: what you send is the document.",
"type": "string"
}
},
"required": [
"source",
"ids"
],
"type": "object"
},
"name": "geml_delete"
},
{
"description": "Search block CONTENT in the document; each hit is one `<name>\\t<address>` row. geml_list says what a document contains, this says which block holds the words — as an address that pastes straight into geml_get or geml_set, not a line number the next edit invalidates. The address is the innermost block holding the match, and a block matching on many lines is reported once. Substring, case-insensitive unless `case` is true. No match is an empty result, not an error. This server is STATELESS: the document travels in `source` and a write comes back as `document` for you to save; it holds no other documents, so a cross-document reference such as `[[other.geml#id]]` cannot be resolved here and is reported as `unresolvable-document`.",
"inputSchema": {
"properties": {
"case": {
"description": "Match case exactly (default: case-insensitive)",
"type": "boolean"
},
"head": {
"description": "Add the matching line as a third column",
"type": "boolean"
},
"name": {
"description": "The document's file name, e.g. notes/spec.geml or README.md — it decides whether the text is read as GEML or as Markdown (a `.md` name), and it is how the document is called in messages. Default: document.geml.",
"type": "string"
},
"pattern": {
"description": "Text to look for inside block bodies",
"type": "string"
},
"source": {
"description": "The document's full text. This server keeps no files: what you send is the document.",
"type": "string"
},
"within": {
"description": "Optional: only look inside the blocks this selector names, e.g. `#install` for a section or `=== table` for every table. It takes the same selector forms as geml_get's `id`.",
"type": "string"
}
},
"required": [
"source",
"pattern"
],
"type": "object"
},
"name": "geml_find"
},
{
"description": "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 `address` geml_list prints as `id` — it also reaches blocks with no `#id`; to locate a block by its words instead, use geml_find first. An `id` that matches nothing, or a file that is not under the server root, is an error naming it. This server is STATELESS: the document travels in `source` and a write comes back as `document` for you to save; it holds no other documents, so a cross-document reference such as `[[other.geml#id]]` cannot be resolved here and is reported as `unresolvable-document`.",
"inputSchema": {
"properties": {
"id": {
"description": "What to read: a block id (with or without `#`), a `## Heading` line (its whole section), `=== type` for every block of a type, `=== code {lang=py}` or `{.warn}` for every block carrying those attributes, a `@<hex>` content address for a block with no id, or `L27`/`L27-58` for the smallest block holding those lines — the forms `geml_list` prints, plus the line numbers an editor or a diff hunk speaks",
"type": "string"
},
"name": {
"description": "The document's file name, e.g. notes/spec.geml or README.md — it decides whether the text is read as GEML or as Markdown (a `.md` name), and it is how the document is called in messages. Default: document.geml.",
"type": "string"
},
"part": {
"description": "How much of the block to return (default: whole). For a SECTION these cut it three ways: `head` is the heading line, `intro` everything under it up to its first subheading, `body` everything under it — so `body` always contains `intro`, and equals it when the section has no subheading. Reach for `intro` to read a section's opening without pulling its subsections into the conversation; a whole `#id` on a top-level heading is often the entire document. Only a heading has an intro. `body` is usually what you want together with `view`.",
"enum": [
"whole",
"head",
"intro",
"body"
],
"type": "string"
},
"source": {
"description": "The document's full text. This server keeps no files: what you send is the document.",
"type": "string"
},
"view": {
"description": "Read THROUGH an `embed` block to the entity block it stands for, following a multi-layer chain to its end. An `embed` has no content of its own, so this is the only way to see what it points at; on any other block it changes nothing. Returns {from, content}: `from` names the document the content actually came from, and its references and relative paths resolve against THAT document, not this one.",
"type": "boolean"
},
"within": {
"description": "Optional: only look inside the blocks this selector names, e.g. `#install` for a section or `=== table` for every table. It takes the same selector forms as geml_get's `id`.",
"type": "string"
}
},
"required": [
"source",
"id"
],
"type": "object"
},
"name": "geml_get"
},
{
"description": "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 `anon` have no `#id`; geml_get and geml_set take their `address` as `id`, while the other write tools need a real id, so give such a block one first. A file that is not under the server root is an error. This server is STATELESS: the document travels in `source` and a write comes back as `document` for you to save; it holds no other documents, so a cross-document reference such as `[[other.geml#id]]` cannot be resolved here and is reported as `unresolvable-document`.",
"inputSchema": {
"properties": {
"name": {
"description": "The document's file name, e.g. notes/spec.geml or README.md — it decides whether the text is read as GEML or as Markdown (a `.md` name), and it is how the document is called in messages. Default: document.geml.",
"type": "string"
},
"source": {
"description": "The document's full text. This server keeps no files: what you send is the document.",
"type": "string"
},
"within": {
"description": "Optional: only look inside the blocks this selector names, e.g. `#install` for a section or `=== table` for every table. It takes the same selector forms as geml_get's `id`.",
"type": "string"
}
},
"required": [
"source"
],
"type": "object"
},
"name": "geml_list"
},
{
"description": "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's anchor is its text, so it is renamed by changing the heading with geml_set (`part: head`), not here. An `old` id that does not exist, or a `new` one already taken, is refused. Returns `{ok, file, diagnostics, revision}`, with `notes` when the write did something to say out loud (a block it dropped, an address it changed); a refusal is `ok: false` with a `hint`, and the file is unchanged. This server is STATELESS: the document travels in `source` and a write comes back as `document` for you to save; it holds no other documents, so a cross-document reference such as `[[other.geml#id]]` cannot be resolved here and is reported as `unresolvable-document`.",
"inputSchema": {
"properties": {
"name": {
"description": "The document's file name, e.g. notes/spec.geml or README.md — it decides whether the text is read as GEML or as Markdown (a `.md` name), and it is how the document is called in messages. Default: document.geml.",
"type": "string"
},
"new": {
"description": "New id",
"type": "string"
},
"old": {
"description": "Current id",
"type": "string"
},
"source": {
"description": "The document's full text. This server keeps no files: what you send is the document.",
"type": "string"
}
},
"required": [
"source",
"old",
"new"
],
"type": "object"
},
"name": "geml_rename"
},
{
"description": "Replace ONE block and leave every other byte untouched — prefer this to rewriting a file. For content that does not exist yet use geml_add; to remove a block, geml_delete. The replacement is validated before it is written: if it would break the document, nothing is written and the diagnostics come back — fix the body rather than resending it. Removing content is not refused: if the replacement drops blocks, the write goes through and the result names each one, so check it after shortening a section; geml_revert puts one back. `part` replaces the whole block (default), its head line, a section's `intro`, or its body. In a Markdown file a heading's anchor is its text, as on GitHub: new heading text gives the heading a new address, and the document's links to the old one follow in the same write. GEML content written over a Markdown heading or prose is converted to Markdown, as in geml_add; a GEML block already in the file stays GEML. An `id` that matches no block, or several, is refused. Returns `{ok, file, diagnostics, revision}`, with `notes` when the write did something to say out loud (a block it dropped, an address it changed); a refusal is `ok: false` with a `hint`, and the file is unchanged. This server is STATELESS: the document travels in `source` and a write comes back as `document` for you to save; it holds no other documents, so a cross-document reference such as `[[other.geml#id]]` cannot be resolved here and is reported as `unresolvable-document`.",
"inputSchema": {
"properties": {
"body": {
"description": "The replacement text",
"type": "string"
},
"id": {
"description": "Which block to replace: an id (with or without `#`), a `@<hex>` content address from `geml_list` for a block with no id, or `L27`/`L27-58` for the smallest block holding those lines. Must match exactly one block",
"type": "string"
},
"name": {
"description": "The document's file name, e.g. notes/spec.geml or README.md — it decides whether the text is read as GEML or as Markdown (a `.md` name), and it is how the document is called in messages. Default: document.geml.",
"type": "string"
},
"part": {
"description": "What to replace (default: whole). `intro` replaces a section's opening — everything under the heading up to its first subheading — and leaves every subsection byte-identical, which is what makes a read-edit-write cycle on a long section safe. An empty intro (a subheading follows the heading immediately) is written into, so this also adds an opening where there was none.",
"enum": [
"whole",
"head",
"intro",
"body"
],
"type": "string"
},
"source": {
"description": "The document's full text. This server keeps no files: what you send is the document.",
"type": "string"
}
},
"required": [
"source",
"id",
"body"
],
"type": "object"
},
"name": "geml_set"
},
{
"description": "Convert a WHOLE document and get the result back as text — the read half of the CLI's `geml <file> --to <fmt>`. `to: \"geml\"` on a Markdown file is the importer, the one thing the block tools cannot do; `to: \"md\"` projects a GEML document out (lossy); `to: \"json\"` returns the full document model, for when geml_list plus geml_get is not enough. Nothing is written — pass the result to geml_add or geml_set to land it. `to: \"html\"` also works but returns a whole self-contained page, usually tens of kilobytes this server cannot save: prefer the CLI (`geml <file> --to html -o out.html`) unless you want the markup in the conversation. A document with errors returns its diagnostics instead of a conversion, and a file that is not under the server root is an error. This server is STATELESS: the document travels in `source` and a write comes back as `document` for you to save; it holds no other documents, so a cross-document reference such as `[[other.geml#id]]` cannot be resolved here and is reported as `unresolvable-document`.",
"inputSchema": {
"properties": {
"from": {
"description": "Override the input format, which is otherwise inferred from the extension (.md -> md, .json -> json, else geml).",
"enum": [
"geml",
"md",
"json"
],
"type": "string"
},
"name": {
"description": "The document's file name, e.g. notes/spec.geml or README.md — it decides whether the text is read as GEML or as Markdown (a `.md` name), and it is how the document is called in messages. Default: document.geml.",
"type": "string"
},
"source": {
"description": "The document's full text. This server keeps no files: what you send is the document.",
"type": "string"
},
"to": {
"description": "Target format. Default is the CLI's: a GEML input becomes json, a Markdown input becomes geml. `html` is a whole page — large, and not writable from here.",
"enum": [
"json",
"md",
"geml",
"html"
],
"type": "string"
}
},
"required": [
"source"
],
"type": "object"
},
"name": "geml_to"
}
]
}What the leaf hashes
{"body":"9cb899e0429126b7326fe53eabeeef6c0134723814def6f068ad4797a980b3a1","id":221271,"kind":"mcp.tools","method":"probe.mcp/1","observed_us":1793027245186141,"prev":null,"subject":"10bc8036-3398-4995-8573-0b7ea5393357","subject_kind":"endpoint"}Proof
Fold these into the leaf in order, hashing each sorted pair with keccak256, to reach the root of (296695 rows).
- 0xfa54858b69d843f0a040a0804cd39b35b8578065a4a32f057b7f73c07ad1d1a8
- 0xc019dd64333c5d68d583829aab6920ab7c8a9917d68403b4fa9978b4435057fc
- 0xe52aa2d8b14d33ec5f5327d23d5036f03e93abeddd61af149667f82d6da025f9
- 0xe2b793827b50c41a09c593ca6174ae79ebbc3684b10ebd60d383ec048008f3a0
- 0xed7ca462b672132ac9661451f55e1eb21eaad7ef72c2fcccaf6c45e588eedbc4
- 0xa253f8030d19bfa1d065d05f1e5616d776048f7393fd3569216a8f41e2152bbc
- 0xabb88ad869fc406e71f062b76807a3159a28f732b0d211fc002aa1733ded90f4
- 0xe15474ac8ff650ef9b19d2c386205f1ddffec35047bd0c6a31e29f94df28e926
- 0xe42efb9b2aa28612ae2da2fcaaad017ee4dc36b03959c21e2fcf16135af25591
- 0x594aa12c66cb1a589bf8523cd0b663bbc2d80e013a2e69ee6b047a4aa23b26a7
- 0xc1f00d9dcd67fe1d14473197e5f14f3efa26c1e1569cc2a3172842f28c850633
- 0x08d20884523152a869ac5da32efc7de7b28316f6e9c2a28242f5ea9da742852f
- 0x694eb701ea36a0e3dcde192253ab85a618738bdc1e3a6e582e6f8bf9647f7a6a
- 0x44945ea9ad8b24e723ad5a8fd6d014024a49531783f74ff9229c2ab6930e84c8
- 0x68d296b1e00b4899fb83c3fba36fffaefa311eac2903067dbebfe776a12b4a9a
- 0x5fb5dda563336cd1bc1b9f44c52b76237ae72ed2145cb9290f39f304ca7dd678
- 0x74a0a08e4e7ab9aa5bfbead33dec7e1c7e8e364cff69a63720d764bbe987aadc
- Day root
- 0xf43e8dcc3d451a4788b26be904c55e8c4c0fa75c9666796c51db38d37e2c0df8
- Chained
- 0x702d5ac508f08b0d1accf36af25822d8e5660367494edd17a642fb61e158a57a
- Published
- On Arc Testnet, block 69251483: 0x495162f8936e19f0039918feebe6c307f327cd6bf8c37219620b1970041fa9ae