toolkit-mcp-server

Generate IDs, QR codes, and hashes, encode values, geolocate IPs, plus gated host diagnostics.

사용해야 할까요

품질 및 안전성

A
설명 품질
100%
스키마 완전성
94%
이름 품질
80%
오염 위험
100%
권한 일치
100%
프로토콜 준수
100%

도구 정의와 프로토콜 준수에 대한 자동 분석을 기반으로 합니다.

컨텍스트 비용

~5,581토큰 (도구 정의)
~10.2 KB일반적인 응답 크기
상당한 주의 영향 (128k 컨텍스트의 4.36%)

이는 서버의 도구가 모델의 컨텍스트에 로드될 때마다 소비되는 대략적인 토큰 수입니다. 수치가 높을수록 다른 작업에 사용할 수 있는 주의가 줄어듭니다.

설치

원클릭 설치

`claude_desktop_config.json` 파일에 다음을 추가하세요:

{
  "mcpServers": {
    "toolkit-mcp-server": {
      "command": "bun",
      "args": [
        "@cyanheads/toolkit-mcp-server"
      ]
    }
  }
}

실행 가능한 패키지

npm@cyanheads/toolkit-mcp-server2.3.1streamable-http

원격 엔드포인트

https://toolkit.caseyjhand.com/mcpstreamable-http

할 수 있는 일

도구 목록

도구 (5)

🟢 읽기 전용🟡 쓰기🔴 삭제⚪ 알 수 없음
🟢toolkit_hash_value(operation, value, algorithm, digestEncoding, expected, ...)

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 (<algorithm>-<base64>, the npm lockfile integrity and Subresource Integrity form, sha256/sha384/sha512 only). expected is accepted as hex, base64, or SRI, recognized by its shape at the algorithm's digest length, so a published checksum 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.

입력 스키마

{
  "type": "object",
  "properties": {
    "operation": {
      "description": "\"generate\" produces a digest; \"compare\" constant-time-checks value against expected. When omitted, resolves to \"compare\" if expected is supplied and \"generate\" otherwise.",
      "type": "string",
      "enum": [
        "generate",
        "compare"
      ]
    },
    "value": {
      "type": "string",
      "description": "The data to hash, interpreted per inputEncoding (raw text by default)."
    },
    "algorithm": {
      "default": "sha256",
      "description": "Digest algorithm. sha256 (default), sha384, or sha512 for security; md5/sha1 are checksum/compat only — not for security.",
      "type": "string",
      "enum": [
        "sha256",
        "sha384",
        "sha512",
        "sha1",
        "md5"
      ]
    },
    "digestEncoding": {
      "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\".",
      "type": "string",
      "enum": [
        "hex",
        "base64",
        "sri"
      ]
    },
    "expected": {
      "description": "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\".",
      "type": "string"
    },
    "inputEncoding": {
      "default": "utf8",
      "description": "How value is decoded before hashing: utf8 text, hex, or base64.",
      "type": "string",
      "enum": [
        "utf8",
        "hex",
        "base64"
      ]
    }
  },
  "required": [
    "value"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "additionalProperties": false
}

출력 스키마

{
  "type": "object",
  "properties": {
    "algorithm": {
      "type": "string",
      "enum": [
        "sha256",
        "sha384",
        "sha512",
        "sha1",
        "md5"
      ],
      "description": "The algorithm used."
    },
    "operation": {
      "type": "string",
      "enum": [
        "generate",
        "compare"
      ],
      "description": "The operation performed, after resolving an omitted operation."
    },
    "digest": {
      "description": "Digest of value in the requested digestEncoding: lowercase hex, base64, or <algorithm>-<base64>. Present for operation \"generate\".",
      "type": "string"
    },
    "matches": {
      "description": "Constant-time equality of the computed digest against expected. Present for operation \"compare\".",
      "type": "boolean"
    },
    "lengthInBytes": {
      "description": "Digest size in bytes (32 for sha256, 48 for sha384, 64 for sha512, 20 for sha1, 16 for md5). Present for \"generate\".",
      "type": "number"
    },
    "error": {
      "description": "Present when the call failed. Absent on success.",
      "type": "object",
      "properties": {
        "code": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "description": "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.",
              "examples": [
                "missing_expected",
                "expected_without_compare",
                "expected_malformed",
                "expected_length_mismatch",
                "expected_algorithm_mismatch",
                "sri_unsupported_algorithm",
                "invalid_input_encoding"
              ]
            },
            "recovery": {
              "description": "Actionable next step for the caller.",
              "type": "object",
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "required": [
                "hint"
              ],
              "additionalProperties": {}
            },
            "retryable": {
              "description": "Whether retrying may succeed.",
              "type": "boolean"
            }
          },
          "additionalProperties": {}
        }
      },
      "required": [
        "code",
        "message"
      ],
      "additionalProperties": {}
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "additionalProperties": false,
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "algorithm",
        "operation"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ]
}
🟢toolkit_generate_id(type, count)

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.

입력 스키마

