Skip to main content
Glama
cyanheads

toolkit-mcp-server

by cyanheads

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework

公開ホストサーバー: https://toolkit.caseyjhand.com/mcp


ツール

7つのツール。5つは常時有効で設定不要 — 純粋な計算ユーティリティとSSRFフリーのIPルックアップ。残り2つはサーバーホストを調査するもので、デフォルトではtools/listに表示されず、オプトインが必要で、フェイルクローズドです。

ツール

説明

toolkit_hash_value

暗号学的ダイジェスト(sha256/sha512/sha1/md5)を生成するか、値を期待されるダイジェストと定数時間比較します。

toolkit_generate_id

暗号学的にランダムな識別子(UUIDv4、UUIDv7、ULID)を、単一または最大1000個のバッチで生成します。

toolkit_generate_qr

テキストまたはURLをQRコードにエンコードし、SVGマークアップ、base64 PNG、または端末表示可能な文字列として出力します。

toolkit_encode_value

値をbase64、base64url、hex、URLパーセントエンコーディングのいずれかでエンコードまたはデコードします(双方向)。

toolkit_geolocate_ip

公開IPまたはホスト名を地理的・ネットワークメタデータ(国、都市、座標、ASN、タイムゾーン)に解決します。

toolkit_check_network

ゲート付き、デフォルトでオフ。 サーバーホストからの読み取り専用ネットワーク診断 — ping、traceroute、TCP接続、または出口IP検出。

toolkit_check_system

ゲート付き、デフォルトでオフ。 サーバーホストのシステム状態の一面(OS、CPU、メモリ、ロード平均、ネットワークインターフェース)を報告します。

toolkit_hash_value

ダイジェストを生成するか、値を期待値と定数時間で検証します。

  • operation: generate(小文字16進ダイジェスト)またはcompare(timingSafeEqualによるタイミングセーフチェック)

  • アルゴリズム: セキュリティ用途にはsha256(デフォルト)とsha512。sha1とmd5はチェックサムやファイル整合性の互換性のためだけに公開 — パスワードや署名には絶対に使用しないでください

  • inputEncodingはvalueをutf8(デフォルト)、hex、base64として読み取るため、バイナリブロブはデコードの往復をスキップします

  • 標準的な使用例: ダウンロードをベンダー公開のチェックサムと照合する


toolkit_generate_id

プラットフォームのCSPRNGから暗号学的にランダムな識別子を生成します — モデルがでっち上げた値とは異なり、予測不可能でなければならないIDに適した正しいソースです。

  • type: uuid_v4(ランダム、デフォルト)、uuid_v7(時間順、作成順にソート可能)、またはulid(26文字のCrockford base32、辞書順ソート可能)

  • countは1回の呼び出しで最大1000個のバッチを生成。返されるids配列は常に正確にcount個の値を保持します

  • uuid_v7とulidのバッチは単調増加 — 同じミリ秒内でも厳密に増加するため、idsは作成順にソートされた状態を保ちます

  • 読み取り専用 — 生成しても何も変更しませんが、決して冪等ではないため、クライアントはバッチをキャッシュしたり重複排除したりしません


toolkit_generate_qr

テキストまたはURLをQRコードにエンコードします。

  • format: svg(インラインマークアップ)、png_base64(mimeTypeとbyteLengthを含むラスターバイト)、またはterminal(Unicodeブロック文字列)

  • errorCorrection(L/M/Q/H)はデータ容量と損傷耐性をトレードオフします。marginはクワイエットゾーンの幅を設定。scaleはラスター出力のモジュールあたりのピクセル数を設定します

  • 返されるversion(1–40)はエンコードされたデータの密度を反映します

  • png_base64はMCP画像コンテンツブロックとしても届くため、content[]を読み取るクライアントはstructuredContentをデコードせずにコードをレンダリングできます

  • レンダリングされたPNGは一辺2048ピクセルに制限 — (modules + 2 × margin) × scale — そのため、高スケールの高密度シンボルは、適合するスケールを指定した型付きraster_too_largeエラーで拒否されます。svgとterminalは無制限です

  • dataは2953バイトに制限 — 絶対上限(バージョン40、レベルL、バイトモード)。使用可能容量はerrorCorrectionレベルが高いほど低くなるため、容量超過の入力は一般的な失敗ではなく、型付きdata_too_largeエラーで拒否されます


toolkit_encode_value

値を双方向でエンコードまたはデコードします。

  • encoding: base64、base64url(URLセーフなアルファベット)、hex、またはurl(パーセントエンコーディング)

  • operation: encode(生のUTF-8 → エンコード)またはdecode(エンコードされた値 → テキスト)

  • 不正なデコード入力は、復旧ヒント付きの型付きdecode_failedエラーを返します。黙ってベストエフォートで処理することはありません


toolkit_geolocate_ip

公開IPまたはホスト名を地理的・ネットワークメタデータに解決します。

  • 国、地域、都市、緯度/経度、ASN、所有組織、タイムゾーンを返します

  • proxy、hosting、mobileは、アドレスがプロキシ/VPN/Tor出口、データセンターネットワーク、モバイルキャリアである場合にフラグを立てます — これらのいずれかがtrueの場合、座標は人物ではなくインフラストラクチャを表します。プロバイダーが報告しない場合は存在しません

  • ホスト名は最初にDNS解決されます。resolvedIpは実際に位置特定されたIPを反映し、sourceは応答したプロバイダーを指定します

  • SSRFフリー — サーバーはプロバイダーを呼び出し、ターゲットは呼び出しません。解決されたIPはプライベート範囲に対して再チェックされ、プライベート/予約済みアドレスは拒否されます(公開ジオロケーションはありません)

  • ベストエフォートかつプロバイダーに依存: VPN、プロキシ、モバイルNAT、エニーキャストはすべてIP-to-locationを無効にし、精度はせいぜい市区町村レベルであり、欠落フィールドは未知として報告され、でっち上げられることはありません

  • プロバイダー提供の文字列は、レスポンスに到達する前に切り詰められ、制御文字が除去されるため、レジストリ管理テキスト(org、isp、as)がモデルのコンテキストを溢れさせたり、書式を乱したりすることはありません

  • デフォルトではキー不要(ip-api無料ティア、平文HTTP — TOOLKIT_GEO_BASE_URLを参照)。結果は解決されたIPごとにメモリ内にキャッシュされ、固定エントリ上限があります


toolkit_check_network

ゲート付き — TOOLKIT_ENABLE_NET_DIAGNOSTICS=trueの場合のみ登録されます。サーバーホストからの読み取り専用ネットワーク診断。

  • mode: ping(ICMPラウンドトリップ)、traceroute(ターゲットへのホップパス)、connectivity(targetのportへの生のTCP接続)、またはpublic_ip(ホスト自身の出口IP)

  • 応答しないホストはreachable: falseとして報告されます — 有効な結果であり、エラーではありません

  • サーバー自身のネットワークを診断するため、ローカルまたはセルフホストデプロイメントで有用です。プライベート/予約済み/内部ターゲットに到達するには、さらにTOOLKIT_ALLOW_PRIVATE_NETWORK=trueが必要です。これにより、クラウドメタデータエンドポイントはデフォルトでブロックされたままになります


