
Toolkit Mcp Server
io.github.cyanheadsv2.3.1更新于 Sep 29, 2026
Generate IDs, QR codes, and hashes, encode values, geolocate IPs, plus gated host diagnostics.
安装
在 SourceWeft 中
- 打开 控制台中的 Toolkit Mcp Server,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Web executable,通过 Streamable HTTP。 远程服务在工作区中配置后即可从网页运行时运行。
其他 MCP 客户端
把它添加到你客户端的 mcpServers 配置中。
{
"mcpServers": {
"toolkit-mcp-server": {
"type": "http",
"url": "https://toolkit.caseyjhand.com/mcp"
}
}
}README
@cyanheads/toolkit-mcp-server
Generate random IDs, QR codes, and hashes, encode and decode values, and geolocate IPs, plus gated network and system diagnostics, via MCP. STDIO or Streamable HTTP.
Public Hosted Server: https://toolkit.caseyjhand.com/mcp
Overview
A standalone developer-utilities server — the five always-on tools need no upstream API: generate identifiers, QR codes, and cryptographic digests, encode and decode values, and geolocate a public IP or hostname. Two more tools report diagnostics about the server's own host, gated off by default. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
Tools
Capability reference
toolkit_hash_value tool
operation:generate(a digest) orcompare(timing-safe check viatimingSafeEqual); omitted, it compares whenexpectedis sent and generates otherwise.generatesent together withexpectedis rejected with a typedexpected_without_compareerror rather than ignoringexpected- Algorithms:
sha256(default),sha384, andsha512for security;sha1andmd5are exposed for checksum and file-integrity compatibility only — never for passwords or signatures digestEncodingsets the generated digest's form:hex(lowercase, default),base64, orsri(sha512-<base64>, the npm lockfileintegrityand Subresource Integrity form — sha256/sha384/sha512 only)expectedis accepted as hex, base64, or SRI, recognized by its shape at the algorithm's digest length, so a published checksum is pasted as-is. An SRI value may hold several space-separated entries, as an npmintegrityfield can: entries for other algorithms are skipped, and it matches when any entry foralgorithmdoes- Typed errors separate an unrecognizable digest (
expected_malformed), one of the wrong length (expected_length_mismatch, whose hint names the algorithm that length belongs to), and an SRI value with no entry foralgorithm(expected_algorithm_mismatch) inputEncodingreadsvalueasutf8(default),hex, orbase64, so binary blobs skip a decode round-trip- Canonical use: match a download against a vendor-published checksum or a lockfile integrity entry
toolkit_generate_id tool
type:uuid_v4(random, default),uuid_v7(time-ordered, sortable by creation), orulid(26-char Crockford base32, lexicographically sortable)countmints a batch up to 1000 in one call; the returnedidsarray always holds exactlycountvaluesuuid_v7andulidbatches are monotonic — strictly increasing even within the same millisecond — soidsstays in sorted creation order. Ids minted in the same millisecond are separated by random gaps (a 32-bit draw plus one), so no id in a batch is derivable from another; forulidthis departs from the spec's reference +1 increment on purpose- Read-only — minting changes nothing — but never idempotent, so a client won't cache or deduplicate a batch
toolkit_generate_qr tool
format:svg(inline markup),png_base64(raster bytes withmimeTypeandbyteLength), orterminal(plain Unicode half-blocks with no escape codes, fenced incontent[])terminalis drawn for a dark background: light modules, quiet zone included, are blocks and dark modules are spaceserrorCorrection(L/M/Q/H) trades data capacity for damage tolerance;marginsets the quiet-zone width in modules for every format;scalesets pixels per module forsvg(itswidth/height) andpng_base64, so both are(modules + 2 × margin) × scalepx per side- The returned
version(1–40) reflects how dense the encoded data is png_base64also arrives as an MCP image content block, so a client readingcontent[]can render the code without decodingstructuredContent- A rendered PNG is bounded at 2048 px per side —
(modules + 2 × margin) × scale— so a dense symbol at a highscaleis rejected with a typedraster_too_largeerror naming a scale that fits;svgandterminalare unbounded datais encoded as UTF-8 and capped at 2953 bytes — the absolute ceiling (version 40, level L, byte mode); a non-ASCII character takes 2–4 bytes, and usable capacity is lower at highererrorCorrectionlevels, so over-capacity input is rejected with a typeddata_too_largeerror that reports the payload's byte count
toolkit_encode_value tool
encoding:base64,base64url(URL-safe alphabet),hex, orurl(percent-encoding)operation:encode(raw UTF-8 → encoding) ordecode(encoded value → bytes)outputEncoding(decode only) returns the recovered bytes asutf8text (when omitted),hex, orbase64— lossless for binary data, and a direct transcode between encodings (a base64 digest to hex, for example). Sent withencode, it is rejected with a typedoutput_encoding_not_applicableerror- Decode never substitutes replacement characters: bytes that aren't valid UTF-8 return a typed
decode_not_utf8error pointing atoutputEncoding, and a leading byte-order mark is kept - Whitespace in
hex,base64, andbase64urlinput is ignored, so line-wrapped MIME and PEM bodies decode as-is (without PEM's-----BEGIN/END-----lines, which aren't base64); aurlvalue is taken literally - Malformed decode input returns a typed
decode_failederror with a recovery hint, not a silent best-effort
toolkit_geolocate_ip tool
- Returns country, region, city, latitude/longitude, ASN, owning organization, and timezone
proxy,hosting, andmobileflag when the address is a proxy/VPN/Tor exit, a datacenter network, or a mobile carrier — atrueon any of them means the coordinates describe infrastructure, not a person. Absent when the provider doesn't report them- A hostname is DNS-resolved first;
resolvedIpechoes the IP actually located, andsourcenames the answering provider - SSRF-free — the server calls the provider, never the target; the resolved IP is re-checked against private ranges, and private/reserved addresses are rejected (they have no public geolocation)
- Best-effort and provider-bounded: VPNs, proxies, mobile NAT, and anycast all defeat IP-to-location, accuracy is city-level at best, and absent fields are reported as unknown rather than invented
- Provider-supplied strings are truncated and stripped of control characters before they reach the response, so registry-controlled text (
org,isp,as) cannot flood or format a model's context - Keyless by default (ip-api free tier, which is plaintext HTTP — see
TOOLKIT_GEO_BASE_URL); results are cached in memory by resolved IP under a fixed entry cap
toolkit_check_network tool
- Gated — registered only when
TOOLKIT_ENABLE_NET_DIAGNOSTICS=true; absent fromtools/listotherwise mode:ping(ICMP round-trip),traceroute(hop path to the target),connectivity(raw TCP connect totargetonport), orpublic_ip(the host's own egress IP)- A host that does not respond is reported as
reachable: false— a valid result, not an error. A ping or traceroute binary that is missing, or that exits without a result, is anunreachableerror naming the binary instead pingreportssent,received, andpacketLossPercentalongside the averagerttMs; on macOS/BSD an IPv6 target runsping6/traceroute6connectivityreports anoutcome—open,refused(nothing listening),timeout(traffic dropped), orunreachable(no route) — and the connect time asrttMswhen open- Diagnoses the server's own network, so it is useful on a local or self-hosted deployment; reaching a private/reserved/internal target additionally requires
TOOLKIT_ALLOW_PRIVATE_NETWORK=true, which keeps the cloud-metadata endpoint blocked by default
toolkit_check_system tool
- Gated — registered only when
TOOLKIT_ENABLE_SYSTEM_INFO=true; absent fromtools/listotherwise what:os,cpu,memory,load, orinterfaces- Exactly one facet object is populated per call, matching
what memoryreportsavailableBytes(headroom for new allocations) and, when the server runs under a container memory limit,limitBytes;totalBytes,freeBytes, andusedBytesare the raw OS figures, which count reclaimable cache as used and read the host's RAM inside a container- Describes the host this server runs on, not the calling client — meaningful on a local or self-hosted deployment; gated off by default because
osandinterfacesdisclose 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:
- Local, pure-compute core — hashing, ID minting, QR encoding, and value encode/decode run entirely in-process via
node:cryptoand theqrcodelibrary; no upstream calls toolkit_geolocate_ipis the one keyless-by-default network call (ip-api free tier, optionalTOOLKIT_GEO_API_KEY); the server calls the provider directly and re-checks the DNS-resolved IP against private ranges, so a hostname can't smuggle a request to an internal address- Fail-closed gating — the two host-probing tools (
toolkit_check_network,toolkit_check_system) are absent fromtools/listunless explicitly enabled, so a hosted instance exposes no SSRF or info-disclosure surface by default - Two-tier network gate — even with diagnostics enabled, private/reserved/loopback/link-local targets (including the cloud-metadata endpoint) stay blocked until a second flag permits them
- Bounded inputs — QR
datacapped at 2953 bytes, rendered PNGs capped at 2048 px per side, ID batches capped at 1000; CSPRNG-backed primitives with constant-time hash comparison viatimingSafeEqual
Agent-friendly output:
- Provenance — geolocation echoes
resolvedIp(the IP actually located) andsource(the answering provider); absent upstream fields are reported as unknown, never invented - Response shaping — provider-supplied strings (
org,isp,as) are length-bounded and stripped of control characters before they reach the response, so untrusted registry text can't flood or format a model's context - Discriminated output contracts —
operation,format,mode, andwhatfields echo back exactly what ran, with only the branch-relevant fields populated per call; an unreachable host intoolkit_check_networkreportsreachable: falseas valid data, not an error - Typed failure reasons — decode, hashing, QR, geolocation, and network failures each carry a structured
reasonplus a next-step recovery hint (e.g.decode_not_utf8,expected_malformed,raster_too_large,private_target_blocked);expectedsent withgenerate, andoutputEncodingsent withencode, are rejected by name rather than silently 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:
Self-Hosted / Local
Add the following to your MCP client configuration file. No API key is required — the five always-on tools and the default keyless geolocation tier work out of the box.
Or with npx (no Bun required):
Or with Docker:
To enable the gated host-probing tools, add their flags to env (or -e for Docker):
For Streamable HTTP, set the transport and start the server:
Prerequisites
- 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:
- Navigate into the directory:
- Install dependencies:
Configuration
Every variable is optional. Server-specific options are validated at startup via the Zod schema in src/config/server-config.ts.
See .env.example for the full list of optional overrides.
Running the server
Local development
-
Build and run:
-
Run checks and tests:
Docker
The 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
Development guide
See CLAUDE.md / AGENTS.md for development guidelines and architectural rules. The short version:
- Handlers throw, framework catches — no
try/catchin tool logic - Use
ctx.logfor request-scoped logging,ctx.statefor tenant-scoped storage - Register new tools in the
createApp()arrays insrc/index.ts - The two host-probing tools register behind their enable-flags; the network target gate validates after DNS resolution — never fabricate a result for an unlocatable or unreachable target
Contributing
Issues are welcome. Run checks and tests before submitting:
License
Apache-2.0 — see LICENSE for details.
来源:README.md,提交 1174e35
工具
0版本历史
3- v2.3.1最新Sep 24, 2026
- v2.2.4Sep 19, 2026
- v2.2.3Sep 16, 2026