{
  "type": "object",
  "properties": {
    "type": {
      "default": "uuid_v4",
      "description": "Identifier format: uuid_v4 (random), uuid_v7 (time-ordered), or ulid (sortable Crockford-base32).",
      "type": "string",
      "enum": [
        "uuid_v4",
        "uuid_v7",
        "ulid"
      ]
    },
    "count": {
      "default": 1,
      "description": "How many identifiers to mint (1–1000). The full batch is always returned.",
      "type": "integer",
      "minimum": 1,
      "maximum": 1000
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "additionalProperties": false
}

출력 스키마

{
  "type": "object",
  "properties": {
    "type": {
      "type": "string",
      "enum": [
        "uuid_v4",
        "uuid_v7",
        "ulid"
      ],
      "description": "The identifier format that was minted."
    },
    "ids": {
      "type": "array",
      "items": {
        "type": "string",
        "description": "A single minted identifier."
      },
      "description": "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."
    },
    "count": {
      "type": "number",
      "description": "The number of identifiers minted (equals the requested count)."
    },
    "error": {
      "description": "Present when the call failed. Absent on success.",
      "type": "object",
      "properties": {
        "code": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "description": "Machine-readable failure mode."
            },
            "recovery": {
              "description": "Actionable next step for the caller.",
              "type": "object",
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "required": [
                "hint"
              ],
              "additionalProperties": {}
            },
            "retryable": {
              "description": "Whether retrying may succeed.",
              "type": "boolean"
            }
          },
          "additionalProperties": {}
        }
      },
      "required": [
        "code",
        "message"
      ],
      "additionalProperties": {}
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "additionalProperties": false,
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "type",
        "ids",
        "count"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ]
}
🟢toolkit_generate_qr(data, format, errorCorrection, margin, scale)

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.

입력 스키마

{
  "type": "object",
  "properties": {
    "data": {
      "type": "string",
      "minLength": 1,
      "maxLength": 2953,
      "description": "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."
    },
    "format": {
      "default": "svg",
      "description": "Output format: svg markup, png_base64 (raster bytes), or terminal (plain Unicode half-blocks, drawn for a dark background).",
      "type": "string",
      "enum": [
        "svg",
        "png_base64",
        "terminal"
      ]
    },
    "errorCorrection": {
      "default": "M",
      "description": "Error-correction level: L (~7% recoverable) to H (~30%). Higher tolerance lowers data capacity.",
      "type": "string",
      "enum": [
        "L",
        "M",
        "Q",
        "H"
      ]
    },
    "margin": {
      "default": 4,
      "description": "Quiet-zone width in modules around the symbol. The spec recommends 4.",
      "type": "integer",
      "minimum": 0,
      "maximum": 20
    },
    "scale": {
      "default": 4,
      "description": "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.",
      "type": "integer",
      "minimum": 1,
      "maximum": 32
    }
  },
  "required": [
    "data"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "additionalProperties": false
}

출력 스키마

{
  "type": "object",
  "properties": {
    "format": {
      "type": "string",
      "enum": [
        "svg",
        "png_base64",
        "terminal"
      ],
      "description": "The format that was produced."
    },
    "content": {
      "type": "string",
      "description": "The QR artifact: SVG markup, the terminal half-block grid (newline-separated rows), or base64 PNG bytes for png_base64."
    },
    "mimeType": {
      "description": "MIME type of content for image formats. Absent for the terminal format.",
      "type": "string",
      "enum": [
        "image/svg+xml",
        "image/png"
      ]
    },
    "byteLength": {
      "description": "Decoded byte size of the PNG. Present only for png_base64.",
      "type": "number"
    },
    "version": {
      "type": "number",
      "description": "QR symbol version (1–40); higher versions hold denser data and indicate denser content."
    },
    "error": {
      "description": "Present when the call failed. Absent on success.",
      "type": "object",
      "properties": {
        "code": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "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"
              ]
            },
            "recovery": {
              "description": "Actionable next step for the caller.",
              "type": "object",
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "required": [
                "hint"
              ],
              "additionalProperties": {}
            },
            "retryable": {
              "description": "Whether retrying may succeed.",
              "type": "boolean"
            }
          },
          "additionalProperties": {}
        }
      },
      "required": [
        "code",
        "message"
      ],
      "additionalProperties": {}
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "additionalProperties": false,
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "format",
        "content",
        "version"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ]
}
🟢toolkit_encode_value(operation, encoding, value, outputEncoding)

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.

입력 스키마