toolkit_check_system

ゲート付き — TOOLKIT_ENABLE_SYSTEM_INFO=trueの場合のみ登録されます。サーバーホストのシステム状態の一面を読み取り専用で報告します。

  • what: os、cpu、memory、load、またはinterfaces

  • 呼び出しごとに、whatに一致する1つのファセットオブジェクトのみが設定されます

  • このサーバーが動作するホストを記述し、呼び出し元のクライアントではありません — ローカルまたはセルフホストデプロイメントで意味があります。osとinterfacesはホストのトポロジーとバージョン詳細を開示するため、デフォルトでゲートオフになっています

Related MCP server: IT Tools MCP Server

機能

@cyanheads/mcp-ts-core上に構築:

  • 宣言的ツール定義 — ツールごとに1ファイル、フレームワークが登録と検証を処理

  • 統一エラーハンドリング — ハンドラーがスローし、フレームワークがキャッチ、分類、フォーマット

  • 型付きエラー契約 — 失敗する可能性のある各ツールは、エージェントが行動できる復旧ヒントとともに失敗理由を宣言

  • プラグイン可能な認証: none、jwt、oauth

  • 構造化ログ、オプションのOpenTelemetryトレーシング

  • STDIOおよびStreamable HTTPトランスポート

ツールキット固有:

  • フェイルクローズドゲーティング — 2つのホスト調査ツールは、明示的に有効にしない限りtools/listに存在しないため、ホスト型インスタンスはSSRFや情報開示の表面を露出しません

  • 2層ネットワークゲート — 診断が有効でも、プライベート/予約済み/ループバック/リンクローカルターゲット(クラウドメタデータエンドポイントを含む)は、2番目のフラグで許可されるまでブロックされたまま

  • CSPRNGバックエンドのプリミティブ — 識別子とダイジェストはプラットフォームの暗号ソースから取得され、ハッシュ比較はtimingSafeEqualによる定数時間

  • SSRFフリーのジオロケーション — サーバーがプロバイダーを呼び出し、次にDNS解決されたIPをプライベート範囲に対して再チェックしてからルックアップを実行するため、ホスト名が内部アドレスへのリクエストを密輸することはできません

エージェントフレンドリーな出力:

  • 出所 — ジオロケーションは解決されたIPを反映し、応答したプロバイダーを指定。欠落した上流フィールドは未知として報告され、決してでっち上げられません

  • ダウンしているが有効な結果 — 到達不能なホストはエラーではなくreachable: falseを返すため、呼び出し元は例外テキストではなくデータに基づいて分岐します

  • 型付き失敗理由 — デコード失敗、ダイジェスト欠落、ブロックされたプライベートターゲットはそれぞれ、構造化された理由と次のステップの復旧ヒントを伴います

はじめに

公開ホストインスタンス

公開インスタンスはhttps://toolkit.caseyjhand.com/mcpで利用可能 — インストール不要。Streamable HTTP経由で任意のMCPクライアントから接続:

{
  "mcpServers": {
    "toolkit-mcp-server": {
      "type": "streamable-http",
      "url": "https://toolkit.caseyjhand.com/mcp"
    }
  }
}

セルフホスト / ローカル

以下をMCPクライアント設定ファイルに追加してください。APIキーは不要 — 5つの常時有効ツールとデフォルトのキーレスジオロケーションティアがそのまま動作します。

{
  "mcpServers": {
    "toolkit-mcp-server": {
      "type": "stdio",
      "command": "bunx",
      "args": ["@cyanheads/toolkit-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info"
      }
    }
  }
}

またはnpxを使用(Bun不要):

{
  "mcpServers": {
    "toolkit-mcp-server": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@cyanheads/toolkit-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info"
      }
    }
  }
}

または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"]
    }
  }
}

ゲート付きホスト調査ツールを有効にするには、env(Dockerの場合は-e)にフラグを追加:

"env": {
  "MCP_TRANSPORT_TYPE": "stdio",
  "TOOLKIT_ENABLE_NET_DIAGNOSTICS": "true",
  "TOOLKIT_ENABLE_SYSTEM_INFO": "true"
}

Streamable HTTPの場合は、トランスポートを設定してサーバーを起動:

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

前提条件

  • Bun v1.3.2以上(またはNode.js v24+)。

  • APIキー不要 — ジオロケーションはデフォルトでキーレスのip-api無料ティアを使用します。

インストール

  1. リポジトリをクローン:

git clone https://github.com/cyanheads/toolkit-mcp-server.git
  1. ディレクトリに移動:

cd toolkit-mcp-server
  1. 依存関係をインストール:

bun install

設定

すべての変数はオプションです。サーバー固有のオプションは、src/config/server-config.ts の Zod スキーマを介して起動時に検証されます。

変数

説明

デフォルト値

TOOLKIT_ENABLE_NET_DIAGNOSTICS

ゲート付きの toolkit_check_network ツールを登録します。ホスティング環境や共有デプロイメントではオフにしてください。

false

TOOLKIT_ENABLE_SYSTEM_INFO

ゲート付きの toolkit_check_system ツールを登録します。ローカルまたはセルフホスト型デプロイメントでのみ意味があります。

false

TOOLKIT_ALLOW_PRIVATE_NETWORK

ネットワーク診断が有効な場合、プライベート/予約済み/ループバックターゲットを許可します。2 つ目の明示的なゲートです。

false

TOOLKIT_GEO_API_KEY

ジオロケーションエンドポイントの API キー(必要な場合)。

なし

TOOLKIT_GEO_BASE_URL

ip-api 互換のジオロケーションエンドポイントのベース URL。デフォルトは平文 HTTP です。ip-api の HTTPS エンドポイントはキーレス無料ティアの一部ではなく、有料キーがないと 403 SSL unavailable for this endpoint を返します。プロバイダーリクエストを暗号化するには、これを HTTPS エンドポイント(TOOLKIT_GEO_API_KEY と共に)に設定してください。

http://ip-api.com

TOOLKIT_GEO_CACHE_TTL_SECONDS

インメモリジオロケーションキャッシュの TTL(秒)。

3600

TOOLKIT_GEO_RATE_LIMIT_PER_MIN

1 分あたりの最大ジオロケーションリクエスト数。

45

MCP_TRANSPORT_TYPE

トランスポート: stdio または http。

stdio

MCP_HTTP_PORT

HTTP サーバーのポート。

3010

MCP_AUTH_MODE

認証モード: none、jwt、または oauth。

none

MCP_LOG_LEVEL

ログレベル(RFC 5424)。

info

OTEL_ENABLED

OpenTelemetry 計装(スパン、メトリクス、完了ログ)を有効にします。

