bulk_lookup_ip
Perform geolocation lookups for multiple IP addresses or domains simultaneously, supporting up to 1,000 addresses per request with optional security and abuse detection modules.
Instructions
Bulk IP lookup via POST /v3/ipgeo-bulk. Paid only. Cost: 1 credit per IP for base geolocation. This MCP server accepts up to 1,000 IPs per request.
Use it when multiple IPs need location or mixed IP domains. Include modules such as security or abuse add their normal per-IP credit costs. For bulk security-only checks, prefer bulk_security_check.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| ips | Yes | Array of IPv4 and/or IPv6 addresses to look up. Minimum 1, maximum 1,000 in this MCP server. Domain names are also accepted. | |
| lang | No | Response language code (en, de, ru, ja, fr, cn, es, cs, it, ko, fa, pt). Defaults to en. | |
| include | No | Comma-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). | |
| fields | No | 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. | |
| excludes | No | Comma-separated dot-path fields to exclude per IP (e.g. currency,time_zone). | |
| force_refresh | No | Default false. Leave unset unless the user asks to refresh or rerun. |
Implementation Reference
- src/tools/geolocation.ts:347-381 (handler)The handler function for 'bulk_lookup_ip' which fetches bulk IP geolocation data using 'getIpGeolocationBulk' and includes optional modules.
async (params) => { try { const effectiveInclude = mergeLookupIpInclude( params.include, params.fields ); const cacheKey = buildBulkIpGeoCacheKey({ ips: params.ips, lang: params.lang, include: effectiveInclude, fields: params.fields, excludes: params.excludes, }); const cached = params.force_refresh ? undefined : getCachedValue(cacheKey); const result = cached ?? (await getIpGeolocationBulk({ ...params, include: effectiveInclude, })); if (cached === undefined) { setCachedValue(cacheKey, result); } return { content: [ { type: "text" as const, text: formatToolResult(result) }, ], }; } catch (error) { return errorToolResponse(error); } } ); - src/tools/geolocation.ts:300-346 (registration)The registration of the 'bulk_lookup_ip' tool with its title, description, and input schema.
"bulk_lookup_ip", { title: "Bulk IP Geolocation", annotations: { readOnlyHint: true, }, description: `Bulk IP lookup via POST /v3/ipgeo-bulk. Paid only. Cost: 1 credit per IP for base geolocation. This MCP server accepts up to ${MAX_BULK_ITEMS.toLocaleString()} IPs per request. Use it when multiple IPs need location or mixed IP domains. Include modules such as security or abuse add their normal per-IP credit costs. For bulk security-only checks, prefer bulk_security_check.`, inputSchema: { ips: z .array(z.string()) .min(1) .max(MAX_BULK_ITEMS) .describe( `Array of IPv4 and/or IPv6 addresses to look up. Minimum 1, maximum ${MAX_BULK_ITEMS.toLocaleString()} in this MCP server. Domain names are also accepted.` ), lang: z .string() .optional() .describe( "Response language code (en, de, ru, ja, fr, cn, es, cs, it, ko, fa, pt). Defaults to en." ), include: z .string() .optional() .describe( "Comma-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)." ), fields: z .string() .optional() .describe( "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." ), excludes: z .string() .optional() .describe( "Comma-separated dot-path fields to exclude per IP (e.g. currency,time_zone)." ), force_refresh: z .boolean() .optional() .describe("Default false. Leave unset unless the user asks to refresh or rerun."), }, },