toolkit-mcp-server
Toolkit MCP server provides developer utilities for hashing, ID/QR generation, encoding/decoding, IP geolocation, and optional host diagnostics.
Generate and compare cryptographic digests using SHA-256, SHA-384, SHA-512, or checksum-only SHA-1/MD5, with selectable input and digest encodings.
Mint cryptographically random UUIDv4, time-ordered UUIDv7, or ULID identifiers, up to 1,000 per call.
Encode text or URLs as QR codes in SVG, base64 PNG, or terminal half-block output, with configurable error correction, margin, and scale.
Encode or decode base64, base64url, hex, and URL percent-encoding; decode binary bytes losslessly to hex or base64.
Geolocate public IPs or dotted hostnames, singly or in batches, returning country, city, coordinates, ASN, organization, timezone, and proxy/hosting/mobile flags.
When enabled, run gated network diagnostics: ping, traceroute, TCP connectivity, and public egress IP checks.
When enabled, inspect gated system diagnostics: OS, CPU, memory, load average, and network interfaces.
Click on "Deploy 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., "@toolkit-mcp-server generate a QR code for https://example.com"
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.
Public Hosted Server: https://toolkit.caseyjhand.com/mcp
Overview
Everyday developer utilities: generate IDs, QR codes, and hashes, encode and decode values, and geolocate a public IP or hostname. Only the geolocation lookup and the gated network diagnostics (off by default) make network calls; everything else runs locally.
Tools
Tool | Description |
| Generate a digest or HMAC (sha256/sha384/sha512/sha1/md5) as hex, base64, base64url, or SRI, or constant-time-compare a value against an expected digest or signature |
| Mint cryptographically random UUIDv4, UUIDv7, or ULID identifiers, up to 1000 per call |
| Encode text or a URL as a QR code in SVG, base64 PNG, or terminal half-blocks |
| Encode or decode base64, base64url, hex, or URL percent-encoding |
| Resolve a public IP or hostname to country, city, coordinates, ASN, and timezone |
| Gated, off by default. Ping, traceroute, TCP connectivity, or IPv4 egress-IP check from the server host |
| Gated, off by default. OS, CPU, memory, load average, or network interfaces of the server host |
Skill
Skill | Description |
Gates the tool descriptions don't carry: reading a digest or signature mismatch, webhook and JWT signing inputs, moving digest bytes between hex, base64, and base64url, who runs an IP's network, and host diagnostics |
MCP clients that support the Skills extension read it as skill://toolkit-guide/SKILL.md. Plugin installs load it from skills/, which also ships in the npm package, the Docker image, and the .mcpb bundle.
Related MCP server: IT Tools MCP Server
Capability reference
toolkit_hash_value tool
valueread perinputEncoding(utf8default,hex,base64);algorithmissha256(default),sha384, orsha512, withsha1andmd5for checksum compatibility and verifying existing HMAC-SHA1 signatures only;operationisgenerateorcompare, and when omitted it compares ifexpectedis sentA non-empty
secretmakes the digest an HMAC keyed by it, for webhook signatures (GitHub'sX-Hub-Signature-256pastes intoexpectedas-is) and HS256 JWT signatures;secretEncodingisutf8(default),hex,base64, orbase64url(a JWKk). The result then carrieshmac: true, and the secret is never echoed in the result or an error; a secret invalid for its encoding fails asinvalid_secret_encodinggeneratereturnsdigestindigestEncoding(hexdefault,base64, unpaddedbase64url, orsrifor plain SHA-2 digests, where an HMAC fails assri_with_secret) pluslengthInBytes;comparereturnsmatchesagainstexpected, pasted as published: hex, base64, or base64url, bare or prefixed (sha256:<digest>,sha256=<digest>); SRI, including a multi-entry npmintegrityvalue; or one checksum-file line assha256sum,shasum,md5, oropenssl dgstprints itA bad
expectedfails asexpected_malformed(including a whole multi-line checksum file, with a hint to pass the file's own line),expected_length_mismatch(the hint names the algorithm that length fits), orexpected_algorithm_mismatch(a tag, prefix, or SRI entry naming another algorithm)
toolkit_generate_id tool
typeisuuid_v4(default),uuid_v7, orulid;countis 1–1000 (default 1)idsalways holds exactlycountvalues;uuid_v7andulidbatches are strictly increasing even within one millisecond, with random gaps so no id is derivable from another
toolkit_generate_qr tool
dataup to 2953 UTF-8 bytes aterrorCorrectionL, less atM(default),Q, andH;formatissvg(default),png_base64, orterminal;margin0–20 modules (default 4),scale1–32 px per module (default 4)Returns
content, the symbolversion(1–40),mimeTypefor image formats, andbyteLengthfor PNG;png_base64also arrives as an MCP image block, andterminalis plain Unicode half-blocks drawn for a dark backgroundOver-capacity input fails as
data_too_largewith its byte count; a PNG over 2048 px per side fails asraster_too_largewith a scale that fits, whilesvgandterminalhave no pixel cap
toolkit_encode_value tool
operation(encodeordecode) andencoding(base64,base64url,hex,url) are required; whitespace inhex,base64, andbase64urlinput is ignored, so wrapped MIME and PEM bodies decode as-isDecode returns
resultasutf8text unlessoutputEncodingasks forhex,base64, or unpaddedbase64url, which returns the bytes losslessly and transcodes between encodings; malformed input fails asdecode_failed, and binary bytes asdecode_not_utf8rather than with replacement characters
toolkit_geolocate_ip tool
targetis an IPv4/IPv6 address or a dotted hostname, DNS-resolved first; private or reserved addresses, and public-format ones the provider reports as unlocatable, fail asprivate_target, unresolvable hostnames asunresolvable_hostOr send
targets(up to 1000) instead, never both: the first 100 return orderedresultswith per-target errors,failedCountcounts failures, andunprocessedTargetslists the rest to resubmitReturns
country,countryCode,region,city,latitude/longitude,asn,asHolder,asName,org,isp, andtimezonewithresolvedIpandsource; atrueinproxy,hosting, ormobilemeans the location describes infrastructure, not a personorgcan name a customer or sub-allocation (APNIC and Cloudflare DNS Resolver projectfor1.1.1.1);isp,asHolder, andasName(CLOUDFLARENET) name the network operator. With noorgfrom the provider,orgcarriesasHolder, thenispUses the keyless ip-api free tier over plaintext HTTP by default (
TOOLKIT_GEO_BASE_URL,TOOLKIT_GEO_API_KEY); results are cached per resolved IPSingle and batch lookups have separate rate limits (
TOOLKIT_GEO_RATE_LIMIT_PER_MIN=45,TOOLKIT_GEO_BATCH_RATE_LIMIT_PER_MIN=15); refusals reportrate_limitedwith seconds to wait, and cache hits stay free
toolkit_check_network tool
modeisping,traceroute,connectivity, orpublic_ip(the host's IPv4 egress address; it can't show whether IPv6 egress works);targetis required except forpublic_ip, andport(1–65535) forconnectivity;count1–10 pings (default 3),timeoutMs100–30000 (default 3000, one budget across every address forconnectivity);family4or6probes one address familyA hostname resolves once to all its addresses, tried in turn and alternating IPv4 and IPv6 until one gives a result;
resolvedIpnames the address whose result is reportedA silent host is
reachable: false, not an error;pingaddsrttMs,sent,received, andpacketLossPercent,connectivityaddsoutcome(open,refused,timeout,unreachable), andtraceroutereturnshops; a hostname that won't resolve fails asunreachablein every mode, as does ping or traceroute when its binary gives no result for any address tried (missing, stopped at its time limit, or exited with an error), and afamilythe target has no address in fails asfamily_mismatchRegistered only when
TOOLKIT_ENABLE_NET_DIAGNOSTICS=true; unlessTOOLKIT_ALLOW_PRIVATE_NETWORK=true, a hostname's private and reserved addresses are skipped, a target with nothing else fails asprivate_target_blocked, and error messages count those addresses instead of naming them
toolkit_check_system tool
whatisos,cpu,memory,load, orinterfaces; exactly one matching facet object is populatedosnames the runtime (runtimeisbunornode,runtimeVersionits version) besidenodeVersion, the Node.js version the process reportsmemory.availableBytesis the allocation headroom, the same figure under Bun and Node, andlimitBytesappears under a container memory limit;totalBytes,freeBytes, andusedBytesare raw OS figures, and on macOSfreeBytesis free pages alone, sousedBytescounts reclaimable cache as used thereUnder Bun on macOS the headroom is read from the host's page statistics; when they can't be read the call fails as
memory_stats_unavailableinstead of reporting free pagesRegistered only when
TOOLKIT_ENABLE_SYSTEM_INFO=true, sinceosandinterfacesdisclose host topology and version details
Features
Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
Toolkit-specific:
Hashing, ID minting, QR encoding, and encode/decode run in-process on
node:crypto,Buffer, and theqrcodelibrary, with no upstream callsGeolocation calls the provider, never the target, and checks the DNS-resolved IP against private ranges, so a hostname can't reach an internal address
Fail-closed gating:
toolkit_check_networkandtoolkit_check_systemare absent fromtools/listunless enabled. Both report on the server's host, not the caller's, so they belong on local or self-hosted deploymentsTwo-tier network gate: with diagnostics on, private, loopback, link-local, and reserved targets (the cloud-metadata endpoint included) stay blocked until
TOOLKIT_ALLOW_PRIVATE_NETWORK=true
Agent-friendly output:
Provenance: geolocation and network diagnostics echo
resolvedIp, the address located or probed; geolocation also names itssourceand omits fields the provider didn't report instead of inventing themResponse shaping: provider strings are capped at 256 characters, stripped of control characters and bidirectional override controls, and Markdown-escaped in
content[], so registry-controlled text likeorgcan't flood a model's context and reads back as written instead of rendering as links or formattingDiscriminated outputs:
operation,format,mode, andwhatecho what ran, and only that branch's fields are populatedTyped failures: every declared failure carries a
reasonand a recovery hint, and conflicting inputs (expectedwithgenerate,outputEncodingwithencode) are rejected by name, not ignored
Getting started
Public Hosted Instance
A public instance is available at https://toolkit.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"toolkit-mcp-server": {
"type": "streamable-http",
"url": "https://toolkit.caseyjhand.com/mcp"
}
}
}Self-Hosted / Local
Add the following to your MCP client configuration file. No API key is required.
{
"mcpServers": {
"toolkit-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/toolkit-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with npx (no Bun required):
{
"mcpServers": {
"toolkit-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/toolkit-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with Docker:
{
"mcpServers": {
"toolkit-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/toolkit-mcp-server:latest"]
}
}
}To enable the gated host-probing tools, add their flags to env (or -e for Docker):
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"TOOLKIT_ENABLE_NET_DIAGNOSTICS": "true",
"TOOLKIT_ENABLE_SYSTEM_INFO": "true"
}For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcpPrerequisites
Bun v1.4.0 or higher (or Node.js v24+).
No API key needed — geolocation uses the keyless ip-api free tier by default.
Installation
Clone the repository:
git clone https://github.com/cyanheads/toolkit-mcp-server.gitNavigate into the directory:
cd toolkit-mcp-serverInstall dependencies:
bun installConfiguration
All variables are optional.
Variable | Description | Default |
| Register the gated |
|
| Register the gated |
|
| With network diagnostics on, permit private, reserved, loopback, and link-local targets. |
|
| API key for the geolocation endpoint, if it requires one. | none |
| Base URL for an ip-api-compatible endpoint. The keyless default is plaintext HTTP; ip-api's HTTPS endpoint needs a paid key. |
|
| In-memory geolocation cache TTL in seconds. |
|
| Max geolocation requests per minute; cache hits don't count. |
|
| Max batch geolocation requests per minute, counted separately. |
|
| Transport: |
|
| Port for the HTTP server. |
|
| HTTP session mode: |
|
| Auth mode: |
|
| Log level (RFC 5424). |
|
| Enable OpenTelemetry. |
|
See .env.example for the full list of optional overrides.
Running the server
Local development
Build and run:
# One-time build bun run rebuild # Run the built server bun run start:stdio # or bun run start:httpRun checks and tests:
bun run devcheck # Lint, format, typecheck, security, changelog sync bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
Docker
docker build -t toolkit-mcp-server .
docker run --rm -p 3010:3010 toolkit-mcp-serverThe Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/toolkit-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
Project structure
Directory | Purpose |
|
|
| Server-specific environment variable parsing and validation with Zod. |
| Tool definitions ( |
| Geolocation service — DNS resolution, provider call with retry, normalization, in-memory cache. |
| Network-diagnostic service plus the shared target schema and private-range classifier. |
| Strict hex / base64 / base64url decoder shared by |
| The published |
| Vitest suites for tools ( |
Development guide
See CLAUDE.md / AGENTS.md for development guidelines and architectural rules. The short version:
Handlers throw, framework catches — no
try/catchin tool logicUse
ctx.logfor request-scoped logging,ctx.statefor tenant-scoped storageRegister new tools in the
createApp()arrays insrc/index.ts; a host-probing tool registers only behind an enable flagWrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields
Contributing
Issues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testLicense
Apache-2.0 — see LICENSE for details.
Available Tools
5 toolstoolkit_encode_valuetoolkit-mcp-server: encode valueARead-onlyIdempotentInspect
Encode or decode a value across base64, base64url, hex, or URL (percent) encoding, in either direction. Set operation to "encode" to transform raw UTF-8 text into the chosen encoding, or "decode" to recover the original bytes from an encoded value. Decoded bytes come back as UTF-8 text by default; set outputEncoding to "hex", "base64", or "base64url" (unpadded, the form JWK members, JWS signatures, and PKCE code challenges use) to receive them re-encoded instead, which is lossless for binary data and transcodes between encodings (a base64 digest to hex, or hex key bytes to base64url, for example). Decoding never substitutes replacement characters: bytes that are not valid UTF-8 text are reported as a recoverable error that points at outputEncoding. Whitespace in hex, base64, and base64url values is ignored, so line-wrapped MIME bodies and PEM bodies decode as-is (drop PEM's -----BEGIN/END----- lines, which are not base64). base64url uses the URL-safe alphabet (- and _ instead of + and /); url applies encodeURIComponent and percent-decoding. A value that is malformed for the chosen encoding is reported as a recoverable error, not a silent best-effort.
Inputs: value (required), encoding (required), operation (required), outputEncoding. Returns: error, result, encoding, operation, +1 more
toolkit_generate_idtoolkit-mcp-server: generate idARead-onlyInspect
Mint cryptographically-random identifiers using the platform CSPRNG — the correct source for IDs that must be unpredictable, unlike model-generated values. type selects the format: uuid_v4 (random, the default), uuid_v7 (time-ordered, sortable by creation), or ulid (26-char Crockford-base32, lexicographically sortable). Set count to mint a batch in one call (up to 1000); the returned ids array always contains exactly count values and is never truncated. For uuid_v7 and ulid, a batch is monotonic — strictly increasing even within the same millisecond — so the ids array stays in sorted creation order; ids minted in the same millisecond are separated by random gaps, so no id in a batch can be derived from another. IDs from this tool feed into toolkit_generate_qr (pass ids[0] as data) to create a scannable code.
Inputs: type, count. Returns: ids, type, count, error
toolkit_generate_qrtoolkit-mcp-server: generate QR codeARead-onlyIdempotentInspect
Encode text or a URL into a QR code. data is the content to encode (a link, a generated identifier such as toolkit_generate_id's ids[0], or any string). format selects the output: svg returns inline SVG markup sized in pixels, png_base64 returns base64-encoded PNG bytes (with mimeType and byteLength), and terminal returns plain Unicode half-block characters (no escape codes) for a monospace display, drawn for a dark background: light modules, quiet zone included, are blocks and dark modules are spaces. errorCorrection (L/M/Q/H) trades data capacity for damage tolerance, margin sets the quiet-zone width in modules, and scale sets pixels per module for svg and png_base64, so both are (modules + 2 × margin) × scale pixels per side. The returned version (1–40) reflects how dense the encoded data is. png_base64 rejects an image past 2048 px per side with a typed raster_too_large error, so a dense symbol needs a lower scale; svg is vector markup and carries no such limit.
Inputs: data (required), scale, format, margin, +1 more. Returns: error, format, content, version, +2 more
toolkit_geolocate_iptoolkit-mcp-server: geolocate IPARead-onlyIdempotentInspect
Resolve a public IP or dotted hostname to country, region, city, coordinates, ASN, AS holder and name, organization, ISP, timezone, and proxy/hosting/mobile flags. Supply target for one lookup or targets for an ordered batch, never both; blank target and empty targets are unset. Batches process the first 100 positions (duplicates retained) and disclose every remainder in unprocessedTargets; at most 1000 inputs are accepted. Each batch position reports its result or an error with recovery, so cached and local outcomes survive quota refusals. The provider is called directly, never the target. Hostnames are DNS-resolved and resolvedIp names the located address. Private/reserved addresses have no public geolocation. Results are best-effort, city-level at best; VPNs, proxies, mobile NAT, and anycast defeat IP-to-location. Read proxy, hosting, and mobile before trusting coordinates: true describes infrastructure, not the user. org can name a customer or sub-allocation rather than the network operator; read isp, asHolder, and asName for the operator. Absent metadata remains unknown. Provider-supplied names are third-party registry text; content[] escapes them so they read as literal text, never as Markdown. source names the provider. Single and batch quotas are independent; cache hits consume neither quota.
Inputs: target, targets. Returns: asn, isp, org, city, +18 more
toolkit_hash_valuetoolkit-mcp-server: hash valueARead-onlyIdempotentInspect
Generate a cryptographic digest or HMAC of a value, or verify a value against an expected digest. Set operation to "generate" for a digest, or "compare" to constant-time-check value against the expected digest — compare is timing-safe and avoids manual string equality checks. Omitting operation compares when expected is supplied and generates otherwise. Algorithm defaults to sha256; sha384 and sha512 are also secure, while md5 and sha1 are exposed ONLY for checksum and file-integrity compatibility and for verifying existing HMAC-SHA1 signatures, and must not be used for passwords, new signatures, or any other security purpose. Set secret to compute HMAC(algorithm, secret, value) instead of a plain digest, for generate and compare alike — the check behind webhook signatures such as GitHub's X-Hub-Signature-256 (pass the header value as expected) and HS256 JWT signatures; secretEncoding says how secret is written (utf8 default, hex, base64, or base64url for a JWK k), the result carries hmac: true, and the secret is never echoed back. digestEncoding selects the generated digest form: lowercase hex (default), base64, base64url (unpadded, the JWS signature form), or sri (-, the npm lockfile integrity and Subresource Integrity form, sha256/sha384/sha512 only, plain digests only). expected is recognized by its shape at the algorithm's digest length, so a published checksum can be pasted as-is: a bare hex, base64, or base64url digest; SRI, which may hold several space-separated entries as an npm integrity field can and matches when any entry for algorithm does; one checksum-file line as sha256sum, shasum, md5, or openssl dgst prints it ( , or SHA256 () = ); or a digest prefixed sha256: or sha256= (OCI and release-asset digests, webhook signature headers). A tag or prefix naming another algorithm fails rather than being ignored, and a multi-line checksum file must be cut to the one line for the file. inputEncoding controls how value is read before hashing (utf8 default, or hex/base64 for raw binary data) so binary blobs need no decode round-trip. The canonical use is matching a download against a vendor-published checksum or a lockfile integrity entry.
Inputs: value (required), secret, expected, algorithm, +4 more. Returns: hmac, error, digest, matches, +3 more
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 5 tools
Each tool targets a clearly distinct resource: hashing, encoding, IP lookup, ID generation, and QR generation. The only mild overlap is between toolkit_hash_value and toolkit_encode_value, since both accept hex/base64/base64url forms and the hash description even mentions transcoding, so an agent might hesitate on which to call to convert a digest between encodings.
All five tools share the prefix `toolkit_` followed by a consistent verb_noun pattern (hash_value, encode_value, geolocate_ip, generate_id, generate_qr). The verb choice matches the operation type (generate/hash/encode/geolocate) predictably.
Five tools is within the healthy range and each is a self-contained, non-trivial utility with paired operations (generate/compare, encode/decode, single/batch). For a general-purpose 'toolkit' the selection feels somewhat arbitrary and sparse, but nothing is redundant.
Within each tool the surface is complete: hashing supports generate and verify, encoding supports both directions and transcoding, ID generation supports batching and multiple formats, QR supports multiple output formats, and geolocation supports single and batch. As a broad 'toolkit' there are gaps (no timestamp/date, JSON, regex, or compression utilities), but they are workable for the apparent crypto/encoding/identity focus.
Maintenance
Related MCP Connectors
The Mercado Pago MCP Server implements the Model Context Protocol to provide AI agents and LLMs with access to Mercado Pago's APIs and tools within compatible development environments. It acts as an intermediary that translates Mercado Pago resources into executable functions (tools) that AI applications can invoke to perform actions and automate flows. The server simplifies integration, enables using documentation to implement or improve code, and optimizes operations through natural language interactions without manual implementations.
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
Real-time planetary signal engine and Model Context Protocol (MCP) server for autonomous AI agents.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA comprehensive Model Context Protocol server implementation that enables AI assistants to interact with file systems, databases, GitHub repositories, web resources, and system tools while maintaining security and control.132 npm2MIT
- 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.100237 npm22TypeScriptMIT
- FlicenseNot gradedqualityDmaintenanceA secure Model Context Protocol server providing HTTP endpoints for AI agent tool execution, including file system operations, shell commands, and LLM-based code generation.1-
- AlicenseAqualityDmaintenanceA Model Context Protocol server providing network diagnostic tools for AI agents, including connectivity testing, batch operations, local network info, and pcap analysis.346MIT