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

Öffentlich gehosteter Server: https://toolkit.caseyjhand.com/mcp


Tools

Sieben Tools. Fünf sind dauerhaft aktiv und benötigen keine Konfiguration – reine Rechenwerkzeuge plus eine SSRF-freie IP-Suche. Zwei prüfen den Server-Host und bleiben so lange ohne Eintrag in tools/list, bis Sie sie aktivieren; sie sind fail-closed.

Tool

Description

toolkit_hash_value

Erzeugt einen kryptografischen Digest (sha256/sha512/sha1/md5) oder vergleicht einen Wert in konstanter Zeit mit einem erwarteten Digest.

toolkit_generate_id

Erzeugt kryptografisch zufällige Bezeichner – UUIDv4, UUIDv7 oder ULID – einzeln oder in Stapeln bis zu 1000.

toolkit_generate_qr

Kodiert Text oder eine URL in einen QR-Code als SVG-Markup, base64-PNG oder eine im Terminal darstellbare Zeichenfolge.

toolkit_encode_value

Kodiert oder dekodiert einen Wert in base64, base64url, hex oder URL-Prozentkodierung, in beide Richtungen.

toolkit_geolocate_ip

Löst eine öffentliche IP oder einen Hostnamen in geografische und Netzwerk-Metadaten auf – Land, Stadt, Koordinaten, ASN, Zeitzone.

toolkit_check_network

Per Flag freigeschaltet, standardmäßig deaktiviert. Schreibgeschützte Netzwerkdiagnosen vom Server-Host – Ping, Traceroute, TCP-Verbindung oder Egress-IP-Erkennung.

toolkit_check_system

Per Flag freigeschaltet, standardmäßig deaktiviert. Meldet einen Aspekt des Systemzustands des Server-Hosts – OS, CPU, Speicher, Lastdurchschnitt oder Netzwerkschnittstellen.

toolkit_hash_value

Erzeugt einen Digest oder verifiziert einen Wert in konstanter Zeit gegen einen erwarteten.

  • operation: generate (Digest in Kleinbuchstaben-Hex) oder compare (zeitlich sicherer Vergleich über timingSafeEqual)

  • Algorithmen: sha256 (Standard) und sha512 für Sicherheit; sha1 und md5 sind nur für Prüfsummen- und Dateiintegritätskompatibilität verfügbar – niemals für Passwörter oder Signaturen

  • inputEncoding liest value als utf8 (Standard), hex oder base64, sodass binäre Blobs einen Decodier-Roundtrip überspringen

  • Kanonischer Anwendungsfall: einen Download gegen eine vom Anbieter veröffentlichte Prüfsumme prüfen


toolkit_generate_id

Erzeugt kryptografisch zufällige Bezeichner aus dem CSPRNG der Plattform – die richtige Quelle für IDs, die unvorhersehbar sein müssen, anders als von Modellen erfundene Werte.

  • type: uuid_v4 (zufällig, Standard), uuid_v7 (zeitlich geordnet, nach Erstellung sortierbar) oder ulid (26 Zeichen Crockford-Basis32, lexikografisch sortierbar)

  • count erzeugt einen Stapel bis zu 1000 in einem Aufruf; das zurückgegebene ids-Array enthält immer genau count Werte

  • uuid_v7- und ulid-Stapel sind monoton – selbst innerhalb derselben Millisekunde streng steigend – sodass ids in sortierter Erstellungsreihenfolge bleibt

  • Schreibgeschützt – das Erzeugen ändert nichts – aber niemals idempotent, sodass ein Client einen Stapel nicht zwischenspeichert oder dedupliziert


toolkit_generate_qr

