ids-le-mcp

An MCP server that finds every identifier
in a document — UUID at every version, ULID, NanoID, MongoDB ObjectId and
Snowflake — with its line, column and key path, whether it is valid, and the
time it was minted where it carries one: the extraction engine behind the
IDs-LE editor extension, exposed as a tool
an agent can call.
A run it cannot name honestly comes back as a row with the reason, never
dropped. Thirty-two hex digits are an unhyphenated UUID and an MD5 digest in
equal measure, so that run is returned with valid: false and
ambiguous_kind, not guessed at. An ObjectId and a Snowflake have nothing in
them to validate, so they are named only under a key that says the field holds
an id.
No dependencies, no network calls, no filesystem access. Content goes in,
structured results come out.
Use it
Point any MCP host at npx ids-le-mcp.
Claude Code
claude mcp add ids-le -- npx -y ids-le-mcp
Anything with a JSON config — Cursor, Windsurf, Claude Desktop:
{
"mcpServers": {
"ids-le": {
"command": "npx",
"args": ["-y", "ids-le-mcp"]
}
}
}
VS Code needs nothing here. Install the extension instead — it
carries this server and registers it for you:
VS Code Marketplace
· Open VSX
No Node? The same extract_ids tool ships in a static Rust binary:
cargo install ids-le, then ids-le mcp
(crates.io). The two servers answer
identically — one corpus runs against both, and a differential test feeds both
thousands of generated documents in every format and compares every answer.
The binary additionally offers ids_le_scan, which walks a tree; this server
reads no files.
Prefer a global install to npx on every launch:
npm install -g ids-le-mcp
No environment variables, no API key, no configuration of its own. To check it
before wiring it into anything:
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | npx -y ids-le-mcp
If that prints the tool name, the server works.
The tool
content | string | required. The document text to scan. |
format | string | json, yaml, csv, tsv, toml, ini, env or text. Optional — it decides only the key paths, never which runs are found. |
filename | string | Used to infer the format when format is absent, e.g. config.toml. |
kind | string | Return only uuid, ulid, nanoid, objectid or snowflake. A run that could not be assigned a kind is then not returned; omit it for the complete answer. |
maxResults | number | Default 500, ceiling 5000. |
Every row carries its raw text, a 1-based line and UTF-16 column, the key path
where the format has one, and valid. A named row adds what was decoded; a
refused row adds refused and a detail sentence:
{
"ok": true,
"data": {
"ids": [
{
"kind": "uuid",
"value": "019ff344-cc00-7abc-8def-0123456789ab",
"line": 3,
"column": 19,
"key": "service.requestId",
"valid": true,
"version": 7,
"variant": "rfc4122",
"timestamp": "2026-08-12T00:00:00.000Z"
},
{
"kind": null,
"value": "5d41402abc4b2a76b9719d911017c592",
"line": 5,
"column": 14,
"key": "digest",
"valid": false,
"refused": "ambiguous_kind",
"detail": "32 hex digits are an unhyphenated UUID and an MD5 digest in equal measure; nothing in this document chooses between them"
}
],
"fileType": "json",
"named": 1,
"refused": 1
},
"diagnostics": [
{
"severity": "warning",
"code": "refused",
"message": "1 run(s) could not be named; each is returned with `valid: false` and a reason"
}
],
"meta": {
"tool": "extract_ids",
"count": 2,
"truncated": false
}
}
ok means the scan ran, not that every run was named.
Also in the MCP registry
io.github.nolindnaidoo/ids-le —
registry.modelcontextprotocol.io
Twelve more like it
One tool each, same shape: content in, structured data out, no network and no
filesystem. Every one is on npm as <name>-mcp and in the MCP registry as
io.github.nolindnaidoo/<name>.
Every tool in the family, one page: letools.dev
Built by
Nolin Naidoo — Chief Engineer, AI/ML & Platform
Architecture. nolindnaidoo.com ·
GitHub ·
LinkedIn
Also from the same workshop
Twelve Rust tools built the same way: small, single-purpose, and driven by a
machine rather than a person. pixelcoords and pixelactions make up one loop —
pixelcoords answers where, pixelactions acts there. The ten LE crates are
the terminal half of the extensions they sit in: the same detection, held to
the extension's own corpus, and an exit code instead of a results editor.
Licence
MIT © Nolin Naidoo