{
  "markdown": "# IPGeolocation.io MCP Server\n\n[![SafeSkill](https://safeskill.dev/api/badge/ipgeolocation-io-mcp)](https://safeskill.dev/scan/ipgeolocation-io-mcp)\n\n[![npm version](https://img.shields.io/npm/v/ipgeolocation-io-mcp?logo=npm&label=npm&color=CB3837)](https://www.npmjs.com/package/ipgeolocation-io-mcp)\n[![GitHub release](https://img.shields.io/github/v/release/IPGeolocation/ipgeolocation-io-mcp?logo=github&label=release&color=181717)](https://github.com/IPGeolocation/ipgeolocation-io-mcp/releases)\n[![MCP Registry](https://img.shields.io/badge/MCP%20Registry-live-0A7CFF?logo=modelcontextprotocol&logoColor=white)](https://registry.modelcontextprotocol.io/?q=ipgeolocation)\n[![Glama](https://img.shields.io/badge/Glama-listed-0A7CFF)](https://glama.ai/mcp/servers/IPGeolocation/ipgeolocation-io-mcp)\n[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/IPGeolocation/ipgeolocation-io-mcp/badge)](https://scorecard.dev/viewer/?uri=github.com/IPGeolocation/ipgeolocation-io-mcp)\n[![Node.js](https://img.shields.io/badge/node-%3E%3D22-5FA04E?logo=node.js&logoColor=white)](https://nodejs.org/)\n[![License](https://img.shields.io/badge/license-MIT-16A34A)](https://github.com/IPGeolocation/ipgeolocation-io-mcp/blob/main/LICENSE)\n\nOfficial MCP server for [IPGeolocation.io](https://ipgeolocation.io). Includes 16 MCP tools: IP geolocation, threat/VPN/proxy detection, timezone lookups and conversions, sunrise/sunset/moon data, ASN details, abuse contacts, and user-agent parsing. Seven tools work on the free plan (1,000 credits/day). Paid plans unlock all 16 plus bulk endpoints (up to 50,000 items per call; default 1,000, configurable via `IPGEOLOCATION_MCP_MAX_BULK_ITEMS`).\n\nWorks with Claude Desktop, Cursor, Windsurf, VS Code, Codex, Cline, Glama, and any other MCP client.\n\n| Item | Value |\n|------|-------|\n| Package | `ipgeolocation-io-mcp` |\n| Version | `2.0.0` |\n| Transport | `stdio` |\n| Node.js | `>=22` |\n\n## Quick Start\n\n1. [Create a free IPGeolocation API key](https://app.ipgeolocation.io/signup)\n\n2. Cursor users can install in one click:\n\n   [![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=ipgeolocation&config=eyJjb21tYW5kIjoibnB4IC15IGlwZ2VvbG9jYXRpb24taW8tbWNwIiwiZW52Ijp7IklQR0VPTE9DQVRJT05fQVBJX0tFWSI6IiJ9fQ%3D%3D)\n\n3. Add this to your MCP client config (see [Install by Client](#install-by-client) below for the exact config file path for your client):\n\n```json\n{\n  \"mcpServers\": {\n    \"ipgeolocation\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"ipgeolocation-io-mcp\"],\n      \"env\": {\n        \"IPGEOLOCATION_API_KEY\": \"<YOUR_API_KEY>\"\n      }\n    }\n  }\n}\n```\n\n4. Restart your client.\n\n5. Test it: ask **\"Where is 8.8.8.8 located?\"**\n\n## Table of Contents\n\n- [Quick Start](#quick-start)\n- [Install by Client](#install-by-client)\n- [Verify It Works](#verify-it-works)\n- [Tools by Plan](#tools-by-plan)\n- [Tool Reference](#tool-reference)\n- [Prompt Examples](#prompt-examples)\n- [Example Answers and Tool Output](#example-answers-and-tool-output)\n- [Error Codes](#error-codes)\n- [How It Works](#how-it-works)\n- [Caching](#caching)\n- [Environment Variables](#environment-variables)\n- [Building from Source](#building-from-source)\n- [Docker](#docker)\n- [Testing](#testing)\n- [Troubleshooting](#troubleshooting)\n- [Pricing](#pricing)\n- [Links](#links)\n- [License](#license)\n- [Privacy Policy](#privacy-policy)\n\n## Install by Client\n\n### Requirements\n\n- Node.js 22 or later\n- `npx` available in your terminal\n- An IPGeolocation.io API key for most tools\n\n`get_my_ip` works without an API key. Everything else requires one.\n\n[Sign up for a free IPGeolocation API key](https://app.ipgeolocation.io/signup)\n\n### Codex CLI\n\n```bash\ncodex mcp add ipgeolocation --env IPGEOLOCATION_API_KEY=<YOUR_API_KEY> -- npx -y ipgeolocation-io-mcp\ncodex mcp list\n```\n\nStart a new Codex session after adding the server.\n\n### Claude Desktop\n\nAdd to `claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ipgeolocation\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"ipgeolocation-io-mcp\"],\n      \"env\": {\n        \"IPGEOLOCATION_API_KEY\": \"<YOUR_API_KEY>\"\n      }\n    }\n  }\n}\n```\n\nRestart Claude Desktop after saving. We also ship `manifest.json` for clients that support MCP Bundles.\n\n### Cline\n\nOpen MCP Servers panel > **Configure** > **Advanced MCP Settings**. Add to `cline_mcp_settings.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ipgeolocation\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"ipgeolocation-io-mcp\"],\n      \"env\": {\n        \"IPGEOLOCATION_API_KEY\": \"<YOUR_API_KEY>\"\n      }\n    }\n  }\n}\n```\n\nRestart Cline after saving.\n\n### Cursor\n\nOne-click install:\n\n[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/install-mcp?name=ipgeolocation&config=eyJjb21tYW5kIjoibnB4IC15IGlwZ2VvbG9jYXRpb24taW8tbWNwIiwiZW52Ijp7IklQR0VPTE9DQVRJT05fQVBJX0tFWSI6IiJ9fQ%3D%3D)\n\nOr add to `.cursor/mcp.json` manually:\n\n```json\n{\n  \"mcpServers\": {\n    \"ipgeolocation\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"ipgeolocation-io-mcp\"],\n      \"env\": {\n        \"IPGEOLOCATION_API_KEY\": \"<YOUR_API_KEY>\"\n      }\n    }\n  }\n}\n```\n\nRestart Cursor after saving.\n\n### Windsurf\n\nAdd to `~/.codeium/windsurf/mcp_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ipgeolocation\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"ipgeolocation-io-mcp\"],\n      \"env\": {\n        \"IPGEOLOCATION_API_KEY\": \"<YOUR_API_KEY>\"\n      }\n    }\n  }\n}\n```\n\nRestart Windsurf after saving.\n\n### VS Code / GitHub Copilot\n\nAdd to your VS Code `settings.json`:\n\n```json\n{\n  \"mcp\": {\n    \"servers\": {\n      \"ipgeolocation\": {\n        \"command\": \"npx\",\n        \"args\": [\"-y\", \"ipgeolocation-io-mcp\"],\n        \"env\": {\n          \"IPGEOLOCATION_API_KEY\": \"<YOUR_API_KEY>\"\n        }\n      }\n    }\n  }\n}\n```\n\nRestart VS Code after saving.\n\n### Glama\n\nYou can try the server on [Glama](https://glama.ai/mcp/servers/IPGeolocation/ipgeolocation-io-mcp) directly. Only `IPGEOLOCATION_API_KEY` is required. Leave other environment variable fields empty unless you want to change cache, timeout, or output limits.\n\nIf you don't have a key yet, [create a free IPGeolocation API key](https://app.ipgeolocation.io/signup).\n\n### Any Other MCP Client\n\nUse this config:\n\n```json\n{\n  \"command\": \"npx\",\n  \"args\": [\"-y\", \"ipgeolocation-io-mcp\"],\n  \"env\": {\n    \"IPGEOLOCATION_API_KEY\": \"<YOUR_API_KEY>\"\n  }\n}\n```\n\n## Verify It Works\n\nTry these after setup:\n\n| Prompt | Expected tool |\n|--------|---------------|\n| Where is 8.8.8.8 located? | `lookup_ip` |\n| For IP 49.12.212.42, give me security verdict, company, ASN, and city. | `lookup_ip` with `fields` and `include=security` |\n| Is 2.56.12.11 safe to allow and what is the abuse contact email? | `lookup_ip` with `include=security,abuse` |\n| For AS1, list upstream ASN numbers only. | `lookup_asn` with `include=upstreams` |\n| Convert 2026-03-07 09:30 from New York to Tokyo time. | `convert_timezone` |\n| Give sunrise times for Karachi from 2026-03-10 to 2026-03-15. | `get_astronomy_time_series` |\n| Parse this user agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 | `parse_user_agent` |\n\n## Tools by Plan\n\n### Free Plan\n\n1,000 credits per day. These 7 tools are available:\n\n| Tool | Credits | What it does |\n|------|---------|--------------|\n| `lookup_ip` | 1 | Location, timezone, currency, ASN for one IP |\n| `get_my_ip` | 0 | Public IP of the machine running the server |\n| `lookup_currency` | 1 | Currency and country metadata for one IP |\n| `get_timezone` | 1 | Timezone by name, location, IP, airport code, or UN/LOCODE |\n| `convert_timezone` | 1 | Convert time between two locations |\n| `get_astronomy` | 1 | Sunrise, sunset, moonrise, moonset, twilight, moon phase for one date |\n| `get_astronomy_time_series` | 1 | Daily astronomy data for a date range (up to 90 days) |\n\n### Paid Plans\n\nAll 16 tools. Paid plans also add `network`, `company`, and extended `asn` fields to `lookup_ip`, plus the `include` parameter for `security`, `abuse`, `hostname`, `liveHostname`, `hostnameFallbackLive`, `user_agent`, `geo_accuracy`, `dma_code`, or `*`.\n\n| Tool | Credits | What it does |\n|------|---------|--------------|\n| `bulk_lookup_ip` | 1 per IP | Batch geolocation, up to 50,000 IPs (default 1,000) |\n| `check_security` | 2 | VPN, proxy, Tor, bot, spam, and threat flags |\n| `bulk_security_check` | 2 per IP | Batch threat checks |\n| `lookup_company` | 1 | Company name and ASN holder for one IP |\n| `lookup_network` | 1 | Route prefix, connection type, anycast status |\n| `parse_user_agent` | 1 | Parse one UA string into browser, device, OS, engine |\n| `bulk_parse_user_agent` | 1 per UA | Batch UA parsing, up to 50,000 strings (default 1,000) |\n| `lookup_asn` | 1 | ASN details, peers, upstreams, downstreams, routes, WHOIS |\n| `get_abuse_contact` | 1 | Abuse contact emails, phone, address, route |\n\n**Credit math for `lookup_ip` with `include`:**\n\n| Combination | Total credits |\n|-------------|---------------|\n| Base lookup | 1 |\n| `include=security` | 3 |\n| `include=abuse` | 2 |\n| `include=*` | 4 |\n| `include=security&fields=security` | 2 |\n| `include=abuse&fields=abuse` | 1 |\n\nFor current plan details and pricing, see the [IPGeolocation pricing page](https://ipgeolocation.io/pricing.html).\n\n## Tool Reference\n\n### lookup_ip\n\nSingle IP or domain lookup. **Free and paid. 1 credit.**\n\nUse this when you need location, timezone, currency, or ASN for one IP address. On paid plans you can add `include` modules to pull security, abuse, or hostname data in the same call, which avoids extra requests.\n\nFree plan returns base location, country metadata, currency, timezone, and basic ASN. Paid plans add `network`, `company`, extended ASN, and the `include` parameter. Note that domain lookups require a paid plan.\n\n| Parameter | Required | Description |\n|-----------|----------|-------------|\n| `ip` | No | IPv4, IPv6, or domain. Domain lookup requires a paid plan. |\n| `lang` | No | Response language. Non-English requires a paid plan. |\n| `include` | No | Extra modules: `security`, `abuse`, `hostname`, `liveHostname`, `hostnameFallbackLive`, `user_agent`, `geo_accuracy`, `dma_code`, or `*` |\n| `fields` | No | Comma-separated fields to return |\n| `excludes` | No | Comma-separated fields to exclude |\n| `force_refresh` | No | Skip the cache and hit the API directly |\n\nTip: combining `include` with `fields` can cut your credit cost. For example, `include=security&fields=security` costs 2 credits instead of 3 because you skip the base geolocation response. Similarly, `include=abuse&fields=abuse` costs 1 credit instead of 2.\n\n### bulk_lookup_ip\n\nBatch IP lookup. **Paid. 1 credit per IP.**\n\nTakes an array of IPs or domains (up to 1,000 by default, configurable with `IPGEOLOCATION_MCP_MAX_BULK_ITEMS`). Supports the same `include`, `fields`, and `excludes` options as `lookup_ip`.\n\n| Parameter | Required | Description |\n|-----------|----------|-------------|\n| `ips` | Yes | Array of IP addresses or domains |\n| `lang` | No | Response language |\n| `include` | No | Extra modules per IP |\n| `fields` | No | Comma-separated fields to return per IP |\n| `excludes` | No | Comma-separated fields to exclude per IP |\n| `force_refresh` | No | Skip the cache |\n\n### get_my_ip\n\nReturns the public IP of the machine running the server. **Free. 0 credits. No API key needed.**\n\nTakes no parameters. Always hits the network (not cached). Useful as a quick check to confirm the server process is up.\n\n### check_security\n\nThreat and anonymity data for one IP. **Paid. 2 credits.**\n\nReturns threat score, VPN/proxy/Tor flags, provider names, confidence scores, bot/spam indicators, anonymity flags, and cloud-provider status.\n\nIf the same prompt also asks for location, ASN, or abuse data, you're better off using `lookup_ip` with `include=security` because it bundles everything in one call (3 credits total instead of 2 + 1 separately).\n\n| Parameter | Required | Description |\n|-----------|----------|-------------|\n| `ip` | No | IP address to check |\n| `fields` | No | Comma-separated fields to return |\n| `excludes` | No | Comma-separated fields to exclude |\n| `force_refresh` | No | Skip the cache |\n\n### bulk_security_check\n\nBatch version of `check_security`. **Paid. 2 credits per IP.**\n\n| Parameter | Required | Description |\n|-----------|----------|-------------|\n| `ips` | Yes | Array of IP addresses |\n| `fields` | No | Comma-separated fields to return per IP |\n| `excludes` | No | Comma-separated fields to exclude per IP |\n| `force_refresh` | No | Skip the cache |\n\n### get_timezone\n\nCurrent time and timezone details for a location. **Free and paid. 1 credit.**\n\nAccepts IANA timezone names, coordinates, IP addresses, airport codes (IATA/ICAO), or UN/LOCODEs. The response includes timezone offsets, date/datetime variants, `current_time`, `current_time_unix`, `time_24`, `time_12`, `week`, `month`, `year`, timezone abbreviations, and DST transition details.\n\nAlways hits the network (not cached) because it returns the current time.\n\n| Parameter | Required | Description |\n|-----------|----------|-------------|\n| `tz` | No | IANA timezone name (e.g., `America/New_York`) |\n| `lat` + `long` | No | Latitude and longitude |\n| `location` | No | City or address string |\n| `ip` | No | IP address |\n| `iata_code` | No | IATA airport code |\n| `icao_code` | No | ICAO airport code |\n| `lo_code` | No | UN/LOCODE |\n| `lang` | No | Response language. Non-English requires a paid plan. |\n\n### convert_timezone\n\nConverts a time between two locations. **Free and paid. 1 credit.**\n\nTakes the same location input types as `get_timezone` for both source and destination. If you leave out the `time` parameter, it converts the current time. Always hits the network (not cached).\n\n| Parameter | Required | Description |\n|-----------|----------|-------------|\n| `time` | No | `yyyy-MM-dd HH:mm` or `yyyy-MM-dd HH:mm:ss`. Defaults to now. |\n| `tz_from` / `tz_to` | No | IANA timezone names |\n| `lat_from` + `long_from` | No | Source coordinates |\n| `lat_to` + `long_to` | No | Destination coordinates |\n| `location_from` / `location_to` | No | City/address strings |\n| `iata_from` / `iata_to` | No | IATA airport codes |\n| `icao_from` / `icao_to` | No | ICAO airport codes |\n| `locode_from` / `locode_to` | No | UN/LOCODEs |\n\n### get_astronomy\n\nSun and moon data for one location on one date. **Free and paid. 1 credit.**\n\nReturns sunrise, sunset, moonrise, moonset, morning and evening twilight, solar noon, day length, moon phase, sun/moon status flags, and live sun/moon position (altitude, azimuth).\n\nAlways hits the network (not cached) because skipping `date` defaults to today.\n\n| Parameter | Required | Description |\n|-----------|----------|-------------|\n| `lat` + `long` | No | Coordinates (highest priority when given) |\n| `location` | No | City or address |\n| `ip` | No | IP address |\n| `date` | No | `YYYY-MM-DD`. Defaults to today. |\n| `elevation` | No | Meters, 0 to 10000 |\n| `time_zone` | No | IANA name to control output times |\n| `lang` | No | Response language. Non-English requires a paid plan. |\n\n### get_astronomy_time_series\n\nAstronomy data for a date range, up to 90 days. **Free and paid. 1 credit per request.**\n\nEach daily entry includes `mid_night`, `night_end`, `morning`, `sunrise`, `sunset`, `evening`, `night_begin`, `sun_status`, `solar_noon`, `day_length`, `moon_phase`, `moonrise`, `moonset`, and `moon_status`. Use this instead of calling `get_astronomy` repeatedly for a range.\n\n| Parameter | Required | Description |\n|-----------|----------|-------------|\n| `dateStart` | Yes | Start date (`YYYY-MM-DD`) |\n| `dateEnd` | Yes | End date (`YYYY-MM-DD`). Max span: 90 days. |\n| `lat` + `long` | No | Coordinates (highest priority when given) |\n| `location` | No | City or address |\n| `ip` | No | IP address |\n| `elevation` | No | Meters |\n| `time_zone` | No | IANA name to control output times |\n| `lang` | No | Response language. Non-English requires a paid plan. |\n| `force_refresh` | No | Skip the cache |\n\n### parse_user_agent\n\nParses one UA string into browser, device, OS, and engine data. **Paid. 1 credit.**\n\nAlso classifies bots and crawlers. Note: this parses the `uaString` you pass in. It does not infer a caller UA from the MCP connection itself.\n\n| Parameter | Required | Description |\n|-----------|----------|-------------|\n| `uaString` | Yes | The user-agent string to parse |\n| `force_refresh` | No | Skip the cache |\n\nReturns `name`, `type`, `version`, `device`, `engine`, and `operating_system`.\n\n### bulk_parse_user_agent\n\nBatch version of `parse_user_agent`. **Paid. 1 credit per string.**\n\nTakes up to 1,000 strings per request by default (configurable with `IPGEOLOCATION_MCP_MAX_BULK_ITEMS`).\n\n| Parameter | Required | Description |\n|-----------|----------|-------------|\n| `uaStrings` | Yes | Array of user-agent strings |\n| `force_refresh` | No | Skip the cache |\n\n### lookup_company\n\nReturns just the company name and ASN holder for one IP. **Paid. 1 credit.**\n\nReturns `company` and `asn` objects. `lookup_ip` returns the same data plus location, timezone, and more. Use this when the company/ASN pair is all you need and you want a smaller response.\n\n| Parameter | Required | Description |\n|-----------|----------|-------------|\n| `ip` | No | IP address |\n| `force_refresh` | No | Skip the cache |\n\n### lookup_currency\n\nCurrency, country calling code, TLD, and languages for one IP. **Free and paid. 1 credit.**\n\nReturns `currency` and `country_metadata` objects.\n\n| Parameter | Required | Description |\n|-----------|----------|-------------|\n| `ip` | No | IP address |\n| `force_refresh` | No | Skip the cache |\n\n### lookup_network\n\nRoute prefix, connection type, and anycast status for one IP. **Paid. 1 credit.**\n\nReturns a `network` object with `connection_type`, `route`, and `is_anycast`.\n\n| Parameter | Required | Description |\n|-----------|----------|-------------|\n| `ip` | No | IP address |\n| `force_refresh` | No | Skip the cache |\n\n### lookup_asn\n\nFull ASN lookup. **Paid. 1 credit.**\n\n`lookup_ip` also returns an `asn` object, but only with basic metadata. This tool returns the full ASN record, including peers, upstreams, downstreams, routes, and WHOIS. Call it once with the `include` fields you need, then filter locally instead of making multiple calls for different slices.\n\n| Parameter | Required | Description |\n|-----------|----------|-------------|\n| `asn` | No | ASN (e.g., `AS13335` or `13335`) |\n| `ip` | No | IP address to resolve to an ASN |\n| `include` | No | `peers`, `downstreams`, `upstreams`, `routes`, `whois_response` |\n| `fields` | No | Comma-separated fields to return |\n| `excludes` | No | Comma-separated fields to exclude |\n| `force_refresh` | No | Skip the cache |\n\n### get_abuse_contact\n\nAbuse contact details for one IP. **Paid. 1 credit.**\n\nReturns the abuse route, country, contact name, organization, address, email addresses, and phone numbers. If you also need geolocation or security data for the same IP, use `lookup_ip` with `include=abuse` (or `include=security,abuse`) to get everything in one call.\n\n| Parameter | Required | Description |\n|-----------|----------|-------------|\n| `ip` | No | IP address |\n| `fields` | No | Comma-separated fields to return |\n| `excludes` | No | Comma-separated fields to exclude |\n| `force_refresh` | No | Skip the cache |\n\n## Prompt Examples\n\n### Check if an IP is safe\n\n- Is 49.12.212.42 safe to trust in our network? Give me the threat summary and city.\n- Check these IPs for VPN, proxy, Tor, bot, and spam indicators: 49.12.212.42, 2.56.12.11, 8.8.8.8\n- For 203.0.113.42, tell me the threat score, whether it is a cloud provider, and whether it looks like a relay.\n\n### Find who owns an IP\n\n- Who uses 1.1.1.1 and which ASN routes it?\n- For AS24940, list upstream ASN numbers only.\n- Is this IP anycast and what route prefix is announced for it: 1.1.1.1\n\n### Get abuse contacts\n\n- For IP 2.56.12.11, give me the abuse contact email, phone number, and organization.\n- I need the abuse contact for 1.0.0.0 and the network route involved.\n- For this IP, show me the abuse contact details only: 198.51.100.27\n\n### Timezone lookups and conversions\n\n- What time is it in Tokyo right now?\n- Convert 2026-03-07 09:30 from New York to Tokyo time.\n- What is the current local time at JFK airport?\n\n### Sunrise, sunset, and moon data\n\n- Give sunrise and sunset for London on 2026-06-21.\n- Show sunrise times in Karachi from 2026-03-10 to 2026-03-15.\n- For New York, give me moon phase and day length on 2026-07-17.\n\n### Parse user-agent strings\n\n- Parse this user agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10\\_11\\_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9\n- Parse these user agents in bulk and tell me the browser, OS, and device type for each.\n- Does this user agent look like a crawler or bot? Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)\n\n## Example Answers and Tool Output\n\nThe text answers below show what a client might say. Exact wording depends on the model. The JSON blocks show raw tool output, trimmed for readability.\n\n### Single IP lookup\n\n**Prompt:** Locate 91.128.103.196 and give me the country, city, ASN, and local time.\n\n**Example answer:** 91.128.103.196 is in Stockholm, Sweden. ASN is AS1257, operated by Tele2 Sverige AB. Timezone is Europe/Stockholm, local time was 2026-02-12 18:36:54.\n\n```json\n{\n  \"ip\": \"91.128.103.196\",\n  \"location\": {\n    \"country_name\": \"Sweden\",\n    \"state_prov\": \"Stockholms lan\",\n    \"city\": \"Stockholm\"\n  },\n  \"asn\": {\n    \"as_number\": \"AS1257\",\n    \"organization\": \"Tele2 Sverige AB\",\n    \"country\": \"SE\"\n  },\n  \"time_zone\": {\n    \"name\": \"Europe/Stockholm\",\n    \"current_time\": \"2026-02-12 18:36:54.401+0100\"\n  }\n}\n```\n\n### Time conversion\n\n**Prompt:** Convert 2025-01-21 13:42:52 from DXB to LHR.\n\n**Example answer:** 2025-01-21 13:42:52 in Dubai converts to 2025-01-21 09:42:52 in London. The difference is 4 hours.\n\n```json\n{\n  \"original_time\": \"2025-01-21 13:42:52\",\n  \"converted_time\": \"2025-01-21 09:42:52\",\n  \"diff_hour\": 4,\n  \"diff_min\": 240\n}\n```\n\n### Abuse contact\n\n**Prompt:** Give me the abuse contact for 1.0.0.0.\n\n**Example answer:** The abuse contact for 1.0.0.0 is IRT-APNICRANDNET-AU in Australia, covering route 1.0.0.0/24. Email: helpdesk@apnic.net.\n\n```json\n{\n  \"ip\": \"1.0.0.0\",\n  \"abuse\": {\n    \"route\": \"1.0.0.0/24\",\n    \"country\": \"AU\",\n    \"name\": \"IRT-APNICRANDNET-AU\",\n    \"address\": \"PO Box 3646, South Brisbane, QLD 4101, Australia\",\n    \"emails\": [\"helpdesk@apnic.net\"]\n  }\n}\n```\n\n## Error Codes\n\nAll tools return structured errors instead of crashing the server. API errors include the upstream status/message plus a `guidance` field so MCP clients can tell the user what to check next instead of only repeating the upstream response.\n\n| Code | Meaning |\n|------|---------|\n| `400` | Bad parameters, invalid date/time format, missing coordinate pair, or unsupported input |\n| `401` | Missing/invalid API key, free plan calling a paid tool, or non-English `lang` on free plan |\n| `404` | Resource not found (e.g., ASN does not exist) |\n| `405` | Method or subscription restriction from the upstream API |\n| `413` | POST body is larger than the upstream API allows |\n| `415` | POST request is missing the required `application/json` content type |\n| `423` | Bogon or private IP (`10.x.x.x`, `192.168.x.x`, etc.) |\n| `429` | Daily request limit (free plan) or subscription/surcharge quota exceeded |\n| `499` | Client-side request or connection timeout was too short |\n| `5xx` | Upstream API server-side error |\n| `502` | Server could not reach the upstream API |\n| `504` | Upstream API timed out |\n\nExact status codes can vary by endpoint and request mode. If an upstream endpoint returns a status outside this table, the server does not guess the cause. It passes the upstream status and message through with `category: \"undocumented_api_error\"` and adds guidance for the MCP client to explain the response as an undocumented upstream status without inventing a cause.\n\n## How It Works\n\nThis is a stdio MCP server that wraps the ipgeolocation.io v3 APIs.\n\nAt runtime:\n\n1. Your MCP client starts the server process.\n2. The client reads the tool list.\n3. When a prompt matches a tool, the client calls it.\n4. The server validates inputs, calls our API, and returns structured JSON.\n5. Cacheable responses are stored in process memory so repeated identical requests skip the API call.\n\nAuthenticated upstream requests send the API key in the `x-ipgeolocation-api-key` header. The key is not added to request URLs.\n\n`lookup_company`, `lookup_currency`, and `lookup_network` are wrappers around parts of the full IP lookup response. They exist as separate tools so MCP clients can discover them when a user only needs one piece of data.\n\n## Caching\n\nTools that return stable data (not current-time lookups) cache their responses in process memory. Repeated lookups are faster and don't use additional credits. Client retries don't generate duplicate API calls.\n\n- Process-level cache, not client or model memory\n- Cache entries are scoped by API key, so separate MCP sessions do not share cached upstream data\n- Default TTL: 5 minutes (`300000` ms)\n- Cache resets when the server process stops\n- Cache misses on TTL expiry, changed parameters, or `force_refresh: true`\n\n**Cached:** `lookup_ip`, `bulk_lookup_ip`, `check_security`, `bulk_security_check`, `lookup_company`, `lookup_currency`, `lookup_network`, `parse_user_agent`, `bulk_parse_user_agent`, `lookup_asn`, `get_abuse_contact`, `get_astronomy_time_series`\n\n**Always live (not cached):** `get_my_ip`, `get_timezone`, `convert_timezone`, `get_astronomy`\n\n## Environment Variables\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `IPGEOLOCATION_API_KEY` | Yes (most tools) | | Your ipgeolocation.io API key |\n| `IPGEOLOCATION_REQUEST_TIMEOUT_MS` | No | `15000` | Upstream timeout in ms. Range: 1000-120000 |\n| `IPGEOLOCATION_MCP_CACHE_TTL_MS` | No | `300000` | Cache TTL in ms. Range: 1000-3600000 |\n| `IPGEOLOCATION_MCP_CACHE_MAX_ENTRIES` | No | `500` | Max entries before eviction. Range: 10-5000 |\n| `IPGEOLOCATION_MCP_MAX_BULK_ITEMS` | No | `1000` | Max items per bulk request. Max: 50000 |\n| `IPGEOLOCATION_MCP_MAX_RESULT_ITEMS` | No | `250` | Max array items before truncation |\n| `IPGEOLOCATION_MCP_MAX_RESPONSE_CHARS` | No | `200000` | Max response text length |\n| `IPGEOLOCATION_MCP_MAX_ERROR_CHARS` | No | `4000` | Max error text length |\n\n## Building from Source\n\n```bash\ngit clone https://github.com/IPGeolocation/ipgeolocation-io-mcp.git\ncd ipgeolocation-io-mcp\nnpm install\nnpm run build\n```\n\nRun it directly:\n\n```bash\nIPGEOLOCATION_API_KEY=<YOUR_KEY> node dist/cli.js\n```\n\nInspect with MCP Inspector:\n\n```bash\nIPGEOLOCATION_API_KEY=<YOUR_KEY> npx @modelcontextprotocol/inspector node dist/cli.js\n```\n\n## Docker\n\n```bash\ndocker build -t ipgeolocation-mcp .\ndocker run -e IPGEOLOCATION_API_KEY=<YOUR_KEY> ipgeolocation-mcp\n```\n\n## Testing\n\n```bash\nnpm test               # full suite\nnpm run test:unit      # unit tests only\nnpm run test:integration  # integration tests only\n```\n\n## Troubleshooting\n\n**Client uses an old tool after updating:** Restart the client and confirm it loaded the latest npm version.\n\n**401 errors:** Check that `IPGEOLOCATION_API_KEY` is set in your config. Some tools are paid-only and return 401 on the free plan. Domain lookups in `lookup_ip` also require a paid plan.\n\n**423 errors:** You passed a private/bogon IP like `10.0.0.1` or `192.168.1.1`. These have no geolocation data.\n\n**504 timeouts:** The upstream API did not respond in time. Increase the timeout with `IPGEOLOCATION_REQUEST_TIMEOUT_MS` (default: 15000 ms, max: 120000 ms).\n\n## Pricing\n\nFor current plan details, credits, and pricing, see the [IPGeolocation pricing page](https://ipgeolocation.io/pricing.html).\n\n## Links\n\n- [IPGeolocation Website](https://ipgeolocation.io)\n- [IPGeolocation API Documentation](https://ipgeolocation.io/documentation.html)\n- [IPGeolocation Pricing](https://ipgeolocation.io/pricing.html)\n- [Create a Free IPGeolocation API Key](https://app.ipgeolocation.io/signup)\n- [Changelog](CHANGELOG.md)\n\n## License\n\n[MIT](LICENSE)\n\n## Privacy Policy\n\nRead the [IPGeolocation Privacy Policy](https://ipgeolocation.io/privacy.html).\n",
  "bytes": 28485,
  "sha": "879b05aa45f4ddcb2e345722469fb47894ef0b8e045067406a832d716a217283",
  "repo_slug": "ipgeolocation/ipgeolocation-io-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_ipgeolocation_ipgeolocation_io_66c67c11/readme"
}