Kodiert Text oder eine URL in einen QR-Code.

  • format: svg (Inline-Markup), png_base64 (Rasterbytes mit mimeType und byteLength) oder terminal (Unicode-Blockzeichenfolge)

  • errorCorrection (L/M/Q/H) tauscht Datenkapazität gegen Schadenstoleranz; margin legt die Breite der Ruhezone fest; scale legt Pixel pro Modul für die Rasterausgabe fest

  • Die zurückgegebene version (1–40) spiegelt wider, wie dicht die kodierten Daten sind

  • png_base64 wird außerdem als MCP-Bildinhaltsblock geliefert, sodass ein Client, der content[] liest, den Code rendern kann, ohne structuredContent zu dekodieren

  • Ein gerendertes PNG ist auf 2048 px pro Seite begrenzt — (modules + 2 × margin) × scale — daher wird ein dichtes Symbol bei hohem scale mit einem typisierten raster_too_large-Fehler abgelehnt, der einen passenden scale-Wert nennt; svg und terminal sind unbegrenzt

  • data ist auf 2953 Bytes begrenzt — die absolute Obergrenze (Version 40, Stufe L, Bytemodus); die nutzbare Kapazität ist bei höheren errorCorrection-Stufen geringer, sodass übermäßige Eingaben mit einem typisierten data_too_large-Fehler statt mit einem allgemeinen Fehler abgelehnt werden


toolkit_encode_value

Kodiert oder dekodiert einen Wert in beide Richtungen.

  • encoding: base64, base64url (URL-sicheres Alphabet), hex oder url (Prozentkodierung)

  • operation: encode (rohes UTF-8 → Kodierung) oder decode (kodierter Wert → Text)

  • Fehlerhafte Decodierungseingabe gibt einen typisierten decode_failed-Fehler mit einem Wiederherstellungshinweis zurück, keine stillschweigende Best-Effort-Lösung


toolkit_geolocate_ip

Löst eine öffentliche IP oder einen Hostnamen in geografische und Netzwerk-Metadaten auf.

  • Gibt Land, Region, Stadt, Breiten-/Längengrad, ASN, besitzende Organisation und Zeitzone zurück

  • proxy, hosting und mobile kennzeichnen, ob die Adresse ein Proxy/VPN/Tor-Ausgang, ein Rechenzentrumsnetzwerk oder ein mobiler Träger ist – ein true bei einem von ihnen bedeutet, dass die Koordinaten Infrastruktur beschreiben, nicht eine Person. Fehlt, wenn der Anbieter sie nicht meldet

  • Ein Hostname wird zuerst per DNS aufgelöst; resolvedIp gibt die tatsächlich geortete IP wieder, und source nennt den antwortenden Anbieter

  • SSRF-frei – der Server ruft den Anbieter auf, niemals das Ziel; die aufgelöste IP wird erneut gegen private Bereiche geprüft, und private/reservierte Adressen werden abgelehnt (sie haben keine öffentliche Geolokalisierung)

  • Best-Effort und durch den Anbieter begrenzt: VPNs, Proxys, mobiles NAT und Anycast verhindern alle eine IP-zu-Standort-Zuordnung; die Genauigkeit ist bestenfalls auf Stadtebene, und fehlende Felder werden als unbekannt statt erfunden gemeldet

  • Vom Anbieter gelieferte Zeichenfolgen werden gekürzt und von Steuerzeichen befreit, bevor sie in die Antwort gelangen, sodass von der Registry kontrollierter Text (org, isp, as) den Kontext eines Modells nicht überfluten oder formatieren kann

  • Standardmäßig schlüssellos (ip-api-Kostenlostarif, der Klartext-HTTP verwendet – siehe TOOLKIT_GEO_BASE_URL); Ergebnisse werden im Speicher nach aufgelöster IP unter einer festen Eintragsobergrenze zwischengespeichert


toolkit_check_network

Per Flag freigeschaltet – wird nur registriert, wenn TOOLKIT_ENABLE_NET_DIAGNOSTICS=true gesetzt ist. Schreibgeschützte Netzwerkdiagnosen vom Server-Host.

  • mode: ping (ICMP-Roundtrip), traceroute (Hop-Pfad zum Ziel), connectivity (rohe TCP-Verbindung zu target auf port) oder public_ip (die eigene Egress-IP des Hosts)

  • Ein Host, der nicht antwortet, wird als reachable: false gemeldet — ein gültiges Ergebnis, kein Fehler

  • Diagnostiziert das eigene Netzwerk des Servers, daher ist es bei einer lokalen oder selbst gehosteten Bereitstellung nützlich; das Erreichen eines privaten/reservierten/internen Ziels erfordert zusätzlich TOOLKIT_ALLOW_PRIVATE_NETWORK=true, wodurch der Cloud-Metadaten-Endpunkt standardmäßig blockiert bleibt


toolkit_check_system

