protogrid

Search / io.github.geml-spec/geml

GEML — a plain-text document format built to be edited in place, one section at a time

R0· no sign-in

One section in, one section out — on Markdown/GEML files, bad writes refused.

v1.12.6 · active · repository · website · descriptor JSON · versions

An agent can connect right now, no human step.Remote endpoint, no authentication, reachable on the last probe.
Quality94strong
Trust97of 100
Uptime, 30 days100%
Latency p50167 ms

Connect

8 clients · secrets stay placeholders
{
  "mcpServers": {
    "geml": {
      "type": "http",
      "url": "https://geml-mcp.supermarket.workers.dev/mcp"
    }
  }
}
claude mcp add --transport http geml https://geml-mcp.supermarket.workers.dev/mcp
[mcp_servers.geml]
url = "https://geml-mcp.supermarket.workers.dev/mcp"
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "geml": {
      "type": "remote",
      "url": "https://geml-mcp.supermarket.workers.dev/mcp",
      "enabled": true
    }
  }
}
{
  "mcpServers": {
    "geml": {
      "type": "http",
      "url": "https://geml-mcp.supermarket.workers.dev/mcp"
    }
  },
  "deeplink": "cursor://anysphere.cursor-deeplink/mcp/install?name=geml&config=eyJ0eXBlIjoiaHR0cCIsInVybCI6Imh0dHBzOi8vZ2VtbC1tY3Auc3VwZXJtYXJrZXQud29ya2Vycy5kZXYvbWNwIn0%3D"
}
{
  "servers": {
    "geml": {
      "type": "http",
      "url": "https://geml-mcp.supermarket.workers.dev/mcp"
    }
  }
}
{
  "mcpServers": {
    "geml": {
      "httpUrl": "https://geml-mcp.supermarket.workers.dev/mcp"
    }
  }
}
extensions:
  "geml":
    enabled: true
    name: "geml"
    type: streamable_http
    uri: "https://geml-mcp.supermarket.workers.dev/mcp"
    timeout: 300

Quality 94 / 100strong

protocol100 · weight 25
  • pass
    protocol.modernsupports 2026-07-28 (server/discover)
  • pass
    protocol.statelessanswers without a session
  • pass
    protocol.transportstreamable HTTP
  • pass
    protocol.list_ttltool list is cacheable (ttlMs 3600000)
authorizationn/a · weight 15
  • n/a
    auth.prm, auth.as_metadata, auth.cimdno remote uses OAuth
  • n/a
    auth.secret_in_urlno templated URL
tool hygiene86 · weight 30
  • pass
    tools.descriptionsevery tool has a description
  • warn
    tools.description_length4 tools have descriptions over 1,024 characters, which crowds the context
  • pass
    tools.schemasevery tool has an object input schema
  • pass
    tools.annotations9 of 9 tools declare readOnlyHint or destructiveHint
  • warn
    tools.directory_hints4 of 9 tools declare all four hints; missing: geml_list (destructiveHint, idempotentHint); geml_find (destructiveHint, idempotentHint); geml_get (destructiveHint, idempotentHint); …
  • pass
    tools.token_costabout 4,355 tokens to load every tool
  • pass
    tools.api_dumptools are not a one-to-one API dump
stability100 · weight 15
  • pass
    stability.changesno tool changes in 30 days
  • pass
    stability.rug_pullno tool changed its meaning under the same name
dependenciesn/a · weight 15
  • n/a
    deps.known_vulns, deps.mcp_sdk_version, deps.resolvabledeps.dev does not know @geml/[email protected]

9 tools, about 4,355 tokens to load them all · tool set 88e7d910a674 · checked 2026-10-19 16:53 UTC

Tool changes

No tool definition changes recorded. A server's first observation is its baseline; later probes record what changes.

Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed. How it is computed.

Trust 97 / 100

provenance90
liveness100
freshness100
hygiene100

+repository +namespace-matches-repo +website +reachable +uptime-100% +updated-3d-ago

Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed. How it is computed.

Dependencies

@geml/[email protected] npmthis version is not known to the dependency resolver

Dependency graphs from deps.dev; advisories from OSV.dev, including the GitHub Advisory Database and the PyPI Advisory Database; all CC BY 4.0. The graph is what a clean install of this version resolves today; nothing was installed or run. How it is checked.

Endpoints

remoteauthreachableuptime 30dp50protocollast ok
https://geml-mcp.supermarket.workers.dev/mcp streamable-httpnoneyes100%167 ms2026-07-282026-10-19
packageregistryversionruntimesecrets
@geml/gemlnpm1.12.6–

Tools (9)

geml_addInsert 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`.
geml_checkread-onlyValidate 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`.
geml_deletedestructiveRemove 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`.
geml_findread-onlySearch 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`.
geml_getread-onlyRead 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`.
geml_listread-onlyList 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`.
geml_renameRename 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`.
geml_setdestructiveReplace 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`.
geml_toread-onlyConvert 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`.

Schemas: list_tools.

Similar MCP servers

Official server.json
{
  "name": "io.github.geml-spec/geml",
  "icons": [
    {
      "src": "https://raw.githubusercontent.com/geml-spec/geml/main/docs/assets/logo/avatar-512.png",
      "sizes": [
        "512x512"
      ],
      "mimeType": "image/png"
    }
  ],
  "title": "GEML — a plain-text document format built to be edited in place, one section at a time",
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
  "remotes": [
    {
      "url": "https://geml-mcp.supermarket.workers.dev/mcp",
      "type": "streamable-http"
    }
  ],
  "version": "1.12.6",
  "packages": [
    {
      "version": "1.12.6",
      "transport": {
        "type": "stdio"
      },
      "identifier": "@geml/geml",
      "registryType": "npm",
      "registryBaseUrl": "https://registry.npmjs.org",
      "packageArguments": [
        {
          "type": "positional",
          "value": "mcp"
        },
        {
          "name": "--root",
          "type": "named",
          "valueHint": "docs_directory",
          "isRequired": true,
          "description": "The one directory the server may read and write. Paths outside it are refused, including via ../, absolute paths, and symlinks. Use an absolute path: a relative one resolves against whatever working directory the client happens to start the server in."
        },
        {
          "name": "--graph",
          "type": "named",
          "valueHint": "code_graph_directory",
          "description": "Optional code-graph directory inside --root, adding four read-only call-graph tools. Defaults to <root>/.geml/codemap when that holds an index.geml; with no graph those tools are not served."
        }
      ]
    }
  ],
  "repository": {
    "url": "https://github.com/geml-spec/geml",
    "source": "github"
  },
  "websiteUrl": "https://geml-spec.github.io/",
  "description": "One section in, one section out — on Markdown/GEML files, bad writes refused."
}