Skip to main content
Glama
IPGeolocation

IPGeolocation MCP Server

Bulk IP Geolocation

bulk_lookup_ip
Read-only

Read-only bulk IP lookup via POST /v3/ipgeo-bulk. Documented as paid-only; the upstream API determines plan access. Base IP data costs 1 credit per valid IP; security adds 2 and abuse adds 1.

Instructions

Read-only bulk IP lookup via POST /v3/ipgeo-bulk. Documented as paid-only; the upstream API determines plan access. Base IP data costs 1 credit per valid IP; security adds 2 and abuse adds 1. Selecting only security costs 2, only abuse costs 1, and security plus abuse without base data costs 3 per valid IP. This MCP server accepts up to 250 IPs per request. Larger batches are rejected before any API call. Complete results are returned directly or as cached pages. Oversized results contain page.next_cursor for complete retrieval through get_cached_result without another API call or additional credits.

The response covers location data or mixed IP data domains for multiple IPs or domains. Private, bogon, and malformed IPs are not billed. fields, excludes, lang, and include behave like lookup_ip for each item; this server also infers include modules from fields. bulk_security_check provides dedicated security-only batch responses.

Input Schema

NameRequiredDescriptionDefault
ipsYesArray of IPv4 and/or IPv6 addresses to look up. Minimum 1, maximum 250 in this MCP server. Domain names are also accepted.
langNoResponse language code (en, de, ru, ja, fr, cn, es, cs, it, ko, fa, pt). Defaults to en.
fieldsNoComma-separated dot-path fields to return per IP (e.g. location.city,asn.organization). Reduces response size and can reduce credit cost when combined with include. Fields under security or abuse auto-add that module. location.accuracy_radius/confidence/locality auto-add geo_accuracy; location.dma_code auto-adds dma_code. Optional modules require a paid plan.
includeNoComma-separated extra modules to include per IP. Options: security (+2 credits/IP), abuse (+1 credit/IP), hostname, liveHostname, hostnameFallbackLive, user_agent, geo_accuracy, dma_code, or * for all (4 credits/IP total).
excludesNoComma-separated dot-path fields to exclude per IP (e.g. currency,time_zone).
force_refreshNoDefault false. When true, bypasses cached bulk geolocation data; a successful refresh makes a new upstream request and can consume credits.

Output Schema