Per Flag freigeschaltet – wird nur registriert, wenn TOOLKIT_ENABLE_SYSTEM_INFO=true gesetzt ist. Meldet einen Aspekt des Systemzustands des Server-Hosts, schreibgeschützt.

  • what: os, cpu, memory, load oder interfaces

  • Pro Aufruf wird genau ein Facettenobjekt entsprechend what befüllt

  • Beschreibt den Host, auf dem dieser Server läuft, nicht den aufrufenden Client – sinnvoll bei einer lokalen oder selbst gehosteten Bereitstellung; standardmäßig deaktiviert, weil os und interfaces Host-Topologie und Versionsdetails offenlegen

Related MCP server: IT Tools MCP Server

Funktionen

Basiert auf @cyanheads/mcp-ts-core:

  • Deklarative Tool-Definitionen – eine Datei pro Tool, das Framework übernimmt Registrierung und Validierung

  • Einheitliche Fehlerbehandlung – Handler werfen, das Framework fängt, klassifiziert und formatiert

  • Typisierte Fehlerverträge – jedes fehleranfällige Tool deklariert seine Fehlerursachen mit Wiederherstellungshinweisen, auf die der Agent reagieren kann

  • Plugbare Authentifizierung: none, jwt, oauth

  • Strukturierte Protokollierung mit optionalem OpenTelemetry-Tracing

  • STDIO- und Streamable-HTTP-Transports

Toolkit-spezifisch:

  • Fail-closed-Gating – die beiden Host-prüfenden Tools fehlen in tools/list, sofern sie nicht explizit aktiviert werden, sodass eine gehostete Instanz keine SSRF- oder Informationsoffenlegungsfläche bietet

  • Zweistufiges Netzwerk-Gate – selbst bei aktivierten Diagnosen bleiben private/reservierte/Loopback-/Link-Local-Ziele (einschließlich des Cloud-Metadaten-Endpunkts) blockiert, bis ein zweites Flag sie erlaubt

  • CSPRNG-gestützte Primitive – Bezeichner und Digests stammen aus der Krypto-Quelle der Plattform, und der Hash-Vergleich erfolgt in konstanter Zeit über timingSafeEqual

  • SSRF-freie Geolokalisierung – der Server ruft den Anbieter auf und prüft die DNS-aufgelöste IP vor der Abfrage erneut gegen private Bereiche, sodass ein Hostname keine Anfrage an eine interne Adresse schmuggeln kann

Agentenfreundliche Ausgabe:

  • Herkunft – Geolokalisierung gibt die aufgelöste IP wieder und nennt den antwortenden Anbieter; fehlende vorgelagerte Felder werden als unbekannt gemeldet, nie erfunden

  • Nicht erreichbar, aber gültige Ergebnisse – ein nicht erreichbarer Host gibt reachable: false statt eines Fehlers zurück, sodass Aufrufer anhand von Daten verzweigen, nicht anhand von Ausnahmetext

  • Typisierte Fehlerursachen – Dekodierungsfehler, fehlende Digests und blockierte private Ziele tragen jeweils eine strukturierte Ursache plus einen Hinweis für den nächsten Wiederherstellungsschritt

Erste Schritte

Öffentlich gehostete Instanz

Eine öffentliche Instanz ist unter https://toolkit.caseyjhand.com/mcp verfügbar – keine Installation erforderlich. Richten Sie einen beliebigen MCP-Client per Streamable HTTP darauf aus:

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

Selbst gehostet / Lokal

Fügen Sie Folgendes zur Konfigurationsdatei Ihres MCP-Clients hinzu. Kein API-Schlüssel erforderlich – die fünf dauerhaft aktiven Tools und die standardmäßige schlüssellose Geolokalisierungsstufe funktionieren sofort.

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

Oder mit npx (kein Bun erforderlich):

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

Oder mit 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"]
    }
  }
}

Um die per Flag freigeschalteten Host-prüfenden Tools zu aktivieren, fügen Sie ihre Flags zu env (oder -e bei Docker) hinzu:

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

Für Streamable HTTP setzen Sie den Transport und starten Sie den Server:

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

Voraussetzungen

  • Bun v1.3.2 oder höher (oder Node.js v24+).

  • Kein API-Schlüssel erforderlich – die Geolokalisierung nutzt standardmäßig den schlüssellosen ip-api-Kostenlostarif.

Installation

  1. Klonen Sie das Repository:

