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.

已验证Streamable HTTP可网页运行Other

安装

在 SourceWeft 中

  1. 打开 控制台中的 Toolkit Mcp Server,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

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.

7 Tools

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

ToolDescription
toolkit_hash_valueGenerate a cryptographic digest (sha256/sha384/sha512/sha1/md5) as hex, base64, or SRI, or constant-time-compare a value against an expected digest.
toolkit_generate_idMint cryptographically-random identifiers — UUIDv4, UUIDv7, or ULID — singly or in batches up to 1000.
toolkit_generate_qrEncode text or a URL into a QR code as SVG markup, base64 PNG, or a terminal-renderable string.
toolkit_encode_valueEncode or decode a value across base64, base64url, hex, or URL percent-encoding, in either direction.
toolkit_geolocate_ipResolve a public IP or hostname to geographic and network metadata — country, city, coordinates, ASN, timezone.
toolkit_check_networkGated, off by default. Read-only network diagnostics from the server host — ping, traceroute, TCP connectivity, or egress-IP detection.
toolkit_check_systemGated, off by default. Report a facet of the server host's system state — OS, CPU, memory, load average, or network interfaces.

Capability reference

toolkit_hash_value tool

  • operation: generate (a digest) or compare (timing-safe check via timingSafeEqual); omitted, it compares when expected is sent and generates otherwise. generate sent together with expected is rejected with a typed expected_without_compare error rather than ignoring expected
  • Algorithms: sha256 (default), sha384, and sha512 for security; sha1 and md5 are exposed for checksum and file-integrity compatibility only — never for passwords or signatures
  • digestEncoding sets the generated digest's form: hex (lowercase, default), base64, or sri (sha512-<base64>, the npm lockfile integrity and Subresource Integrity form — sha256/sha384/sha512 only)
  • expected is 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 npm integrity field can: entries for other algorithms are skipped, and it matches when any entry for algorithm does
  • 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 for algorithm (expected_algorithm_mismatch)
  • inputEncoding reads value as utf8 (default), hex, or base64, 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), or ulid (26-char Crockford base32, lexicographically sortable)
  • count mints a batch up to 1000 in one call; the returned ids array always holds exactly count values
  • uuid_v7 and ulid batches are monotonic — strictly increasing even within the same millisecond — so ids stays 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; for ulid this 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 with mimeType and byteLength), or terminal (plain Unicode half-blocks with no escape codes, fenced in content[])
  • terminal is 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 for every format; scale sets pixels per module for svg (its width/height) and png_base64, so both are (modules + 2 × margin) × scale px per side
  • The returned version (1–40) reflects how dense the encoded data is
  • png_base64 also arrives as an MCP image content block, so a client reading content[] can render the code without decoding structuredContent
  • A rendered PNG is bounded at 2048 px per side — (modules + 2 × margin) × scale — so a dense symbol at a high scale is rejected with a typed raster_too_large error naming a scale that fits; svg and terminal are unbounded
  • data is 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 higher errorCorrection levels, so over-capacity input is rejected with a typed data_too_large error that reports the payload's byte count