NameRequiredDescriptionDefault
pageNo
errorNoPresent when the whole tool call fails, with isError: true.
itemsNoPresent on success: complete API results in input order, including any per-item error messages.
errorsNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changedv2.0.3
    • removedOutput schema / properties / items / items / additionalProperties / anyOf
      Removed value: -[
      -  {
      -    "type": "null"
      -  },
      -  {
      -    "type": "boolean"
      -  },
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "array"
      -  },
      -  {
      -    "type": "object"
      -  }
      -]
    • addedOutput schema / properties / items / items / additionalProperties / type
      Added value: +[
      +  "null",
      +  "boolean",
      +  "number",
      +  "string",
      +  "array",
      +  "object"
      +]
  2. Changed5 schema fields changedv2.0.1
    • addedInput schema / additionalProperties
      Added value: +false
    • changedInput schema / properties / fields / description
      Previous value: -"Comma-separated dot-path fields to return per IP (e.g. location.city,asn.organization). Reduces response size and can reduce credit cost when combined with include. If fields reference include-only modules (for example security.* or abuse.*), this server auto-adds required include modules."New value: +"Comma-separated dot-path fields to return per IP (e.g. location.city,asn.organization). Reduces response size and can reduce credit cost when combined with include. Fields under security or abuse auto-add that module. location.accuracy_radius/confidence/locality auto-add geo_accuracy; location.dma_code auto-adds dma_code. Optional modules require a paid plan."
    • changedInput schema / properties / ips / description
      Previous value: -"Array of IPv4 and/or IPv6 addresses to look up. Minimum 1, maximum 1,000 in this MCP server. Domain names are also accepted."New value: +"Array of IPv4 and/or IPv6 addresses to look up. Minimum 1, maximum 250 in this MCP server. Domain names are also accepted."
    • changedInput schema / properties / ips / maxItems
      Previous value: -1000New value: +250
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": false,
      +  "properties": {
      +    "error": {
      +      "additionalProperties": false,
      +      "description": "Present when the whole tool call fails, with isError: true.",
      +      "properties": {
      +        "assistant_guidance": {
      +          "type": "string"
      +        },
      +        "category": {
      +          "type": "string"
      +        },
      +        "documented_status": {
      +          "type": "boolean"
      +        },
      +        "explanation_hint": {
      +          "type": "string"
      +        },
      +        "guidance": {
      +          "type": "string"
      +        },
      +        "message": {
      +          "type": "string"
      +        },
      +        "retryable": {
      +          "type": "boolean"
      +        },
      +        "source": {
      +          "enum": [
      +            "mcp_server",
      +            "ipgeolocation_api"
      +          ],
      +          "type": "string"
      +        },
      +        "status": {
      +          "maximum": 9007199254740991,
      +          "minimum": -9007199254740991,
      +          "type": "integer"
      +        }
      +      },
      +      "required": [
      +        "source",
      +        "category",
      +        "message",
      +        "retryable",
      +        "guidance",
      +        "assistant_guidance"
      +      ],
      +      "type": "object"
      +    },
      +    "errors": {
      +      "items": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "category": {
      +            "const": "upstream_item",
      +            "type": "string"
      +          },
      +          "guidance": {
      +            "type": "string"
      +          },
      +          "input": {
      +            "type": "string"
      +          },
      +          "input_index": {
      +            "maximum": 9007199254740991,
      +            "minimum": 0,
      +            "type": "integer"
      +          },
      +          "message": {
      +            "type": "string"
      +          },
      +          "retryable": {
      +            "type": "boolean"
      +          },
      +          "source": {
      +            "const": "ipgeolocation_api",
      +            "type": "string"
      +          },
      +          "status": {
      +            "description": "Present only when the API supplied an item HTTP status.",
      +            "maximum": 9007199254740991,
      +            "minimum": -9007199254740991,
      +            "type": "integer"
      +          }
      +        },
      +        "required": [
      +          "input_index",
      +          "input",
      +          "source",
      +          "category",
      +          "message",
      +          "retryable",
      +          "guidance"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "items": {
      +      "description": "Present on success: complete API results in input order, including any per-item error messages.",
      +      "items": {
      +        "additionalProperties": {
      +          "anyOf": [
      +            {
      +              "type": "null"
      +            },
      +            {
      +              "type": "boolean"
      +            },
      +            {
      +              "type": "number"
      +            },
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "array"
      +            },
      +            {
      +              "type": "object"
      +            }
      +          ]
      +        },
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "page": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "cursor": {
      +          "description": "Opaque cursor returned in page.cursor or page.next_cursor. Retrieval requires the same server process and API key and does not repeat the original lookup.",
      +          "maxLength": 80,
      +          "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}:\\d{1,16}$",
      +          "type": "string"
      +        },
      +        "expires_at": {
      +          "description": "ISO timestamp for idle expiry. Successful page reads extend the cache TTL; eviction or process restart can also remove the result.",
      +          "type": "string"
      +        },
      +        "format": {
      +          "const": "structuredContent_json",
      +          "type": "string"
      +        },
      +        "json_fragment": {
      +          "description": "JSON fragment of the original structuredContent. Fragments concatenate in offset order into the complete JSON, including bulk items and errors.",
      +          "type": "string"
      +        },
      +        "next_cursor": {
      +          "description": "Cursor for the next get_cached_result page, absent on the last page. Page reads never call the API or consume credits.",
      +          "maxLength": 80,
      +          "pattern": "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}:\\d{1,16}$",
      +          "type": "string"
      +        },
      +        "offset": {
      +          "maximum": 9007199254740991,
      +          "minimum": 0,
      +          "type": "integer"
      +        },
      +        "source_tool": {
      +          "type": "string"
      +        },
      +        "total_chars": {
      +          "maximum": 9007199254740991,
      +          "minimum": 0,
      +          "type": "integer"
      +        }
      +      },
      +      "required": [
      +        "source_tool",
      +        "format",
      +        "json_fragment",
      +        "offset",
      +        "total_chars",
      +        "cursor",
      +        "expires_at"
      +      ],
      +      "type": "object"
      +    }
      +  },
      +  "type": "object"
      +}
  3. Changed2 schema fields changedv2.0.0
    • removedInput schema / additionalProperties
      Removed value: -false
    • changedInput schema / properties / force_refresh / description
      Previous value: -"Default false. Set true only when the user asks to bypass cached bulk geolocation data; a successful refresh makes a new upstream request and can consume credits."New value: +"Default false. When true, bypasses cached bulk geolocation data; a successful refresh makes a new upstream request and can consume credits."
  4. Changed1 schema field changedv1.0.15
    • changedInput schema / properties / force_refresh / description
      Previous value: -"Default false. Leave unset unless the user asks to refresh or rerun."New value: +"Default false. Set true only when the user asks to bypass cached bulk geolocation data; a successful refresh makes a new upstream request and can consume credits."
  5. First observedv1.0.10

TDQS

A4.6/5.0
Behavior5/5

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

Annotations only declare readOnlyHint and openWorldHint; the description adds substantial context beyond them — per-IP credit math for base/security/abuse combinations, the hard 250-item pre-flight rejection, cached pagination via page.next_cursor, and that fetching oversized pages through get_cached_result costs no additional API call or credits. It even qualifies the read-only hint by noting force_refresh can consume credits.

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?

Key facts (bulk scope, 250 limit, credit cost, pagination) are front-loaded and the alternative tool is named at the end. The credit-cost breakdown is somewhat repetitive, restating base/security/abuse pricing twice, and the sentence about 'location data or mixed IP data domains' is diffuse, but nothing is truly wasted.

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

Completeness5/5

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

For a 6-parameter, credit-metered bulk tool with an output schema, the description covers everything an agent needs to call it correctly: input ceiling, rejection behavior, cost model, plan gating, pagination escape hatch, and sibling routing. Return-value structure is correctly left to the output schema.

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 the baseline is 3; the description earns more by adding cross-parameter meaning the schema only hints at — that it infers include modules from fields (e.g. security/abuse dot-paths auto-add modules) and that fields+include combinations can reduce credit cost. This tells the agent how to combine parameters economically, not just what each one is.

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, and mode ('Read-only bulk IP lookup via POST /v3/ipgeo-bulk'), immediately separating it from the single-item lookup_ip sibling. It also names bulk_security_check as the dedicated alternative for security-only batches, so an agent can route without opening a schema.

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 concrete operating conditions: up to 250 IPs per request, larger batches rejected before any API call, paid-plan gating determined upstream, and private/bogon/malformed IPs not billed. It names bulk_security_check as the alternative for security-only work, but never explicitly says when to fall back to lookup_ip for single addresses, leaving that inference to the agent.

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