git clone https://github.com/cyanheads/toolkit-mcp-server.git
  1. Wechseln Sie in das Verzeichnis:

cd toolkit-mcp-server
  1. Installieren Sie die Abhängigkeiten:

bun install

Konfiguration

Jede Variable ist optional. Serverspezifische Optionen werden beim Start über das Zod-Schema in src/config/server-config.ts validiert.

Variable

Beschreibung

Standard

TOOLKIT_ENABLE_NET_DIAGNOSTICS

Registriert das gesperrte Tool toolkit_check_network. Für gehostete oder gemeinsam genutzte Bereitstellungen weglassen.

false

TOOLKIT_ENABLE_SYSTEM_INFO

Registriert das gesperrte Tool toolkit_check_system. Nur bei einer lokalen oder selbst gehosteten Bereitstellung sinnvoll.

false

TOOLKIT_ALLOW_PRIVATE_NETWORK

Bei aktivierter Netzwerkdiagnose erlaubt private/reservierte/Loopback-Ziele. Die zweite explizite Absicherung.

false

TOOLKIT_GEO_API_KEY

API-Schlüssel für den Geodienst-Endpunkt, falls erforderlich.

Keiner

TOOLKIT_GEO_BASE_URL

Basis-URL für einen ip-api-kompatiblen Geodienst-Endpunkt. Der Standard ist Klartext-HTTP – der HTTPS-Endpunkt von ip-api ist nicht Teil des schlüssellosen Free-Tarifs und antwortet ohne einen kostenpflichtigen Schlüssel mit 403 SSL unavailable for this endpoint. Leite dies auf einen HTTPS-Endpunkt um (mit TOOLKIT_GEO_API_KEY), um die Anforderung an den Anbieter zu verschlüsseln.

http://ip-api.com

TOOLKIT_GEO_CACHE_TTL_SECONDS

TTL des Geodienst-Caches im Arbeitsspeicher in Sekunden.

3600

TOOLKIT_GEO_RATE_LIMIT_PER_MIN

Maximale Anzahl von Geodienst-Anfragen pro Minute.

45

MCP_TRANSPORT_TYPE

Transport: stdio oder http.

stdio

MCP_HTTP_PORT

Port für den HTTP-Server.

3010

MCP_AUTH_MODE

Authentifizierungsmodus: none, jwt oder oauth.

none

MCP_LOG_LEVEL

Log-Level (RFC 5424).

info

OTEL_ENABLED

Aktiviere OpenTelemetry-Instrumentierung (Spans, Metriken, Fertigstellungsprotokolle).

false

Siehe .env.example für die vollständige Liste optionaler Überschreibungen.

Ausführen des Servers

Lokale Entwicklung

  • Erstellen und ausführen:

    # One-time build
    bun run rebuild
    
    # Run the built server
    bun run start:stdio
    # or
    bun run start:http
  • Checks und Tests ausführen:

    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

Das Dockerfile verwendet standardmäßig HTTP-Transport, zustandslosen Sitzungsmodus und protokolliert nach /var/log/toolkit-mcp-server. OpenTelemetry-Peer-Abhängigkeiten werden standardmäßig installiert – erstelle mit --build-arg OTEL_ENABLED=false, um sie wegzulassen.

Projektstruktur

Verzeichnis

Zweck

src/index.ts

Einstiegspunkt createApp() – registriert Tools und initialisiert Dienste, mit Fail-Closed-Absicherung für die beiden Host-Überprüfungs-Tools.

src/config

Serverspezifische Umgebungsvariablen-Analyse und -Validierung mit Zod.

src/mcp-server/tools

Tool-Definitionen (*.tool.ts). Sieben Tools – fünf immer aktiv, zwei gesperrt.

src/services/geo

Geodienst – DNS-Auflösung, Anbieteraufruf mit Wiederholungs-/Backoff-Logik, Normalisierung, In-Memory-Cache.

src/services/network

Netzwerkdiagnose-Dienst plus der gemeinsame Ziel-Validator und der Klassifikator für private Bereiche.

tests/

Unit- und Integrationstests, die die src/-Struktur widerspiegeln.

Entwicklungsleitfaden