{
  "type": "object",
  "properties": {
    "operation": {
      "type": "string",
      "enum": [
        "encode",
        "decode"
      ],
      "description": "\"encode\" transforms text into the encoding; \"decode\" recovers the bytes from an encoded value."
    },
    "encoding": {
      "type": "string",
      "enum": [
        "base64",
        "base64url",
        "hex",
        "url"
      ],
      "description": "The encoding to apply: base64, URL-safe base64url, hex, or URL percent-encoding."
    },
    "value": {
      "type": "string",
      "description": "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."
    },
    "outputEncoding": {
      "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\".",
      "type": "string",
      "enum": [
        "utf8",
        "hex",
        "base64"
      ]
    }
  },
  "required": [
    "operation",
    "encoding",
    "value"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "additionalProperties": false
}

출력 스키마

{
  "type": "object",
  "properties": {
    "encoding": {
      "type": "string",
      "enum": [
        "base64",
        "base64url",
        "hex",
        "url"
      ],
      "description": "The encoding that was applied."
    },
    "operation": {
      "type": "string",
      "enum": [
        "encode",
        "decode"
      ],
      "description": "The operation that was performed."
    },
    "outputEncoding": {
      "description": "How result renders the decoded bytes: utf8 text, hex, or base64. Present for operation \"decode\".",
      "type": "string",
      "enum": [
        "utf8",
        "hex",
        "base64"
      ]
    },
    "result": {
      "type": "string",
      "description": "The transformed value: encoded text for encode; for decode, the recovered bytes as UTF-8 text, hex, or base64 per outputEncoding."
    },
    "error": {
      "description": "Present when the call failed. Absent on success.",
      "type": "object",
      "properties": {
        "code": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "description": "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.",
              "examples": [
                "decode_failed",
                "decode_not_utf8",
                "output_encoding_not_applicable"
              ]
            },
            "recovery": {
              "description": "Actionable next step for the caller.",
              "type": "object",
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "required": [
                "hint"
              ],
              "additionalProperties": {}
            },
            "retryable": {
              "description": "Whether retrying may succeed.",
              "type": "boolean"
            }
          },
          "additionalProperties": {}
        }
      },
      "required": [
        "code",
        "message"
      ],
      "additionalProperties": {}
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "additionalProperties": false,
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "encoding",
        "operation",
        "result"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ]
}
🟢toolkit_geolocate_ip(target)

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

입력 스키마

{
  "type": "object",
  "properties": {
    "target": {
      "anyOf": [
        {
          "type": "string",
          "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])$",
          "description": "A raw IPv4 address."
        },
        {
          "type": "string",
          "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}|:))$",
          "description": "A raw IPv6 address."
        },
        {
          "type": "string",
          "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])?)+$",
          "description": "A dotted hostname, e.g. \"example.com\"."
        }
      ],
      "description": "A public IPv4/IPv6 address or a hostname (e.g. \"8.8.8.8\" or \"example.com\")."
    }
  },
  "required": [
    "target"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "additionalProperties": false
}

출력 스키마

{
  "type": "object",
  "properties": {
    "target": {
      "type": "string",
      "description": "The target as supplied (IP or hostname)."
    },
    "resolvedIp": {
      "type": "string",
      "description": "The IP that was actually located (a supplied hostname is resolved to this first)."
    },
    "country": {
      "description": "Country name. Absent when the provider does not report it.",
      "type": "string",
      "maxLength": 256
    },
    "countryCode": {
      "description": "ISO 3166-1 alpha-2 country code. Absent when unknown.",
      "type": "string",
      "maxLength": 256
    },
    "region": {
      "description": "Region or state name. Absent when unknown.",
      "type": "string",
      "maxLength": 256
    },
    "city": {
      "description": "City name. Absent when unknown.",
      "type": "string",
      "maxLength": 256
    },
    "latitude": {
      "description": "Latitude in decimal degrees. Absent when unknown.",
      "type": "number"
    },
    "longitude": {
      "description": "Longitude in decimal degrees. Absent when unknown.",
      "type": "number"
    },
    "asn": {
      "description": "Autonomous System number, e.g. \"AS15169\". Absent on providers that omit it.",
      "type": "string",
      "maxLength": 256
    },
    "org": {
      "description": "Owning organization or ISP, e.g. \"Google LLC\". Absent when unknown.",
      "type": "string",
      "maxLength": 256
    },
    "timezone": {
      "description": "IANA timezone, e.g. \"America/Los_Angeles\". Absent when unknown.",
      "type": "string",
      "maxLength": 256
    },
    "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"
    },
    "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"
    },
    "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"
    },
    "source": {
      "type": "string",
      "description": "The provider that answered the lookup, e.g. \"ip-api\"."
    },
    "error": {
      "description": "Present when the call failed. Absent on success.",
      "type": "object",
      "properties": {
        "code": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "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"
              ]
            },
            "recovery": {
              "description": "Actionable next step for the caller.",
              "type": "object",
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "required": [
                "hint"
              ],
              "additionalProperties": {}
            },
            "retryable": {
              "description": "Whether retrying may succeed.",
              "type": "boolean"
            }
          },
          "additionalProperties": {}
        }
      },
      "required": [
        "code",
        "message"
      ],
      "additionalProperties": {}
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "additionalProperties": false,
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "target",
        "resolvedIp",
        "source"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ]
}

커뮤니티

이 서버 평가하기

증거

최근 관측

검증됨버전이 기록되지 않음도구 5개
검증됨버전이 기록되지 않음도구 5개