lookup_ip_address_privacy
Identify if an IP address is linked to a VPN, proxy, anonymizing service, hosting provider, or appears on an abuse blocklist. Analyze IPv4 or IPv6 addresses or check details of the caller's IP.
Instructions
Check whether an IP address is detected as a VPN, proxy, other anonymizing service; is on an abuse blocklist; or is a hosting provider. Can look up any IPv4 or IPv6 address, or your own IP if no address is provided.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| ip | No | IPv4 or IPv6 address to look up. If not provided, returns information about the caller's IP address. |
Implementation Reference
- src/index.ts:200-233 (handler)Handler function that validates the optional IP address input, fetches full IP data using the shared fetchIPData helper, extracts the privacy and hosting fields from the response, and returns them as a formatted JSON string. Includes error handling for invalid IPs and API failures.async ({ ip }) => { if (ip && !isValidIP(ip)) { return { content: [{ type: "text", text: `Error: "${ip}" is not a valid IPv4 or IPv6 address.` }], isError: true }; } try { const data = await fetchIPData(ip); const privacyData = { ip: data.ip, privacy: data.privacy, hosting: data.hosting }; return { content: [{ type: "text", text: JSON.stringify(privacyData, null, 2) }] }; } catch (error) { return { content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; }
- src/index.ts:192-235 (registration)Registration of the lookup_ip_address_privacy tool using server.registerTool, specifying the tool name, metadata (title, description), input schema, and inline handler function.// Register tool: lookup_ip_address_privacy server.registerTool( "lookup_ip_address_privacy", { title: "Look up IP Address Privacy & Security", description: "Check whether an IP address is detected as a VPN, proxy, other anonymizing service; is on an abuse blocklist; or is a hosting provider. Can look up any IPv4 or IPv6 address, or your own IP if no address is provided.", inputSchema: IPAddressSchema }, async ({ ip }) => { if (ip && !isValidIP(ip)) { return { content: [{ type: "text", text: `Error: "${ip}" is not a valid IPv4 or IPv6 address.` }], isError: true }; } try { const data = await fetchIPData(ip); const privacyData = { ip: data.ip, privacy: data.privacy, hosting: data.hosting }; return { content: [{ type: "text", text: JSON.stringify(privacyData, null, 2) }] }; } catch (error) { return { content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } } );
- src/index.ts:14-16 (schema)Shared input schema definition for all IP lookup tools, including lookup_ip_address_privacy. Defines optional 'ip' parameter using Zod for validation.const IPAddressSchema = { ip: z.string().optional().describe("IPv4 or IPv6 address to look up. If not provided, returns information about the caller's IP address.") };
- src/models.ts:49-69 (schema)TypeScript interface defining the structure of the IPLocate API response, including 'privacy' and 'hosting' fields specifically used by this tool's handler.export interface IPLocateResponse { ip: string; country?: string | null; country_code?: string | null; is_eu?: boolean; city?: string | null; continent?: string | null; latitude?: number | null; longitude?: number | null; time_zone?: string | null; postal_code?: string | null; subdivision?: string | null; currency_code?: string | null; calling_code?: string | null; network?: string | null; asn?: ASNInfo | null; privacy?: PrivacyInfo; company?: CompanyInfo | null; hosting?: HostingInfo | null; abuse?: AbuseInfo | null; }
- src/index.ts:44-89 (helper)Shared helper function that performs the HTTP fetch to the iplocate.io API, handles API key, errors, and returns typed response data. Called by the handler to retrieve raw IP information.async function fetchIPData(ip?: string): Promise<IPLocateResponse> { const baseUrl = "https://iplocate.io/api/lookup"; const apiKey = process.env.IPLOCATE_API_KEY; let url = ip ? `${baseUrl}/${ip}` : `${baseUrl}/`; // Add API key if available if (apiKey) { url += `?apikey=${apiKey}`; } try { const response = await fetch(url, { headers: { 'User-Agent': `mcp-server-iplocate/${VERSION}` } }); if (!response.ok) { const errorText = await response.text(); let errorMessage = `API request failed with status ${response.status}`; try { const errorJson = JSON.parse(errorText); if (errorJson.error) { errorMessage = errorJson.error; } } catch { // If not JSON, use the raw text if (errorText) { errorMessage = errorText; } } throw new Error(errorMessage); } const data = await response.json() as IPLocateResponse; return data; } catch (error) { if (error instanceof Error) { throw error; } throw new Error(`Failed to fetch IP data: ${String(error)}`); } }