Siehe CLAUDE.md / AGENTS.md für Entwicklungsrichtlinien und Architekturregeln. Die Kurzfassung:

  • Handler werfen Fehler, das Framework fängt sie – kein try/catch in der Tool-Logik

  • Verwende ctx.log für anforderungsbezogenes Logging, ctx.state für mandantenbezogenen Speicher

  • Registriere neue Tools in den createApp()-Arrays in src/index.ts

  • Die beiden Host-Überprüfungs-Tools registrieren sich hinter ihren Aktivierungsflags; die Netzwerkziel-Absicherung validiert nach der DNS-Auflösung – fabriziere niemals ein Ergebnis für ein nicht auffindbares oder nicht erreichbares Ziel

Mitwirken

Issues und Pull-Requests sind willkommen. Führe Checks und Tests vor dem Einreichen aus:

bun run devcheck
bun run test

Lizenz

Apache-2.0 – siehe LICENSE für Details.

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.

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

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.

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

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.

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

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 or dotted hostname to country, region, city, coordinates, ASN, organization, timezone, and proxy/hosting/mobile flags. Supply target for one lookup or targets for an ordered batch, never both; blank target and empty targets are unset. Batches process the first 100 positions (duplicates retained) and disclose every remainder in unprocessedTargets; at most 1000 inputs are accepted. Each batch position reports its result or an error with recovery, so cached and local outcomes survive quota refusals. The provider is called directly, never the target. Hostnames are DNS-resolved and resolvedIp names the located address. Private/reserved addresses have no public geolocation. Results are best-effort, city-level at best; VPNs, proxies, mobile NAT, and anycast defeat IP-to-location. Read proxy, hosting, and mobile before trusting coordinates: true describes infrastructure, not the user. Absent metadata remains unknown. source names the provider. Single and batch quotas are independent; cache hits consume neither quota.

NameRequiredDescriptionDefault
targetNoOne public IP or dotted hostname; mutually exclusive with nonempty targets.
targetsNoOrdered public IPs or dotted hostnames; first 100 positions are served, every remainder is disclosed. Mutually exclusive with nonblank target.

Output 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.
resultsNoOrdered results or failures for the first 100 input positions.
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.
failedCountNoNumber of failed processed targets.
unprocessedTargetsNoEvery input position past the first 100; resubmit these targets in another batch.

TDQS

A4.4/5.0
Behavior5/5

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

Annotations only declare readOnly/openWorld/idempotent; the description adds substantial behavior the annotations cannot convey: batches serve the first 100 positions (duplicates retained) and disclose the rest in unprocessedTargets, a 1000-input cap, per-position errors with recovery, independent single/batch quotas, cache hits consuming neither quota, and most importantly that the provider is called directly and never the target. It also states that private/reserved addresses have no public geolocation and that absent metadata stays unknown.

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?

A single dense paragraph of roughly nine sentences, but the purpose and input-mode rules are front-loaded and each subsequent sentence carries non-redundant content (limits, quota behavior, accuracy caveats). It would benefit from light structuring, yet almost every sentence earns its place given the tool's complexity.

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?

An output schema exists, so return-value documentation is not required, yet the description still names the fields and explains source/resolvedIp semantics. Combined with quota rules, batch limits, mutual exclusivity, and accuracy caveats, an agent has everything needed to call this correctly and interpret results.

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

Parameters3/5

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

Schema description coverage is 100%, so the two parameters are already fully documented, including mutual exclusivity and the blank-means-unset semantics. The description reinforces those points and adds one detail not in the schema (duplicates retained in a batch), but it adds little syntax or format meaning beyond what the schema provides, so the baseline 3 is appropriate.

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?

Opens with a specific verb+resource ("Resolve a public IP or dotted hostname") and enumerates exactly what is returned: country, region, city, coordinates, ASN, organization, timezone, and proxy/hosting/mobile flags. The sibling tools (generate_qr, hash_value, encode_value, generate_id) are unrelated utilities, so no sibling disambiguation is needed and none is missing.

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?