false

オプションのオーバーライドの完全なリストについては、.env.example を参照してください。

サーバーの実行

ローカル開発

  • ビルドと実行:

    # One-time build
    bun run rebuild
    
    # Run the built server
    bun run start:stdio
    # or
    bun run start:http
  • チェックとテストの実行:

    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 -e MCP_TRANSPORT_TYPE=http -p 3010:3010 toolkit-mcp-server

Dockerfile はデフォルトで HTTP トランスポート、ステートレスセッションモードを使用し、ログを /var/log/toolkit-mcp-server に出力します。OpenTelemetry のピア依存関係はデフォルトでインストールされます。これらを省略するには、--build-arg OTEL_ENABLED=false を指定してビルドしてください。

プロジェクト構造

ディレクトリ

目的

src/index.ts

createApp() エントリポイント — ツールを登録し、サービスを初期化します。2 つのホストプローブツールには、フェイルクローズドのゲーティングがあります。

src/config

サーバー固有の環境変数の解析と Zod による検証。

src/mcp-server/tools

ツール定義(*.tool.ts)。7 つのツール — 5 つは常時有効、2 つはゲート付き。

src/services/geo

ジオロケーションサービス — DNS 解決、リトライ/バックオフ付きプロバイダー呼び出し、正規化、インメモリキャッシュ。

src/services/network

ネットワーク診断サービスと、共有ターゲットバリデーターおよびプライベート範囲分類子。

tests/

src/ 構造を反映したユニットテストと統合テスト。

開発ガイド

開発ガイドラインとアーキテクチャルールについては、CLAUDE.md / AGENTS.md を参照してください。簡単にまとめると:

  • ハンドラーはスローし、フレームワークがキャッチします — ツールロジック内で try/catch は使用しないでください

  • リクエストスコープのログには ctx.log を、テナントスコープのストレージには ctx.state を使用します

  • 新しいツールは src/index.ts の createApp() 配列に登録します

  • 2 つのホストプローブツールは、それぞれの有効化フラグの背後に登録されます。ネットワークターゲットゲートは DNS 解決後に検証します — 特定不能または到達不能なターゲットに対して結果を捏造しないでください

貢献

Issue とプルリクエストを歓迎します。提出前にチェックとテストを実行してください:

bun run devcheck
bun run test

ライセンス

Apache-2.0 — 詳細は LICENSE を参照してください。

Available Tools

5 tools
toolkit_encode_valuetoolkit-mcp-server: encode valueA
Read-onlyIdempotent
Inspect

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" or "base64" to receive them re-encoded instead, which is lossless for binary data and transcodes between encodings (a base64 digest to hex, 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
valueYesThe value to transform — raw text for encode, an encoded string for decode. Whitespace is ignored when decoding hex, base64, or base64url; a url value is taken literally.
encodingYesThe encoding to apply: base64, URL-safe base64url, hex, or URL percent-encoding.
operationYes"encode" transforms text into the encoding; "decode" recovers the bytes from an encoded value.
outputEncodingNoDecode only: how the recovered bytes are returned. utf8 (used when omitted) returns text and fails when the bytes are not valid UTF-8; hex and base64 return the raw bytes re-encoded, losslessly. Rejected when operation is "encode".

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNoPresent when the call failed. Absent on success.
resultNoThe transformed value: encoded text for encode; for decode, the recovered bytes as UTF-8 text, hex, or base64 per outputEncoding.
encodingNoThe encoding that was applied.
operationNoThe operation that was performed.
outputEncodingNoHow result renders the decoded bytes: utf8 text, hex, or base64. Present for operation "decode".

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes far beyond the readOnlyHint/idempotentHint annotations by disclosing key behavior: decoding never substitutes replacement characters, malformed values produce recoverable errors, whitespace is ignored in certain encodings, base64url uses the URL-safe alphabet, and url uses encodeURIComponent. This is exactly the kind of behavioral context an agent needs beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is longer than average but every sentence carries useful information, including edge cases, error behavior, and encoding-specific details. The first sentence front-loads the core purpose. It is dense rather than redundant, though it could be tightened slightly without losing value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity — four parameters, three enums, two operations, and multiple encoding formats — the description is remarkably complete. It covers error handling, whitespace tolerance, PEM/MIME scenarios, binary data handling, and output format options. With an output schema also present, nothing an agent needs to call and understand this tool is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Even though schema coverage is 100%, the description adds substantial meaning to the parameters: it explains what "decode" returns by default, how outputEncoding enables lossless transcoding, how whitespace handling affects the value parameter, and which alphabet base64url uses. This is meaningful value beyond the schema's enumerated definitions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource combination: "Encode or decode a value across base64, base64url, hex, or URL (percent) encoding, in either direction." This unambiguously identifies the tool's operation and scope, and clearly separates it from siblings like hash_value or generate_id, which perform different transformations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear operational guidance: when to use "encode" vs "decode", and when to set outputEncoding. It also gives practical use cases like decoding base64 digests and PEM bodies. However, it does not explicitly name sibling tools or state when this tool should be preferred over them, though the context is strong enough that an agent can infer appropriate usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

toolkit_generate_idtoolkit-mcp-server: generate idA
Read-only
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNoIdentifier format: uuid_v4 (random), uuid_v7 (time-ordered), or ulid (sortable Crockford-base32).uuid_v4
countNoHow many identifiers to mint (1–1000). The full batch is always returned.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idsNoThe minted identifiers — exactly count of them, in mint order; for uuid_v7 and ulid that order is strictly increasing (sorted by creation), with random gaps between ids minted in the same millisecond.
typeNoThe identifier format that was minted.
countNoThe number of identifiers minted (equals the requested count).
errorNoPresent when the call failed. Absent on success.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, but the description goes far beyond: it discloses the source (platform CSPRNG), output guarantees ('always contains exactly count values and is never truncated'), monotonic ordering for uuid_v7/ulid, strict increasing within the same millisecond, and the security property that 'no id in a batch can be derived from another'. This rich behavioral disclosure is not present in annotations and is critical for correct use.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Each sentence earns its place: purpose and source are front-loaded, then type semantics, batch behavior, ordering guarantees, and downstream integration. There is no fluff or repetition of schema verbatim; the description is dense but well-structured, guiding the agent from conceptual purpose to invocation details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter tool with an output schema and clear annotations, the description fully covers what an agent needs: when to use, format selection, batching limits, return-count guarantees, ordering behavior, and integration with a sibling. No critical information is missing, and the output schema handles return-shape details.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The description adds meaningful semantics beyond the schema: it explains the default (uuid_v4), clarifies each type's ordering properties, specifies 'up to 1000' for count, and introduces the guarantee that the full batch is always returned without truncation. This adds real value over the schema alone, though the schema already covers basic type and count limits.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description opens with 'Mint cryptographically-random identifiers using the platform CSPRNG' — a specific verb ('mint'), resource ('identifiers'), and method (CSPRNG). It distinguishes this tool from siblings by stating it is the correct source for unpredictable IDs and explicitly contrasts with 'model-generated values'. The purpose is unambiguous and differentiates from toolkit_hash_value, toolkit_encode_value, etc.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description says to use this tool when IDs 'must be unpredictable' and indicates 'unlike model-generated values' — an explicit when-not. It also provides a concrete downstream workflow: 'feed into toolkit_generate_qr (pass ids[0] as data)', which acts as a usage directive. Combined with format-selection guidance for type and batching with count, the agent knows exactly when and how to invoke it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

