digit-tools
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@digit-toolshash the text "hello world" with SHA-256"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@digitable-lol/tools-core
Headless TypeScript port of the it-tools utility collection: pure functions, a machine-readable catalog, and an MCP stdio server that exposes all of it through three tools instead of ninety-four.
No Vue. No DOM. No browser APIs. Runs under Node, Bun, and as a single compiled binary.
95 tools ported from 75 of the 86 upstream utilities
14 categories, 114 worked examples (all executed by the test suite)
220 tests passing,
tsc --noEmitclean
Origin and licence. This is a derivative work of it-tools by Corentin Thomasset, which is published under the GNU General Public License version 3. Because this package copies and adapts that source, it inherits the same licence and is redistributed under GPL-3.0-only — see LICENSE and NOTICE. Not affiliated with or endorsed by the upstream author.
Why three MCP tools
Registering 95 MCP tools would push every input schema into the model's context on every turn. This package routes in two cheap steps instead:
MCP tool | Purpose | Payload |
| Index of the 14 categories, one line each | ~536 tokens |
| Full schemas + examples for one category | 1-17 tools |
| Run a tool by | — |
Results are returned both as structuredContent and as a pretty-printed JSON text block, so
clients that read either channel work unchanged.
The design target is a 0.6B router model, which is why descriptions are short and
single-purpose, schemas are flat (never deeper than two levels of properties), and oneOf /
anyOf never appear in an input schema. A test enforces all three properties.
Related MCP server: aleostudio MCP Server
Quick start
npm install
npm test # 220 tests
npm run typecheck
npm run build:binary # -> dist/digit-tools-mcp
npm run smoke:binary # replays all 114 catalog examples through the binaryRun the server straight from source:
npm run mcp # node --experimental-strip-types src/mcp.tsUse it as a library:
import { executeTool, getCategoryIndex, getToolsInCategory } from '@digitable-lol/tools-core';
getCategoryIndex(); // step 1: which category?
getToolsInCategory('crypto'); // step 2: which tool, and what arguments?
await executeTool('hash_text', { text: 'hello', algorithm: 'SHA256' });
// { ok: true, result: { algorithm: 'SHA256', encoding: 'Hex', hash: '2cf24dba…' } }
await executeTool('hash_text', { algorithm: 'SHA256' });
// { ok: false, code: 'invalid_args', error: "must have required property 'text'" }executeTool never throws. Every outcome is {ok: true, result} or
{ok: false, error, code}, where code is one of unknown_tool, invalid_args,
execution_error, timeout. Arguments are validated against the tool's input_schema with
ajv (coerceTypes and useDefaults on, since small models routinely emit "2024" where a
number is wanted).
Connecting an MCP client
Compiled binary — no runtime required on the host:
{
"mcpServers": {
"digit-tools": {
"command": "/absolute/path/to/tools-core/dist/digit-tools-mcp"
}
}
}From source, using Node's built-in TypeScript stripping:
{
"mcpServers": {
"digit-tools": {
"command": "node",
"args": [
"--experimental-strip-types",
"/absolute/path/to/tools-core/src/mcp.ts"
]
}
}
}Binary size and startup
Metric | Value |
Binary size | 111,683,904 bytes (107 MiB) |
Startup (spawn → | 542 ms |
Startup, min / p90 | 390 ms / 641 ms |
Same, running from source under Node | ~3,900 ms median |
Measured with npm run bench:startup (12 runs, first two discarded) on Linux 6.8, Node
v24.18, Bun 1.3.12, at a 1-minute load average of ~10 on 8 cores.
Caveat on these numbers: this machine carries other workloads. A re-run at load average ~48 gave min 3,711 ms / median 7,794 ms for the same binary — roughly 14x worse purely from CPU contention. Re-measure on an idle host before treating 542 ms as the figure; the shape of the result (binary ≈ 7x faster than Node-from-source) held at both load levels.
Startup was 1,214 ms before the heaviest payloads — mathjs, the OUI table, markdown-it,
libphonenumber, sql-formatter, node-forge, qrcode, figlet, the emoji dataset — were moved behind dynamic
import() calls inside the tools that need them. The first call to those tools pays a
one-time load cost; everything else starts fast.
The catalog
src/catalog.ts is the key artifact. Each entry:
{
id: 'hash_text',
name_ru: 'Хеш текста',
name_en: 'Hash text',
category: 'crypto',
description_ru: 'Считает криптографический хеш строки выбранным алгоритмом.',
deterministic: true,
input_schema: { /* flat JSON Schema */ },
output_schema: { /* flat JSON Schema */ },
examples: [{ input: {...}, output: {...} }],
run: hashText,
}API:
getCategoryIndex()— the 14 categories with one-line descriptions and tool counts (1,875 chars ≈ 536 tokens)getToolsInCategory(cat)— full schemas for one category, implementations strippedgetToolSchema(id),getFullCatalog(),getToolIds()npm run catalog:dumpwrites the whole thing as JSON (~184 KB)
Entries live in src/catalog/*.ts grouped by family; src/catalog.ts aggregates them and
exposes the routing API.
Categories
id | Russian name | Tools |
| Криптография | 9 |
| Генераторы | 9 |
| Аутентификация | 7 |
| Кодирование | 12 |
| Конвертеры форматов | 17 |
| Работа с текстом | 8 |
| Веб | 10 |
| Сети | 5 |
| Разработка | 5 |
| Разбор данных | 4 |
| Дата и время | 1 |
| Математика | 3 |
| Измерения | 2 |
| Изображения | 3 |
Ten come straight from the upstream registry; generators, auth, encoding and
datetime were split out of it-tools' oversized Converter and Web buckets so no
category is large enough to blow the router's context.
Examples are the eval set
Every tool has at least one example, and test/catalog.test.ts executes all 114 through
executeTool. For the 80 deterministic tools the output is compared with a deep equality
check. For the 15 non-deterministic ones the example carries match: 'shape' and only the
key set and value kinds are verified — the values genuinely change between runs.
npm run smoke:binary replays the same 114 examples through the compiled binary over
real stdio. This is what caught the figlet font-loading bug described below; a passing unit
suite would not have.
What was ported
Group A — pure deterministic functions (62 upstream utilities). Hashes, HMAC, codecs,
format converters, parsers, formatters, calculators. Logic carried over from the upstream
.service.ts / .models.ts where one existed, or lifted out of the <script setup> block
where it did not. Cryptographic code (bcrypt, BIP39, JWT, crypto-js ciphers, OTP) was moved
verbatim and still leans on the same npm packages at the same major versions as it-tools.
Group C — random or clock-dependent (13 upstream utilities, 15 tool ids). Ported and
flagged deterministic: false:
bcrypt_hash, encrypt_text, rsa_keypair_generate, token_generate, uuid_generate,
ulid_generate, bip39_generate, lorem_ipsum_generate, random_port_generate,
mac_address_generate, otp_generate_totp, otp_verify_totp, otp_secret_generate,
ipv6_ula_generate, eta_calculate
Where it was cheap, randomness was made reproducible. src/utils.ts provides a seeded
mulberry32 PRNG, and an optional integer seed makes token_generate, uuid_generate,
ulid_generate, lorem_ipsum_generate, random_port_generate, mac_address_generate and
otp_secret_generate repeatable. Clock-driven tools take an explicit time instead:
otp_generate_totp/otp_verify_totp accept now, ipv6_ula_generate accepts timestamp,
eta_calculate accepts startedAtMs.
Not seedable, deliberately: bcrypt_hash and encrypt_text draw their salt from the
underlying library, and rsa_keypair_generate from node-forge. Forcing a seed there would
mean reimplementing cryptographic primitives, which is exactly the kind of change that
introduces silent security bugs.
Three tools are deterministic despite living next to random ones, and are marked as such:
bcrypt_compare, decrypt_text, bip39_from_entropy / bip39_to_entropy.
What was NOT ported (Group B — 11 utilities)
Utility | Reason |
| Needs a browser |
|
|
| A live wall-clock stopwatch; no meaning in a request/response tool |
| Reads |
| Reads live DOM keyboard events |
| Needs an uploaded PDF binary |
| TipTap editor UI; no headless logic |
| Pure Monaco diff-editor widget; the |
| Static cheatsheet, not a computation |
| Static cheatsheet, not a computation |
| Skipped: depends on |
The last three are honest omissions rather than technical impossibilities — a cheatsheet lookup tool could be built, it just would not be a port of anything.
Deliberate deviations from upstream
Ten behaviour changes, made on purpose, each because the browser original was wrong for a headless caller. Everything not on this list is a straight port — see NOTICE for the structural changes (Vue removed, catalog / execution / MCP layers added) that sit on top of these.
xml_formatemits LF, not CRLF.xml-formatterdefaults to\r\n.temperature_convertrounds to 10 decimals. The scale factors are irrational in binary, so 100 °C → °F produced211.99999999999994. Rounding removes the noise without touching any precision a temperature reading carries.benchmark_statstakes one series, not many. Upstream compared several suites at once, which forces an array-of-objects-holding-arrays input — three levels of schema nesting. One series per call keeps the schema flat.chmod_calculatetakes a flat string. Upstream drove nine checkboxes; here"755"or"rwxr-xr-x"works, in either direction.json_diffreturns a flat change list. Upstream produced a nested tree for its tree widget; a list of{path, status, oldValue, value}is far easier for a small model.Errors are thrown, not swallowed. Upstream wrapped most tools in
withDefaultOnError(..., '')and rendered an empty string. Here the throw propagates toexecuteTool, which turns it into{ok: false, code: 'execution_error'}. Affectsxml_format,token_generate(empty alphabet) and the format converters.eta_calculateformats durations without date-fns locales, so output is stable.jwt_parserendersexp/iat/nbfas ISO 8601, not a machine-local locale string.QR codes render as SVG, not a canvas — same
qrcodepackage, headless renderer.emoji-pickerbecameemoji_search. Upstream is a scrollable grid with a fuse.js search box; headless, only the search means anything. Fuzzy matching is replaced by exact / prefix / substring tiers over name, slug, keywords, group, code points and the emoji itself, so a query always returns the same list in the same order. With noquerythe tool returns the firstlimitemoji of the dataset (optionally of onegroup).
Everything else is a straight port. Where upstream had a .service.ts, the algorithm is
unchanged.
Tests
test/catalog.test.ts 124 tests catalog integrity + all 114 examples via executeTool
test/ported.test.ts 60 tests upstream unit tests, imports adapted
test/tools.test.ts 18 tests mac_address_lookup and emoji_search, incl. embedded data
test/execute.test.ts 11 tests validation, defaults, coercion, timeouts, error mapping
test/mcp.test.ts 7 tests the three MCP tools over an in-memory transport
──────────────────────────────────
220 passingtest/ported.test.ts carries over every upstream *.service.test.ts / *.models.test.ts
that survived the port: chmod, hash-text, integer-base-converter, ipv4-address-converter,
ipv4-range-expander, json-diff, json-to-csv, json-viewer, list-converter,
mac-address-generator, numeronym, OTP, password-strength, regex-tester, roman-numerals,
safelink, string-obfuscator, text-statistics, text-to-binary, text-to-unicode,
token-generator, xml-formatter, color-converter, date-time-converter. The two assertions
that changed are commented in place, both consequences of deviation #6 above.
Upstream tests that were dropped: chronometer.service.test.ts (tool not ported).
Known limitations
The execution timeout is not preemptive. JavaScript cannot interrupt synchronous CPU-bound work.
withTimeoutfires at the nextawaitboundary, which in practice covers the lazily-loaded tools; a runaway regex insideregex_testwould still block the process. Fixing this properly needs a worker thread. Documented onwithTimeoutinsrc/execute.tsand pinned by a test.ascii_art_generateships 15 fonts, not figlet's 328. figlet reads.flffiles from disk at runtime, whichbun build --compiledoes not bundle — the binary crashed withENOENT: /$bunfs/fonts/Standard.flf. A curated set is embedded as data byscripts/generate-figlet-fonts.mjs(~300 KB) and loaded lazily. Add names to that script and tosrc/tools/figlet-font-names.tsto include more.The OUI vendor table is embedded, not read from
oui-data. Same trap as the fonts: the package is a bareindex.jsonthatrequireresolved from node_modules, so the compiled binary failed withCannot find package 'oui-data' from '/$bunfs/root/…'whenever it ran outside this checkout. All 39,227 entries are inlined byscripts/generate-oui-data.mjsintosrc/tools/oui-data.ts(~4 MB) and loaded through a lazyimport(). Runnpm run generate:ouiafter bumping the dev dependency to refresh it.emoji_searchships a snapshot of the CLDR emoji data. 1,870 emoji with names, slugs, groups and keywords are inlined insrc/tools/emoji-data.ts(~260 KB), taken fromunicode-emoji-json0.4.0 andemojilib3.0.10 — the datasets upstream loads in the browser. Refreshing them means regenerating that file.json_to_toml/yaml_to_tomlwrite8_080, not8080.@iarna/tomluses underscore digit separators for larger integers. This is the library's canonical output, left as-is.iban_validatereports a generic checksum error. ibantools v4 exposes its detailed error-code list through an overload thatextractIBANdoes not surface, so theerrorsarray is coarser than upstream's.The binary is 107 MiB. Bun's compiled output embeds the whole runtime. The embedded OUI table (~4 MB), the figlet fonts (~300 KB) and the emoji dataset (~260 KB) add to it, but the runtime dominates.
iarna-toml-esm(used upstream) is unloadable under plain Node ESM, so this package uses@iarna/tomlv3 — the same code, same major version, packaged for CommonJS.
Layout
src/
catalog.ts aggregation + getCategoryIndex / getToolsInCategory
catalog/*.ts catalog entries grouped by family
execute.ts executeTool: ajv validation, timeout, structured results
mcp.ts binary entry point
mcp-server.ts the three MCP tools
tools/*.ts the ported implementations
utils.ts base64, seeded PRNG, shared helpers
interop.ts dual-build (CJS/ESM) default-export unwrapping
node-require-shim.ts global `require` for js-sha256's eval probe
scripts/ font/OUI generation, catalog dump, binary smoke test, benchmark
test/ the four suites abovesrc/interop.ts and src/node-require-shim.ts exist because several dependencies ship both
a CommonJS and an ESM build. Node resolves one, Bun's bundler resolves the other, and a
plain default import works in exactly one of them. The namespace-import-plus-unwrap pattern
is what lets identical source run under node --experimental-strip-types, vitest, and
bun build --compile.
License
GPL-3.0-only, inherited — not chosen — from it-tools by Corentin Thomasset. This package copies and adapts it-tools source code, which makes it a derivative work, so the GNU General Public License version 3 covers it as a whole. Upstream states "GNU GPLv3" and ships the plain GPL-3.0 text with no "or any later version" grant, so version 3 is the version that applies here too.
The full licence text is in LICENSE. Provenance, the list of changes, and the third-party data notices are in NOTICE.
Practical consequence: if you hand someone the compiled binary (dist/digit-tools-mcp),
GPL-3.0 sections 4-6 require you to give them the corresponding source under the same
licence. That obligation is why this repository is published rather than kept private — the
binary is distributable precisely because its source is here.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseBqualityFmaintenanceA comprehensive Model Context Protocol server providing access to 70+ IT tools for developers and system administrators, including encoding/decoding, text manipulation, hashing, and network utilities.Last updated3410023722TypeScriptMIT
- FlicenseAqualityDmaintenanceA lightweight MCP server providing utility tools for math, text processing, data conversion, and URL fetching. It supports both STDIO and SSE communication modes for seamless integration with Claude Desktop and remote AI agents.Last updated51
- Flicense-qualityDmaintenanceSwiss-army-knife utility MCP server for AI agents. 18 tools for JSON validation/formatting, base64 encode/decode, hash generation, UUID generation, URL parsing, regex testing, markdown↔HTML conversion, text stats, slug generation, datetime conversion, cron parsing, text diffing, CSV↔JSON conversion, and JWT decoding. Zero API Key requiredLast updated5

@mate-tools/mcp-serverofficial
Alicense-qualityCmaintenanceMCP server providing 35 utility tools for AI agents including text analysis, encoding, hashing, password generation, JSON/CSV/XML parsing, regex, color, date, finance, URL metadata, SEO tags, DNS lookup, SSL inspection, and JWT decoding. Free, zero-dependency, and works with any MCP client.Last updatedMIT
Related MCP Connectors
Remote MCP server: 10 developer utilities (base64, JWT, DNS, UUID, URL, JSON, UA, IP lookup).
500+ deterministic tools for AI agents: math, conversion, validation, hashing, encoding, date/time.
Markdown-first MCP server for Notion API with 8 composite tools and 39 actions.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/digitable-lol/tools-core'
If you have feedback or need assistance with the MCP directory API, please join our Discord server