Gives clear operating rules: use target for one lookup or targets for a batch, never both; blank/empty values are treated as unset. It also supplies interpretation guidance ("Read proxy, hosting, and mobile before trusting coordinates") and warns that VPNs, proxies, mobile NAT, and anycast defeat IP-to-location. No alternative tool exists to route to, so the only gap is the absence of explicit when-not scenarios beyond the accuracy caveats.

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.

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

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. 1 tool updatev2.3.3
    • Changedtoolkit_geolocate_ip10 fields changed
      • changedInput schema / properties / target / anyOf
        Previous value: -[
        -  {
        -    "description": "A raw IPv4 address.",
        -    "format": "ipv4",
        -    "pattern": "^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$",
        -    "type": "string"
        -  },
        -  {
        -    "description": "A raw IPv6 address.",
        -    "format": "ipv6",
        -    "pattern": "^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$",
        -    "type": "string"
        -  },
        -  {
        -    "description": "A dotted hostname, e.g. \"example.com\".",
        -    "pattern": "^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$",
        -    "type": "string"
        -  }
        -]New value: +[
        +  {
        +    "description": "Blank means unset.",
        +    "pattern": "^\\s*$",
        +    "type": "string"
        +  },
        +  {
        +    "description": "A raw IPv4 address.",
        +    "format": "ipv4",
        +    "pattern": "^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$",
        +    "type": "string"
        +  },
        +  {
        +    "description": "A raw IPv6 address.",
        +    "format": "ipv6",
        +    "pattern": "^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$",
        +    "type": "string"
        +  },
        +  {
        +    "description": "A dotted hostname, e.g. \"example.com\".",
        +    "pattern": "^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$",
        +    "type": "string"
        +  }
        +]
      • changedInput schema / properties / target / description
        Previous value: -"A public IPv4/IPv6 address or a hostname (e.g. \"8.8.8.8\" or \"example.com\")."New value: +"One public IP or dotted hostname; mutually exclusive with nonempty targets."
      • addedInput schema / properties / targets
        Added value: +{
        +  "description": "Ordered public IPs or dotted hostnames; first 100 positions are served, every remainder is disclosed. Mutually exclusive with nonblank target.",
        +  "items": {
        +    "anyOf": [
        +      {
        +        "description": "A raw IPv4 address.",
        +        "format": "ipv4",
        +        "pattern": "^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$",
        +        "type": "string"
        +      },
        +      {
        +        "description": "A raw IPv6 address.",
        +        "format": "ipv6",
        +        "pattern": "^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$",
        +        "type": "string"
        +      },
        +      {
        +        "description": "A dotted hostname, e.g. \"example.com\".",
        +        "pattern": "^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$",
        +        "type": "string"
        +      }
        +    ],
        +    "description": "A public IPv4/IPv6 address or a hostname (e.g. \"8.8.8.8\" or \"example.com\")."
        +  },
        +  "maxItems": 1000,
        +  "type": "array"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "target"
        -]
      • changedOutput schema / anyOf
        Previous value: -[
        -  {
        -    "not": {
        -      "required": [
        -        "error"
        -      ]
        -    },
        -    "required": [
        -      "target",
        -      "resolvedIp",
        -      "source"
        -    ]
        -  },
        -  {
        -    "required": [
        -      "error"
        -    ]
        -  }
        -]New value: +[
        +  {
        +    "not": {
        +      "required": [
        +        "error"
        +      ]
        +    }
        +  },
        +  {
        +    "required": [
        +      "error"
        +    ]
        +  }
        +]
      • changedOutput schema / properties / error / properties / data / properties / reason / description
        Previous value: -"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."New value: +"Machine-readable failure mode. Declared by this tool: `rate_limited`: The endpoint request quota or provider cooldown is exhausted. `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."
      • changedOutput schema / properties / error / properties / data / properties / reason / examples
        Previous value: -[
        -  "unresolvable_host",
        -  "private_target"
        -]New value: +[
        +  "rate_limited",
        +  "unresolvable_host",
        +  "private_target"
        +]
      • addedOutput schema / properties / failedCount
        Added value: +{
        +  "description": "Number of failed processed targets.",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / results
        Added value: +{
        +  "description": "Ordered results or failures for the first 100 input positions.",
        +  "items": {
        +    "anyOf": [
        +      {
        +        "additionalProperties": false,
        +        "description": "Normalized geolocation metadata for one target.",
        +        "properties": {
        +          "asn": {
        +            "description": "Autonomous System number, e.g. \"AS15169\". Absent on providers that omit it.",
        +            "maxLength": 256,
        +            "type": "string"
        +          },
        +          "city": {
        +            "description": "City name. Absent when unknown.",
        +            "maxLength": 256,
        +            "type": "string"
        +          },
        +          "country": {
        +            "description": "Country name. Absent when the provider does not report it.",
        +            "maxLength": 256,
        +            "type": "string"
        +          },
        +          "countryCode": {
        +            "description": "ISO 3166-1 alpha-2 country code. Absent when unknown.",
        +            "maxLength": 256,
        +            "type": "string"
        +          },
        +          "hosting": {
        +            "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"
        +          },
        +          "latitude": {
        +            "description": "Latitude in decimal degrees. Absent when unknown.",
        +            "type": "number"
        +          },
        +          "longitude": {
        +            "description": "Longitude in decimal degrees. Absent when unknown.",
        +            "type": "number"
        +          },
        +          "mobile": {
        +            "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"
        +          },
        +          "org": {
        +            "description": "Owning organization or ISP, e.g. \"Google LLC\". Absent when unknown.",
        +            "maxLength": 256,
        +            "type": "string"
        +          },
        +          "proxy": {
        +            "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"
        +          },
        +          "region": {
        +            "description": "Region or state name. Absent when unknown.",
        +            "maxLength": 256,
        +            "type": "string"
        +          },
        +          "resolvedIp": {
        +            "description": "The IP that was actually located (a supplied hostname is resolved to this first).",
        +            "type": "string"
        +          },
        +          "source": {
        +            "description": "The provider that answered the lookup, e.g. \"ip-api\".",
        +            "type": "string"
        +          },
        +          "target": {
        +            "description": "The target as supplied (IP or hostname).",
        +            "type": "string"
        +          },
        +          "timezone": {
        +            "description": "IANA timezone, e.g. \"America/Los_Angeles\". Absent when unknown.",
        +            "maxLength": 256,
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "target",
        +          "resolvedIp",
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "additionalProperties": false,
        +        "description": "A failed batch target with recovery guidance.",
        +        "properties": {
        +          "error": {
        +            "additionalProperties": false,
        +            "description": "Failure for this input position.",
        +            "properties": {
        +              "message": {
        +                "description": "Server-authored failure message.",
        +                "type": "string"
        +              },
        +              "reason": {
        +                "description": "Why this target could not be located.",
        +                "enum": [
        +                  "unresolvable_host",
        +                  "private_target",
        +                  "rate_limited",
        +                  "provider_unavailable"
        +                ],
        +                "type": "string"
        +              },
        +              "recovery": {
        +                "additionalProperties": false,
        +                "description": "Recovery guidance for the failed target.",
        +                "properties": {
        +                  "hint": {
        +                    "description": "How to recover this target lookup.",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "hint"
        +                ],
        +                "type": "object"
        +              },
        +              "waitTimeSeconds": {
        +                "description": "Seconds to wait before retrying a rate-limited target.",
        +                "type": "number"
        +              }
        +            },
        +            "required": [
        +              "reason",
        +              "message",
        +              "recovery"
        +            ],
        +            "type": "object"
        +          },
        +          "target": {
        +            "description": "The failed target as supplied.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "target",
        +          "error"
        +        ],
        +        "type": "object"
        +      }
        +    ],
        +    "description": "Result or failure for one input position."
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / unprocessedTargets
        Added value: +{
        +  "description": "Every input position past the first 100; resubmit these targets in another batch.",
        +  "items": {
        +    "description": "One unprocessed target.",
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
  2. 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."
  3. 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"
        -]
  4. 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
  5. 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."
  6. 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
  7. 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 targets a distinct utility: QR generation, cryptographic hashing, IP geolocation, encoding/decoding, and ID generation. There is no functional overlap that would cause misselection, and selectors like hash vs encode are clearly separated by purpose.

Naming Consistency5/5

All tools follow a consistent toolkit_<verb>_<noun> pattern (generate_qr, hash_value, geolocate_ip, encode_value, generate_id). Verb choices are predictable and readable throughout.

Tool Count5/5

Five tools is a well-scoped set for a miscellaneous utility toolkit. Each tool earns its place as an independent, non-redundant capability.

Completeness4/5

Each tool internally covers its operation well (e.g., hash generate/compare, encode/decode both directions, batch geolocation, batched ID minting). As a general 'toolkit' there is no canonical lifecycle to fully satisfy, but minor adjacent utilities (e.g., timestamp/date formatting) are absent.

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.
    39 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
    124 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
    -