toolkit_generate_qrtoolkit-mcp-server: generate QR codeA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
dataYesThe text or URL to encode, stored as UTF-8. Capacity is counted in bytes: 2953 UTF-8 bytes is the absolute ceiling (QR version 40, level L, byte mode). The 2953-character limit here is only an upper bound, since a non-ASCII character takes 2–4 bytes. Usable capacity drops at higher errorCorrection levels, so over-capacity data is rejected with a typed data_too_large error rather than a generic failure.
scaleNoPixels per module for svg (its width and height) and png_base64. Ignored for terminal. png_base64 also bounds the whole image at 2048 px per side, so a dense symbol or a wide margin admits a lower scale than 32 there.
formatNoOutput format: svg markup, png_base64 (raster bytes), or terminal (plain Unicode half-blocks, drawn for a dark background).svg
marginNoQuiet-zone width in modules around the symbol. The spec recommends 4.
errorCorrectionNoError-correction level: L (~7% recoverable) to H (~30%). Higher tolerance lowers data capacity.M

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNoPresent when the call failed. Absent on success.
formatNoThe format that was produced.
contentNoThe QR artifact: SVG markup, the terminal half-block grid (newline-separated rows), or base64 PNG bytes for png_base64.
versionNoQR symbol version (1–40); higher versions hold denser data and indicate denser content.
mimeTypeNoMIME type of content for image formats. Absent for the terminal format.
byteLengthNoDecoded byte size of the PNG. Present only for png_base64.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint and idempotentHint annotations, the description discloses significant behavioral detail: format-specific output shapes (SVG markup, base64 PNG bytes with mimeType and byteLength, terminal Unicode blocks), typed error conditions (data_too_large, raster_too_large), the pixel-size formula, and the version range reflecting data density. It even clarifies terminal rendering for dark backgrounds. This far exceeds what annotations alone provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is information-dense and front-loaded with the core purpose in the first sentence. Each subsequent sentence introduces a distinct parameter or constraint, and the flow from format to error behavior is logical. It is longer than two sentences, but given the three output formats and several interacting parameters, the length is justified without wasteful repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 5 parameters, 3 formats, and a moderately complex output, the description is thorough: it covers all parameters, format-specific behaviors, encoding boundaries, and error conditions. An output schema exists, so return values are already documented. No critical information an agent needs to invoke the tool correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although the schema already has 100% parameter coverage, the description adds meaningful semantics not present in the schema: how scale and margin combine into final image dimensions, which parameters are ignored by which format, how errorCorrection trades capacity against tolerance, and the pixel limit interaction with scale for png_base64. This elevates the description well above the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Encode text or a URL into a QR code', which clearly states the tool's function. It goes beyond the title by naming concrete use cases (links, generated identifiers, strings) and enumerating the three output formats. Sibling tools like toolkit_encode_value, toolkit_generate_id, and toolkit_hash_value are clearly different in purpose, so an agent can distinguish this tool without confusion.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides rich context for when to use the tool: what kinds of data are acceptable (links, identifiers, arbitrary strings), what each format yields, and how parameters interact. It does not explicitly state when not to use this tool or name alternative siblings for specific scenarios, but the sibling set is distinct enough that the usage is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

toolkit_geolocate_iptoolkit-mcp-server: geolocate IPA
Read-onlyIdempotent
Inspect

Resolve a public IP address (or hostname) to geographic and network metadata: country, region, city, latitude/longitude, the owning ASN and organization, timezone, and the proxy/hosting/mobile quality flags. target accepts an IPv4/IPv6 address or a hostname — a hostname is DNS-resolved first and the resolvedIp field echoes which IP was actually located. The provider is called directly (never the target), so this is SSRF-free and safe to expose anywhere. Results are best-effort and provider-bounded: VPNs, proxies, mobile NAT, and anycast all defeat IP-to-location, accuracy is city-level at best, and many fields can be absent for reserved or thinly-documented ranges — absent fields are reported as unknown, never invented. Read proxy, hosting, and mobile before trusting the coordinates: a true on any of them means the location describes infrastructure, not the user. Private/reserved addresses have no public geolocation and are rejected. The source field names which provider answered.

ParametersJSON Schema
NameRequiredDescriptionDefault
targetYesA public IPv4/IPv6 address or a hostname (e.g. "8.8.8.8" or "example.com").

Output Schema

ParametersJSON Schema
NameRequiredDescription
asnNoAutonomous System number, e.g. "AS15169". Absent on providers that omit it.
orgNoOwning organization or ISP, e.g. "Google LLC". Absent when unknown.
cityNoCity name. Absent when unknown.
errorNoPresent when the call failed. Absent on success.
proxyNoTrue when the address is a known proxy, VPN, or Tor exit — the location describes the exit node, not the user. Absent when the provider does not report it.
mobileNoTrue when the address belongs to a mobile carrier network, where NAT can place the location far from the device. Absent when unreported.
regionNoRegion or state name. Absent when unknown.
sourceNoThe provider that answered the lookup, e.g. "ip-api".
targetNoThe target as supplied (IP or hostname).
countryNoCountry name. Absent when the provider does not report it.
hostingNoTrue when the address belongs to a hosting or datacenter network, so the location is a facility rather than a person. Absent when unreported.
latitudeNoLatitude in decimal degrees. Absent when unknown.
timezoneNoIANA timezone, e.g. "America/Los_Angeles". Absent when unknown.
longitudeNoLongitude in decimal degrees. Absent when unknown.
resolvedIpNoThe IP that was actually located (a supplied hostname is resolved to this first).
countryCodeNoISO 3166-1 alpha-2 country code. Absent when unknown.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With readOnlyHint=true and destructiveHint=false already in annotations, the bar is lower, yet the description still adds real context: the provider is called directly (never the target), so it is safe on untrusted input; accuracy is provider-bounded; behavior on private/reserved ranges is stated; proxy/VPN/mobile flags are defined as reliability warnings; and the source field is disclosed. Nothing contradicts the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