toolkit_encode_value tool

  • encoding: base64, base64url (URL-safe alphabet), hex, or url (percent-encoding)
  • operation: encode (raw UTF-8 → encoding) or decode (encoded value → bytes)
  • outputEncoding (decode only) returns the recovered bytes as utf8 text (when omitted), hex, or base64 — lossless for binary data, and a direct transcode between encodings (a base64 digest to hex, for example). Sent with encode, it is rejected with a typed output_encoding_not_applicable error
  • Decode never substitutes replacement characters: bytes that aren't valid UTF-8 return a typed decode_not_utf8 error pointing at outputEncoding, and a leading byte-order mark is kept
  • Whitespace in hex, base64, and base64url input is ignored, so line-wrapped MIME and PEM bodies decode as-is (without PEM's -----BEGIN/END----- lines, which aren't base64); a url value is taken literally
  • Malformed decode input returns a typed decode_failed error 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, and mobile flag when the address is a proxy/VPN/Tor exit, a datacenter network, or a mobile carrier — a true on 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; resolvedIp echoes the IP actually located, and source names 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 from tools/list otherwise
  • mode: ping (ICMP round-trip), traceroute (hop path to the target), connectivity (raw TCP connect to target on port), or public_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 an unreachable error naming the binary instead
  • ping reports sent, received, and packetLossPercent alongside the average rttMs; on macOS/BSD an IPv6 target runs ping6/traceroute6
  • connectivity reports an outcome — open, refused (nothing listening), timeout (traffic dropped), or unreachable (no route) — and the connect time as rttMs when 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 from tools/list otherwise
  • what: os, cpu, memory, load, or interfaces
  • Exactly one facet object is populated per call, matching what
  • memory reports availableBytes (headroom for new allocations) and, when the server runs under a container memory limit, limitBytes; totalBytes, freeBytes, and usedBytes are 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 os and interfaces disclose 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:crypto and the qrcode library; no upstream calls
  • toolkit_geolocate_ip is the one keyless-by-default network call (ip-api free tier, optional TOOLKIT_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 from tools/list unless 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 data capped at 2953 bytes, rendered PNGs capped at 2048 px per side, ID batches capped at 1000; CSPRNG-backed primitives with constant-time hash comparison via timingSafeEqual

Agent-friendly output:

  • Provenance — geolocation echoes resolvedIp (the IP actually located) and source (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, and what fields echo back exactly what ran, with only the branch-relevant fields populated per call; an unreachable host in toolkit_check_network reports reachable: false as valid data, not an error
  • Typed failure reasons — decode, hashing, QR, geolocation, and network failures each carry a structured reason plus a next-step recovery hint (e.g. decode_not_utf8, expected_malformed, raster_too_large, private_target_blocked); expected sent with generate, and outputEncoding sent with encode, 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:

json
{  "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 — the five always-on tools and the default keyless geolocation tier work out of the box.

json
{  "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):

json
{  "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:

json
{  "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):

json
"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:

sh
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http# Server listens at http://localhost:3010/mcp

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

  1. Clone the repository:
sh
git clone https://github.com/cyanheads/toolkit-mcp-server.git
  1. Navigate into the directory:
sh
cd toolkit-mcp-server
  1. Install dependencies:
sh
bun install

Configuration

Every variable is optional. Server-specific options are validated at startup via the Zod schema in src/config/server-config.ts.

VariableDescriptionDefault
TOOLKIT_ENABLE_NET_DIAGNOSTICSRegister the gated toolkit_check_network tool. Leave off for hosted or shared deployments.false
TOOLKIT_ENABLE_SYSTEM_INFORegister the gated toolkit_check_system tool. Meaningful only on a local or self-hosted deployment.false
TOOLKIT_ALLOW_PRIVATE_NETWORKWith network diagnostics on, permit private/reserved/loopback targets. The second explicit gate.false
TOOLKIT_GEO_API_KEYAPI key for the geolocation endpoint, if it requires one.none
TOOLKIT_GEO_BASE_URLBase URL for an ip-api-compatible geolocation endpoint. The default is plaintext HTTP — ip-api's HTTPS endpoint is not part of the keyless free tier and answers 403 SSL unavailable for this endpoint without a paid key. Point this at an HTTPS endpoint (with TOOLKIT_GEO_API_KEY) to encrypt the provider request.http://ip-api.com
TOOLKIT_GEO_CACHE_TTL_SECONDSIn-memory geolocation cache TTL in seconds.3600
TOOLKIT_GEO_RATE_LIMIT_PER_MINMax geolocation requests per minute.45
MCP_TRANSPORT_TYPETransport: stdio or http.stdio
MCP_HTTP_PORTPort for the HTTP server.3010
MCP_SESSION_MODEauto, stateful, or stateless. No tool requests multi-round input. auto is the framework schema default and resolves to stateful, but with MCP_SESSION_MODE unset the server resolves stateless from createApp({ sessionMode }); an explicit MCP_SESSION_MODE value still overrides it.stateless
MCP_AUTH_MODEAuth mode: none, jwt, or oauth.none
MCP_LOG_LEVELLog level (RFC 5424).info
OTEL_ENABLEDEnable OpenTelemetry instrumentation (spans, metrics, completion logs).false

See .env.example for the full list of optional overrides.

Running the server

Local development

  • Build and run:

    sh
    # One-time buildbun run rebuild
    # Run the built serverbun run start:stdio# orbun run start:http
  • Run checks and tests:

    sh
    bun run devcheck   # Lint, format, typecheck, security, changelog syncbun run test       # Vitest test suitebun run lint:mcp   # Validate MCP definitions against spec

Docker

sh
docker build -t toolkit-mcp-server .docker run --rm -e MCP_TRANSPORT_TYPE=http -p 3010:3010 toolkit-mcp-server

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

DirectoryPurpose
src/index.tscreateApp() entry point — registers tools and inits services, with fail-closed gating for the two host-probing tools.
src/configServer-specific environment variable parsing and validation with Zod.
src/mcp-server/toolsTool definitions (*.tool.ts). Seven tools — five always-on, two gated.
src/services/geoGeolocation service — DNS resolution, provider call with retry/backoff, normalization, in-memory cache.
src/services/networkNetwork-diagnostic service plus the shared target validator and private-range classifier.
tests/Unit and integration tests mirroring the src/ structure.

Development guide

See CLAUDE.md / AGENTS.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic
  • Use ctx.log for request-scoped logging, ctx.state for tenant-scoped storage
  • Register new tools in the createApp() arrays in src/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:

sh
bun run devcheckbun run test

License

Apache-2.0 — see LICENSE for details.

来源:README.md,提交 1174e35

工具

0
工具元数据尚未被收录。

版本历史

3
  1. v2.3.1最新Sep 24, 2026
  2. v2.2.4Sep 19, 2026
  3. v2.2.3Sep 16, 2026