All four sentences are substantive and the operation is stated up front in the first sentence, with caveats and security notes after. No filler. Minor redundancy between 'accuracy is best-effort' and 'VPNs, proxies, anycast...' slightly thins the density, but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-param, read-only tool whose output is not schema-described, the description covers: the input types, DNS resolution behavior, the output fields, the meaning of proxy/mobile flags for reliability, and failure modes (private ranges rejected). An agent has everything needed to call it correctly and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% (the single param is fully defined with three alternates: IPv4, IPv6, hostname). The description adds value beyond the schema by stating that hostnames are DNS-resolved first and that the resolved address is echoed in the response — behavior the schema cannot express. Slightly more caveat detail (e.g., punycode) would push to 5, but coverage is already high.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence states a clear verb-resource pair — resolve a public IP or hostname to a set of geographic and network metadata — and enumerates every returned field, so an agent immediately knows what it does and what it returns. It also carves out scope (public only) that distinguishes it in a toolkit whose other tools are QR, hash, and weather related.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains when results are reliable and when they are not (VPNs, proxies, anycast, mobile NAT, reserved ranges), which is implicit guidance to the caller on trusting the output. It does not explicitly contrast with a sibling geolocation alternative, but the sibling set contains no competing tool, so a 4 is appropriate rather than a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

toolkit_hash_valuetoolkit-mcp-server: hash valueA
Read-onlyIdempotent
Inspect

Generate a cryptographic digest 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 for checksum and file-integrity compatibility ONLY and must not be used for passwords, signatures, or any security purpose. digestEncoding selects the generated digest form: lowercase hex (default), base64, or sri (-, 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 can be pasted as-is; an SRI value may hold several space-separated entries, as an npm integrity field can, and matches when any entry for algorithm does. 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
valueYesThe data to hash, interpreted per inputEncoding (raw text by default).
expectedNoThe digest to compare against, as hex (any case), standard base64, or SRI (<algorithm>-<base64>); the form is recognized from its shape at the algorithm's digest length, and a string of only hex digits is always read as hex. An SRI value may carry several space-separated entries: entries for other algorithms are skipped, and it matches when any entry for algorithm matches. Supplying it with operation omitted runs a compare; it is rejected with operation "generate".
algorithmNoDigest algorithm. sha256 (default), sha384, or sha512 for security; md5/sha1 are checksum/compat only — not for security.sha256
operationNo"generate" produces a digest; "compare" constant-time-checks value against expected. When omitted, resolves to "compare" if expected is supplied and "generate" otherwise.
inputEncodingNoHow value is decoded before hashing: utf8 text, hex, or base64.utf8
digestEncodingNoForm of the generated digest: lowercase hex (default), standard base64, or sri (<algorithm>-<base64>, sha256/sha384/sha512 only). Applies to operation "generate".hex

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNoPresent when the call failed. Absent on success.
digestNoDigest of value in the requested digestEncoding: lowercase hex, base64, or <algorithm>-<base64>. Present for operation "generate".
matchesNoConstant-time equality of the computed digest against expected. Present for operation "compare".
algorithmNoThe algorithm used.
operationNoThe operation performed, after resolving an omitted operation.
lengthInBytesNoDigest size in bytes (32 for sha256, 48 for sha384, 64 for sha512, 20 for sha1, 16 for md5). Present for "generate".

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool as readOnly and idempotent. The description adds meaningful behavioral detail: constant-time comparison, security caveats for weak algorithms, flexible expected-format recognition, and SRI multi-entry matching. These go well beyond the annotations and give the agent a clear model of how the tool behaves without contradicting the structured metadata.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long (~150 words) but every sentence contributes a distinct piece of information: purpose, operation behavior, algorithm security, digest encoding, expected format handling, input encoding, and a canonical use case. It is front-loaded with the core purpose and then systematically covers each nuance. While it could be tightened, the density is justified by the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description need not specify return values. It thoroughly covers all parameters, their defaults, and edge cases (omitted operation, SRI multi-entries, binary input). It does not mention error conditions or limits, but these are minor given the extensive guidance and the presence of structured schemas. Overall, an agent has enough context to invoke this tool correctly in typical scenarios.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so every parameter already has a description. The tool description enriches this by explaining the interaction between operation and expected (omission logic), the shape-based recognition of expected formats, the meaning of SRI, and the rationale for inputEncoding. This adds genuine value beyond the schema's individual property descriptions, making the parameter semantics clearer and more actionable.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a precise statement of both capabilities: 'Generate a cryptographic digest of a value, or verify a value against an expected digest.' It names the verb (generate/verify), the resource (value), and clearly distinguishes the two operations. This is far from a tautology and immediately separates it from sibling tools like encode or generate_id.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides strong contextual guidance: it explains the default operation resolution, warns against using md5/sha1 for security, and gives a canonical use case ('matching a download against a vendor-published checksum or a lockfile integrity entry'). It does not explicitly name alternatives or exclusions, but the unique function makes that less critical. The 'compare is timing-safe and avoids manual string equality checks' also informs when to use this tool over manual comparison.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv2.3.1
    • Changedtoolkit_encode_value7 fields changed
      • changedInput schema / properties / operation / description
        Previous value: -"\"encode\" transforms text into the encoding; \"decode\" recovers text from an encoded value."New value: +"\"encode\" transforms text into the encoding; \"decode\" recovers the bytes from an encoded value."
      • addedInput schema / properties / outputEncoding
        Added value: +{
        +  "description": "Decode only: how the recovered bytes are returned. utf8 (used when omitted) returns text and fails when the bytes are not valid UTF-8; hex and base64 return the raw bytes re-encoded, losslessly. Rejected when operation is \"encode\".",
        +  "enum": [
        +    "utf8",
        +    "hex",
        +    "base64"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / value / description
        Previous value: -"The value to transform — raw text for encode, an encoded string for decode."New value: +"The value to transform — raw text for encode, an encoded string for decode. Whitespace is ignored when decoding hex, base64, or base64url; a url value is taken literally."
      • changedOutput schema / properties / error / properties / data / properties / reason / description
        Previous value: -"Machine-readable failure mode. Declared by this tool: `decode_failed`: operation is \"decode\" but value is malformed for the chosen encoding. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `decode_failed`: operation is \"decode\" but value is malformed for the chosen encoding. `decode_not_utf8`: operation is \"decode\", outputEncoding is utf8 (or omitted), and the decoded bytes are not valid UTF-8 text. `output_encoding_not_applicable`: operation is \"encode\" and outputEncoding was supplied; it selects how decoded bytes are returned. Other values are possible when a failure originates below the handler."
      • changedOutput schema / properties / error / properties / data / properties / reason / examples
        Previous value: -[
        -  "decode_failed"
        -]New value: +[
        +  "decode_failed",
        +  "decode_not_utf8",
        +  "output_encoding_not_applicable"
        +]
      • addedOutput schema / properties / outputEncoding
        Added value: +{
        +  "description": "How result renders the decoded bytes: utf8 text, hex, or base64. Present for operation \"decode\".",
        +  "enum": [
        +    "utf8",
        +    "hex",
        +    "base64"
        +  ],
        +  "type": "string"
        +}
      • changedOutput schema / properties / result / description
        Previous value: -"The transformed value (encoded text, or the decoded original)."New value: +"The transformed value: encoded text for encode; for decode, the recovered bytes as UTF-8 text, hex, or base64 per outputEncoding."
    • Changedtoolkit_generate_id1 field changed
      • changedOutput schema / properties / ids / description
        Previous value: -"The minted identifiers — exactly count of them, in mint order; for uuid_v7 and ulid that order is strictly increasing (sorted by creation)."New value: +"The minted identifiers — exactly count of them, in mint order; for uuid_v7 and ulid that order is strictly increasing (sorted by creation), with random gaps between ids minted in the same millisecond."
    • Changedtoolkit_generate_qr4 fields changed
      • changedInput schema / properties / data / description
        Previous value: -"The text or URL to encode. 2953 is the absolute ceiling (QR version 40, level L, byte mode); usable capacity drops at higher errorCorrection levels, so over-capacity data is rejected with a typed data_too_large error rather than a generic failure."New value: +"The text or URL to encode, stored as UTF-8. Capacity is counted in bytes: 2953 UTF-8 bytes is the absolute ceiling (QR version 40, level L, byte mode). The 2953-character limit here is only an upper bound, since a non-ASCII character takes 2–4 bytes. Usable capacity drops at higher errorCorrection levels, so over-capacity data is rejected with a typed data_too_large error rather than a generic failure."
      • changedInput schema / properties / format / description
        Previous value: -"Output format: svg markup, png_base64 (raster bytes), or a terminal-renderable string."New value: +"Output format: svg markup, png_base64 (raster bytes), or terminal (plain Unicode half-blocks, drawn for a dark background)."
      • changedInput schema / properties / scale / description
        Previous value: -"Pixels per module for raster (png_base64) output. Ignored for terminal. png_base64 also bounds the whole image at 2048 px per side, so a dense symbol or a wide margin admits a lower scale than 32."New value: +"Pixels per module for svg (its width and height) and png_base64. Ignored for terminal. png_base64 also bounds the whole image at 2048 px per side, so a dense symbol or a wide margin admits a lower scale than 32 there."
      • changedOutput schema / properties / content / description
        Previous value: -"The QR artifact: SVG markup, a terminal-renderable string, or base64 PNG bytes for png_base64."New value: +"The QR artifact: SVG markup, the terminal half-block grid (newline-separated rows), or base64 PNG bytes for png_base64."
    • Changedtoolkit_hash_value13 fields changed
      • changedInput schema / properties / algorithm / description
        Previous value: -"Digest algorithm. sha256 (default) or sha512 for security; md5/sha1 are checksum/compat only — not for security."New value: +"Digest algorithm. sha256 (default), sha384, or sha512 for security; md5/sha1 are checksum/compat only — not for security."
      • changedInput schema / properties / algorithm / enum
        Previous value: -[
        -  "sha256",
        -  "sha512",
        -  "sha1",
        -  "md5"
        -]New value: +[
        +  "sha256",
        +  "sha384",
        +  "sha512",
        +  "sha1",
        +  "md5"
        +]
      • addedInput schema / properties / digestEncoding
        Added value: +{
        +  "default": "hex",
        +  "description": "Form of the generated digest: lowercase hex (default), standard base64, or sri (<algorithm>-<base64>, sha256/sha384/sha512 only). Applies to operation \"generate\".",
        +  "enum": [
        +    "hex",
        +    "base64",
        +    "sri"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / expected / description
        Previous value: -"The expected lowercase-hex digest to compare against. Required when operation is \"compare\"."New value: +"The digest to compare against, as hex (any case), standard base64, or SRI (<algorithm>-<base64>); the form is recognized from its shape at the algorithm's digest length, and a string of only hex digits is always read as hex. An SRI value may carry several space-separated entries: entries for other algorithms are skipped, and it matches when any entry for algorithm matches. Supplying it with operation omitted runs a compare; it is rejected with operation \"generate\"."
      • changedInput schema / properties / inputEncoding / description
        Previous value: -"How value (and expected's pre-image, when relevant) is decoded before hashing: utf8 text, hex, or base64."New value: +"How value is decoded before hashing: utf8 text, hex, or base64."
      • removedInput schema / properties / operation / default
        Removed value: -"generate"
      • changedInput schema / properties / operation / description
        Previous value: -"\"generate\" produces a digest; \"compare\" constant-time-checks value against expected."New value: +"\"generate\" produces a digest; \"compare\" constant-time-checks value against expected. When omitted, resolves to \"compare\" if expected is supplied and \"generate\" otherwise."
      • changedOutput schema / properties / algorithm / enum
        Previous value: -[
        -  "sha256",
        -  "sha512",
        -  "sha1",
        -  "md5"
        -]New value: +[
        +  "sha256",
        +  "sha384",
        +  "sha512",
        +  "sha1",
        +  "md5"
        +]
      • changedOutput schema / properties / digest / description
        Previous value: -"Lowercase-hex digest of value. Present for operation \"generate\"."New value: +"Digest of value in the requested digestEncoding: lowercase hex, base64, or <algorithm>-<base64>. Present for operation \"generate\"."
      • changedOutput schema / properties / error / properties / data / properties / reason / description
        Previous value: -"Machine-readable failure mode. Declared by this tool: `missing_expected`: operation is \"compare\" but no expected digest was supplied. `expected_length_mismatch`: The expected digest length does not match the algorithm, so compare would always fail. `invalid_input_encoding`: value is not valid for the declared inputEncoding (e.g. non-hex characters with inputEncoding \"hex\"). Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `missing_expected`: operation is \"compare\" but no expected digest was supplied. `expected_without_compare`: operation is \"generate\" but an expected digest was also supplied, so it would be ignored. `expected_malformed`: expected is not a hex, standard base64, or sha256/sha384/sha512 SRI digest, or an SRI value holds a token that is not an SRI entry. `expected_length_mismatch`: expected is a recognized digest form but its length does not match the algorithm, so compare would always fail. `expected_algorithm_mismatch`: expected is SRI and none of its entries names the chosen algorithm. `sri_unsupported_algorithm`: digestEncoding is \"sri\" and algorithm is md5 or sha1, which SRI does not define. `invalid_input_encoding`: value is not valid for the declared inputEncoding (e.g. non-hex characters with inputEncoding \"hex\"). Other values are possible when a failure originates below the handler."
      • changedOutput schema / properties / error / properties / data / properties / reason / examples
        Previous value: -[
        -  "missing_expected",
        -  "expected_length_mismatch",
        -  "invalid_input_encoding"
        -]New value: +[
        +  "missing_expected",
        +  "expected_without_compare",
        +  "expected_malformed",
        +  "expected_length_mismatch",
        +  "expected_algorithm_mismatch",
        +  "sri_unsupported_algorithm",
        +  "invalid_input_encoding"
        +]
      • changedOutput schema / properties / lengthInBytes / description
        Previous value: -"Digest size in bytes (32 for sha256, 64 for sha512, 20 for sha1, 16 for md5). Present for \"generate\"."New value: +"Digest size in bytes (32 for sha256, 48 for sha384, 64 for sha512, 20 for sha1, 16 for md5). Present for \"generate\"."
      • changedOutput schema / properties / operation / description
        Previous value: -"The operation performed."New value: +"The operation performed, after resolving an omitted operation."
  2. 5 tool updatesv2.2.2
    • Changedtoolkit_encode_value6 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedInput schema / additionalProperties
        Added value: +false
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedOutput schema / anyOf
        Added value: +[
        +  {
        +    "not": {
        +      "required": [
        +        "error"
        +      ]
        +    },
        +    "required": [
        +      "encoding",
        +      "operation",
        +      "result"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "error"
        +    ]
        +  }
        +]
      • addedOutput schema / properties / error
        Added value: +{
        +  "additionalProperties": {},
        +  "description": "Present when the call failed. Absent on success.",
        +  "properties": {
        +    "code": {
        +      "description": "JSON-RPC error code for this failure.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "data": {
        +      "additionalProperties": {},
        +      "properties": {
        +        "reason": {
        +          "description": "Machine-readable failure mode. Declared by this tool: `decode_failed`: operation is \"decode\" but value is malformed for the chosen encoding. Other values are possible when a failure originates below the handler.",
        +          "examples": [
        +            "decode_failed"
        +          ],
        +          "type": "string"
        +        },
        +        "recovery": {
        +          "additionalProperties": {},
        +          "description": "Actionable next step for the caller.",
        +          "properties": {
        +            "hint": {
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "hint"
        +          ],
        +          "type": "object"
        +        },
        +        "retryable": {
        +          "description": "Whether retrying may succeed.",
        +          "type": "boolean"
        +        }
        +      },
        +      "type": "object"
        +    },
        +    "message": {
        +      "description": "Human-readable description of what went wrong.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "code",
        +    "message"
        +  ],
        +  "type": "object"
        +}
      • removedOutput schema / required
        Removed value: -[
        -  "encoding",
        -  "operation",
        -  "result"
        -]
    • Changedtoolkit_generate_id6 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedInput schema / additionalProperties
        Added value: +false
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedOutput schema / anyOf
        Added value: +[
        +  {
        +    "not": {
        +      "required": [
        +        "error"
        +      ]
        +    },
        +    "required": [
        +      "type",
        +      "ids",
        +      "count"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "error"
        +    ]
        +  }
        +]
      • addedOutput schema / properties / error
        Added value: +{
        +  "additionalProperties": {},
        +  "description": "Present when the call failed. Absent on success.",
        +  "properties": {
        +    "code": {
        +      "description": "JSON-RPC error code for this failure.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "data": {
        +      "additionalProperties": {},
        +      "properties": {
        +        "reason": {
        +          "description": "Machine-readable failure mode.",
        +          "type": "string"
        +        },
        +        "recovery": {
        +          "additionalProperties": {},
        +          "description": "Actionable next step for the caller.",
        +          "properties": {
        +            "hint": {
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "hint"
        +          ],
        +          "type": "object"
        +        },
        +        "retryable": {
        +          "description": "Whether retrying may succeed.",
        +          "type": "boolean"
        +        }
        +      },
        +      "type": "object"
        +    },
        +    "message": {
        +      "description": "Human-readable description of what went wrong.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "code",
        +    "message"
        +  ],
        +  "type": "object"
        +}
      • removedOutput schema / required
        Removed value: -[
        -  "type",
        -  "ids",
        -  "count"
        -]
    • Changedtoolkit_generate_qr6 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedInput schema / additionalProperties
        Added value: +false
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedOutput schema / anyOf
        Added value: +[
        +  {
        +    "not": {
        +      "required": [
        +        "error"
        +      ]
        +    },
        +    "required": [
        +      "format",
        +      "content",
        +      "version"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "error"
        +    ]
        +  }
        +]
      • addedOutput schema / properties / error
        Added value: +{
        +  "additionalProperties": {},
        +  "description": "Present when the call failed. Absent on success.",
        +  "properties": {
        +    "code": {
        +      "description": "JSON-RPC error code for this failure.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "data": {
        +      "additionalProperties": {},
        +      "properties": {
        +        "reason": {
        +          "description": "Machine-readable failure mode. Declared by this tool: `data_too_large`: data exceeds the QR capacity for the chosen errorCorrection level and encoding mode. `raster_too_large`: format is png_base64 and (modules + 2 × margin) × scale exceeds the pixel budget. Other values are possible when a failure originates below the handler.",
        +          "examples": [
        +            "data_too_large",
        +            "raster_too_large"
        +          ],
        +          "type": "string"
        +        },
        +        "recovery": {
        +          "additionalProperties": {},
        +          "description": "Actionable next step for the caller.",
        +          "properties": {
        +            "hint": {
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "hint"
        +          ],
        +          "type": "object"
        +        },
        +        "retryable": {
        +          "description": "Whether retrying may succeed.",
        +          "type": "boolean"
        +        }
        +      },
        +      "type": "object"
        +    },
        +    "message": {
        +      "description": "Human-readable description of what went wrong.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "code",
        +    "message"
        +  ],
        +  "type": "object"
        +}
      • removedOutput schema / required
        Removed value: -[
        -  "format",
        -  "content",
        -  "version"
        -]
    • Changedtoolkit_geolocate_ip6 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedInput schema / additionalProperties
        Added value: +false
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedOutput schema / anyOf
        Added value: +[
        +  {
        +    "not": {
        +      "required": [
        +        "error"
        +      ]
        +    },
        +    "required": [
        +      "target",
        +      "resolvedIp",
        +      "source"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "error"
        +    ]
        +  }
        +]
      • addedOutput schema / properties / error
        Added value: +{
        +  "additionalProperties": {},
        +  "description": "Present when the call failed. Absent on success.",
        +  "properties": {
        +    "code": {
        +      "description": "JSON-RPC error code for this failure.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "data": {
        +      "additionalProperties": {},
        +      "properties": {
        +        "reason": {
        +          "description": "Machine-readable failure mode. Declared by this tool: `unresolvable_host`: A hostname target failed DNS resolution. `private_target`: The target resolves to a private/reserved IP with no public geolocation. Other values are possible when a failure originates below the handler.",
        +          "examples": [
        +            "unresolvable_host",
        +            "private_target"
        +          ],
        +          "type": "string"
        +        },
        +        "recovery": {
        +          "additionalProperties": {},
        +          "description": "Actionable next step for the caller.",
        +          "properties": {
        +            "hint": {
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "hint"
        +          ],
        +          "type": "object"
        +        },
        +        "retryable": {
        +          "description": "Whether retrying may succeed.",
        +          "type": "boolean"
        +        }
        +      },
        +      "type": "object"
        +    },
        +    "message": {
        +      "description": "Human-readable description of what went wrong.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "code",
        +    "message"
        +  ],
        +  "type": "object"
        +}
      • removedOutput schema / required
        Removed value: -[
        -  "target",
        -  "resolvedIp",
        -  "source"
        -]
    • Changedtoolkit_hash_value6 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedInput schema / additionalProperties
        Added value: +false
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedOutput schema / anyOf
        Added value: +[
        +  {
        +    "not": {
        +      "required": [
        +        "error"
        +      ]
        +    },
        +    "required": [
        +      "algorithm",
        +      "operation"
        +    ]
        +  },
        +  {
        +    "required": [
        +      "error"
        +    ]
        +  }
        +]
      • addedOutput schema / properties / error
        Added value: +{
        +  "additionalProperties": {},
        +  "description": "Present when the call failed. Absent on success.",
        +  "properties": {
        +    "code": {
        +      "description": "JSON-RPC error code for this failure.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "data": {
        +      "additionalProperties": {},
        +      "properties": {
        +        "reason": {
        +          "description": "Machine-readable failure mode. Declared by this tool: `missing_expected`: operation is \"compare\" but no expected digest was supplied. `expected_length_mismatch`: The expected digest length does not match the algorithm, so compare would always fail. `invalid_input_encoding`: value is not valid for the declared inputEncoding (e.g. non-hex characters with inputEncoding \"hex\"). Other values are possible when a failure originates below the handler.",
        +          "examples": [
        +            "missing_expected",
        +            "expected_length_mismatch",
        +            "invalid_input_encoding"
        +          ],
        +          "type": "string"
        +        },
        +        "recovery": {
        +          "additionalProperties": {},
        +          "description": "Actionable next step for the caller.",
        +          "properties": {
        +            "hint": {
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "hint"
        +          ],
        +          "type": "object"
        +        },
        +        "retryable": {
        +          "description": "Whether retrying may succeed.",
        +          "type": "boolean"
        +        }
        +      },
        +      "type": "object"
        +    },
        +    "message": {
        +      "description": "Human-readable description of what went wrong.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "code",
        +    "message"
        +  ],
        +  "type": "object"
        +}
      • removedOutput schema / required
        Removed value: -[
        -  "algorithm",
        -  "operation"
        -]
  3. 2 tool updatesv2.2.0
    • Changedtoolkit_generate_qr1 field changed
      • changedInput schema / properties / scale / description
        Previous value: -"Pixels per module for raster (png_base64) output. Ignored for terminal."New value: +"Pixels per module for raster (png_base64) output. Ignored for terminal. png_base64 also bounds the whole image at 2048 px per side, so a dense symbol or a wide margin admits a lower scale than 32."
    • Changedtoolkit_geolocate_ip10 fields changed
      • addedOutput schema / properties / asn / maxLength
        Added value: +256
      • addedOutput schema / properties / city / maxLength
        Added value: +256
      • addedOutput schema / properties / country / maxLength
        Added value: +256
      • addedOutput schema / properties / countryCode / maxLength
        Added value: +256
      • addedOutput schema / properties / hosting
        Added value: +{
        +  "description": "True when the address belongs to a hosting or datacenter network, so the location is a facility rather than a person. Absent when unreported.",
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / mobile
        Added value: +{
        +  "description": "True when the address belongs to a mobile carrier network, where NAT can place the location far from the device. Absent when unreported.",
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / org / maxLength
        Added value: +256
      • addedOutput schema / properties / proxy
        Added value: +{
        +  "description": "True when the address is a known proxy, VPN, or Tor exit — the location describes the exit node, not the user. Absent when the provider does not report it.",
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / region / maxLength
        Added value: +256
      • addedOutput schema / properties / timezone / maxLength
        Added value: +256
  4. 2 tool updatesv2.0.1
    • Changedtoolkit_generate_id1 field changed
      • changedOutput schema / properties / ids / description
        Previous value: -"The minted identifiers — exactly count of them, in mint order."New value: +"The minted identifiers — exactly count of them, in mint order; for uuid_v7 and ulid that order is strictly increasing (sorted by creation)."
    • Changedtoolkit_generate_qr1 field changed
      • changedInput schema / properties / data / description
        Previous value: -"The text or URL to encode. Capped at 2953 bytes — the absolute QR capacity (version 40, level L)."New value: +"The text or URL to encode. 2953 is the absolute ceiling (QR version 40, level L, byte mode); usable capacity drops at higher errorCorrection levels, so over-capacity data is rejected with a typed data_too_large error rather than a generic failure."
  5. 21 tool updatesv2.0.0
    • RemovedcheckConnectivity
    • RemovedclearGeoCache
    • RemovedcompareHashes
    • RemovedconvertTimezone
    • RemovedgenerateQRCode
    • RemovedgenerateUUID
    • Removedgeolocate
    • RemovedgetCurrentTime
    • RemovedgetLoadAverage
    • RemovedgetNetworkInterfaces
    • RemovedgetPublicIP
    • RemovedgetSystemInfo
    • RemovedhashData
    • RemovedlistTimezones
    • RemovedpingHost
    • Addedtoolkit_encode_value
    • Addedtoolkit_generate_id
    • Addedtoolkit_generate_qr
    • Addedtoolkit_geolocate_ip
    • Addedtoolkit_hash_value
    • Removedtraceroute
  6. 16 tool updates
    • First observedcheckConnectivity
    • First observedclearGeoCache
    • First observedcompareHashes
    • First observedconvertTimezone
    • First observedgenerateQRCode
    • First observedgenerateUUID
    • First observedgeolocate
    • First observedgetCurrentTime
    • First observedgetLoadAverage
    • First observedgetNetworkInterfaces
    • First observedgetPublicIP
    • First observedgetSystemInfo
    • First observedhashData
    • First observedlistTimezones
    • First observedpingHost
    • First observedtraceroute

TDQS

A4.7/5.0

Scored across 5 tools

Disambiguation5/5

Each tool serves a clearly distinct purpose: QR generation, hashing, ID generation, encoding/decoding, and IP geolocation. There is no overlap or possibility of confusion between tools. Descriptions are detailed and unambiguous.

Naming Consistency5/5

All tools use the consistent 'toolkit_' prefix with snake_case names following a verb_noun pattern (generate_qr, hash_value, generate_id, encode_value, geolocate_ip). The naming is predictable and uniform across the entire set.

Tool Count5/5

With 5 tools, the server is well-scoped for a general-purpose toolkit. Each tool is substantial and earns its place, covering a broad range of utility functions without redundancy. The count is neither thin nor bloated.

Completeness4/5

The toolkit covers a solid variety of utility categories (generation, hashing, encoding, geolocation), but lacks common text/data manipulation features like string transformation or JSON handling. The core workflows within each tool are complete, with no dead ends, though the breadth could be broader for a general toolkit.

Maintenance

ActivityMaintained
ResponsivenessWithin a week

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A 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.
    65 npm
    2
    MIT
  • A
    license
    B
    quality
    F
    maintenance
    A 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.
    100
    98 npm
    22
    TypeScript
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    A 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
    -