MaxMindDB MCP Server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MaxMindDB MCP Serveridentify the country and ASN for 8.8.8.8"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MaxMindDB MCP Server
Look up IP locations and network ownership in GeoIP2, GeoLite2, and custom MMDB databases from your AI assistant. Search networks, compare databases, and download new databases through MCP.
This is an unofficial project and is not endorsed by MaxMind Inc. For official products and support, visit maxmind.com.
Try asking:
"Using MaxMindDB, identify the country and autonomous system for 8.8.8.8."
"Find the networks belonging to AS13335 within 1.0.0.0/8 in my ASN database."
"Which databases are available, and when were they built?"
Answers come from your databases. IP geolocation is an estimate, not a device's precise location. ASN data describes network ownership, not the identity of a person using an address.
What you need
Provide either existing .mmdb files or a MaxMind account ID and license key with access to the editions you want.
Databases and credentials are not bundled.
The server runs on your computer and requires a client that supports local MCP servers.
Related MCP server: geolocation-mcp
Installation
Claude Desktop
Install and configure the server through Claude Desktop. No terminal, Go installation, or config file is required.
Download the latest MCPB. The single file includes native builds for all supported platforms.
Open Settings → Extensions → Advanced settings → Install Extension in Claude Desktop and select the file.
Choose how to provide databases in the extension settings:
Download databases: Enter your MaxMind account ID and license key. The default editions are
GeoLite2-CityandGeoLite2-ASN.Use existing files: Turn off Download and update MaxMind databases and select the folder containing your
.mmdbfiles.
Enable the extension and ask: "Using MaxMindDB, list my databases and look up 8.8.8.8."
The first download runs in the background. Ask Claude to check database status if lookups are not ready yet. Enter license keys in extension settings, not in chat.
Upgrading from v0.2.0 or earlier: Remove the old extension, install the new one, and configure it again. Your database files remain in place. See upgrades, settings, and supported platforms.
Standalone executable
On macOS, install with Homebrew:
brew install --cask oschwald/tap/maxminddb-mcpFor other platforms, or without Homebrew, download an archive or Linux package from GitHub Releases. See standalone setup for installation and checksums. Then configure the server and connect your client below.
Go developers can also build from source.
Connect a client
Choose your client for step-by-step setup.
Client | Setup requirements |
Installed executable and configuration; local threads only | |
Installed executable; config file or environment settings | |
Universal native plugin, or installed executable and configuration | |
Installed executable and configuration | |
Installed executable and configuration | |
Docker engine and a config file readable by the container | |
Codex CLI registration and existing server configuration; desktop UI unverified | |
Universal plugin ZIP; installation and settings UI unverified | |
Docker engine; installation and settings UI unverified | |
Continued Gemini CLI access; native extension prompts for account settings |
Configuration
Claude Desktop users can manage settings in the extension. For standalone installations, the configuration guide covers:
Downloads using MaxMind credentials.
Existing MMDB folders or
GeoIP.conf.Environment settings, config discovery, and logging.
If setup fails, start with troubleshooting.
Tools
Your assistant discovers the tools automatically. You can ask it to look up IPs, search or summarize networks, compare and inspect databases, or install and update databases.
The tool reference documents arguments, results, filters, pagination, limits, and errors.
Help and development
Contributing: build, test, and release instructions.
License
ISC.
Available Tools
10 toolscompare_databasesCompare databasesARead-onlyIdempotent
Compare lookup answers in two loaded databases within a CIDR, for example before and after an update. Returns paginated added, removed, and changed address ranges. Equal answers with different network boundaries are unchanged. Pages scan at most 10,000 segments and can contain no changes while has_more is true. Continue until has_more is false.
| Name | Required | Description | Default |
|---|---|---|---|
| network | Yes | CIDR to compare. Use an IPv4 prefix length of 8 or greater, or a native IPv6 prefix length of 32 or greater. Repeat on each page. | |
| max_results | No | Maximum changed address ranges to return on this page. | |
| new_database | Yes | Comparison database's exact filename from list_databases. Supplies the after values. Both databases must be loaded. | |
| old_database | Yes | Baseline database's exact filename from list_databases. Supplies the before values. | |
| resume_token | No | Token from the previous page. Omit on the first request. Repeat both database names and network. If either loaded database changed, start a new comparison. |
Output Schema
| Name | Required | Description |
|---|---|---|
| changes | Yes | |
| has_more | Yes | |
| resume_token | Yes | |
| scanned_segments | Yes | Address segments examined on this page, including unchanged segments. Not cumulative across pages. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds genuinely non-obvious behavior beyond the annotations: equal answers with different network boundaries count as unchanged, pages scan at most 10,000 segments, and a page can legitimately be empty while has_more is true. These are exactly the traits that prevent an agent from stopping early or misreading an empty page as completion.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Five compact sentences with the core action front-loaded, followed by output shape, then the subtle equivalence rule and paging caveats. No filler and nothing repeated from the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotations covering the safety profile and an output schema covering return values, the description is complete: it supplies the scanning bound, the empty-page edge case, and the termination condition that the structured fields do not express. An agent can call this correctly and paginate it safely from the description alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so all five parameters are already documented in the schema, including the resume-token workflow and the filename requirements. The description reinforces the paging discipline (repeat params, keep going while has_more) but adds no parameter-level detail the schema lacks, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource pair: 'Compare lookup answers in two loaded databases within a CIDR', including the motivating scenario (before/after an update) and the output shape (added/removed/changed ranges). It is clearly a diff operation rather than another lookup, so it is distinguishable from siblings like lookup_network, though it never names an alternative explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete use context ('for example before and after an update') and a precise paging protocol ('Continue until has_more is false'). It does not state exclusions or point to a sibling for the single-database case, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inspect_databaseInspect a databaseARead-onlyIdempotent
Read MMDB metadata and sample field paths, types, and examples. Use this to choose fields, filter paths, or a summarize_network group_by field. Sampling starts at the first network record, so observed fields are not a complete schema. Use verify_database to check file integrity.
| Name | Required | Description | Default |
|---|---|---|---|
| database | Yes | Exact filename of a loaded database from list_databases. | |
| sample_size | No | Maximum network records to sample. Larger samples may reveal more fields. Sampling can stop early at internal field limits. |
Output Schema
| Name | Required | Description |
|---|---|---|
| fields | Yes | |
| database | Yes | |
| metadata | Yes | |
| sample_limit | Yes | Requested record sampling limit. Field traversal limits may stop sampling earlier. |
| sampled_records | Yes | Network records sampled in database order, not a statistically representative sample. |
| schema_complete | Yes | Always false. A field absent from this sample may exist in other records. |
| fields_truncated | Yes | True when field traversal limits or unaddressable keys omitted fields. Does not indicate whether all records were sampled. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive/closed-world, so the safety profile is covered. The description adds genuinely new behavioral context: sampling begins at the first network record and observed fields are not a complete schema, which prevents the agent from over-trusting results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, all front-loaded with the core action first, then usage routing, then the sampling caveat. Every sentence earns its place with no restatement of the name or schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation. Combined with full parameter coverage and annotations, the description supplies everything an agent needs: what it reads, when to use it, the sampling limitation, and where to go for integrity checks.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaning beyond the schema by noting that sampling starts at the first record — a non-random starting point that affects how sample_size should be interpreted and how representative the results are.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource: 'Read MMDB metadata and sample field paths, types, and examples.' It also distinguishes itself from siblings by naming summarize_network (group_by field selection) and verify_database (integrity), so an agent can route without opening other schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use: 'Use this to choose fields, filter paths, or a summarize_network group_by field.' It also names an exclusion case by directing integrity checks to verify_database instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
install_databaseInstall a database from a URLADestructive
Download, validate, and load a database from an HTTP or HTTPS URL. Use install_edition, when available, for MaxMind editions with managed updates. Accepts MMDB, gzip, tar, tar.gz, or ZIP with exactly one MMDB. Downloads and expanded data are limited to 1 GiB. Uses the configured download folder, or the first folder in directory mode. Existing files require overwrite: true and are replaced only after validation. Does not use MaxMind credentials or save the URL for updates.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Database download URL. Requests can reach any HTTP(S) host accessible to this server. | |
| database | Yes | Destination filename ending in .mmdb, without a directory path. A name loaded from another folder is rejected, even with overwrite. MaxMind updates can replace imports named after configured or API-installed editions. | |
| overwrite | No | Replace an existing database with this name. Defaults to false. |
Output Schema
| Name | Required | Description |
|---|---|---|
| size | No | |
| error | No | |
| updated | Yes | |
| database | Yes | |
| last_update | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructive, openWorld and non-idempotent, but the description adds substantial behavior beyond them: accepted formats, the exactly-one-MMDB constraint, a 1 GiB cap on download and expanded data, the destination folder rule (configured folder vs. first folder in directory mode), and the replace-only-after-validation ordering. That is precisely the context needed to call a destructive import safely.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Five sentences, front-loaded with the core action and then descending into constraints, limits, and caveats in priority order. Dense but every sentence carries a distinct constraint; only the format enumeration and the folder-mode clause could be trimmed slightly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, open-world install operation with an output schema already documenting returns, the description covers formats, size limits, overwrite semantics, validation ordering, and credential behavior. Nothing an agent needs in order to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 above baseline by tying overwrite to the existence check ('Existing files require overwrite: true') and by explaining which folder the database parameter is resolved into. The remaining gap is minor: it does not restate the no-directory-path / .mmdb suffix rule that the schema carries.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific three-step verb chain (download, validate, load) against a specific resource (database from HTTP/HTTPS URL). It also names the sibling it is not (install_edition) and the condition that selects that sibling, so an agent can distinguish them without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent to install_edition 'when available, for MaxMind editions with managed updates,' and closes with a negative exclusion ('Does not use MaxMind credentials or save the URL for updates'). This gives when-to-use, when-not-to-use, and the alternative in one pass.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_databasesList databasesARead-onlyIdempotent
List loaded databases, their metadata, download status, and setup instructions. Call this first to choose exact database filenames for other tools. An empty list can mean the initial download is still running. If status is downloading, wait and call again without starting another update.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| status | Yes | |
| update | No | |
| message | Yes | |
| databases | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and closed-world access, so the safety profile is covered. The description adds genuinely non-obvious behavior: an empty list may mean a download is in flight, and a 'downloading' status means wait-and-repoll rather than triggering another update. Lacks any note on list size or staleness, so not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each doing distinct work: what it returns, when to call it, and how to interpret an anomalous result. Front-loaded with the call-first instruction and free of repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
A zero-parameter, read-only discovery tool with full annotation coverage and an output schema; the description covers the only real ambiguities (empty result, downloading status). Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate; baseline is 4. The description correctly implies the tool is unfiltered and takes no input to narrow results.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List loaded databases') and enumerates what comes back: metadata, download status, setup instructions. It is clearly separable from siblings like inspect_database or install_database, which operate on a single already-chosen database.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit ordering rule ('Call this first to choose exact database filenames for other tools') that routes the agent before it reaches inspect/verify/compare. It also covers the edge case where an empty list is expected, though it does not explicitly name which sibling to invoke next.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_ipLook up an IP addressARead-onlyIdempotent
Look up one IP address in local MMDB databases. Returns the matching record and network, with found=false when no record matches. Use lookup_ips for a batch of addresses or lookup_network to enumerate records in a CIDR.
| Name | Required | Description | Default |
|---|---|---|---|
| ip | Yes | IPv4 or IPv6 address, for example 8.8.8.8 or 2001:4860:4860::8888. | |
| fields | No | Optional field paths. Returns an object keyed by each selected path. Use dots for map keys, numeric array indexes, or $ for the whole record. Omit or use [] for full records. Repeat on each page. | |
| database | No | Exact filename from list_databases. Omit to query all loaded databases. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ip | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, non-open-world, so the safety profile is covered. The description adds genuinely new behavior: matching record and network are returned and a found=false sentinel signals no match, plus 'local MMDB' implies offline/no-auth lookup. Strong added context without contradicting annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with zero filler; the core action and return semantics come first, and the sibling routing is packed into a single final sentence. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the description need not enumerate return fields, yet it still supplies the not-found sentinel and offline DB context. Combined with annotations and full schema coverage, an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so all three parameters (ip, fields, database) are already documented including format examples and dotted-path semantics. The description adds nothing parameter-specific, so the baseline 3 for schema-does-the-work applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (look up) and resource (one IP address) with scope 'one' that distinguishes it from batch and CIDR siblings. Names the specific alternatives (lookup_ips, lookup_network) so an agent can route without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says to use lookup_ips for a batch of addresses and lookup_network to enumerate a CIDR, giving clear when-to-use-this vs when-to-use-alternative conditions. No inference required from the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_ipsLook up IP addressesARead-onlyIdempotent
Look up a batch of IP addresses in local MMDB databases. Each result contains the matching record and network, found=false for no match, or an error for that address. Other addresses are still processed after an error. Use lookup_ip for a single address.
| Name | Required | Description | Default |
|---|---|---|---|
| ips | Yes | IPv4 or IPv6 addresses to look up. Results preserve input order, including duplicate addresses. | |
| fields | No | Optional field paths. Returns an object keyed by each selected path. Use dots for map keys, numeric array indexes, or $ for the whole record. Omit or use [] for full records. Repeat on each page. | |
| database | No | Exact filename from list_databases. Omit to query all loaded databases. |
Output Schema
| Name | Required | Description |
|---|---|---|
| results | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, closed-world behavior, but the description adds genuinely new contract details: per-address failure isolation ('Other addresses are still processed after an error') and the found=false semantics for misses. It does not cover pagination or result-size limits, which keeps it from a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the primary action and scope, followed by result semantics and the sibling routing note. Every sentence carries information and none repeats the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value structure need not be described, yet the description still gives the key outcome variants (match record+network, found=false, per-address error). Combined with annotations and full schema coverage, an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and all three parameters (ips, fields, database) are documented in the schema itself, including ordering/duplicate behavior and field-path syntax. The description adds no parameter-level detail beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (look up), resource (batch of IP addresses), and scope (local MMDB databases). It also distinguishes itself from the sibling lookup_ip by explicitly noting the single-address alternative, so an agent can route without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Directly names the alternative tool ('Use lookup_ip for a single address') along with the condition that selects it (batch vs. single). The batch framing plus the explicit alternative leaves no ambiguity about when this tool is the right choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_networkQuery a networkARead-only
Find stored network records overlapping a CIDR, with optional filters and field selection. Returned networks may extend beyond the requested CIDR. Use lookup_range for start/end bounds or summarize_network for grouped counts. Repeat the network and database on each page. Stop when has_more is false.
| Name | Required | Description | Default |
|---|---|---|---|
| fields | No | Optional field paths. Returns an object keyed by each selected path. Use dots for map keys, numeric array indexes, or $ for the whole record. Omit or use [] for full records. Repeat on each page. | |
| filters | No | Conditions on record fields. For example, [{"field":"autonomous_system_number","operator":"equals","value":13335}]. Omit for no filtering on a new query. On paginated queries, omit to retain the original filters. | |
| network | Yes | IPv4 or IPv6 CIDR to scan, for example 192.168.1.0/24 or 2001:db8::/32. Broad queries may scan many records. | |
| database | No | Exact filename from list_databases. Required when more than one database is loaded. Repeat the same name on each page. | |
| filter_mode | No | Combine filters with and (all must match) or or (any can match). Defaults to and for a new query. Omit when paging to retain the original mode. | |
| iterator_id | No | ID from the previous page. Omit on the first request. Send with the latest resume_token to continue if the iterator expires. | |
| max_results | No | Maximum matching records to return on this page. Use a smaller page to reduce response size. | |
| resume_token | No | Token from the previous page, used if iterator_id is missing or expired. Omit on the first request. If the database build changed, start a new query. |
Output Schema
| Name | Required | Description |
|---|---|---|
| results | Yes | |
| has_more | Yes | True when another matching record exists. Continue with the same query parameters. |
| iterator_id | Yes | Identifier for continuing this live query with the same parameters. |
| resume_token | Yes | Token for resuming after the last returned record if the live iterator expires. |
| total_matched | Yes | Cumulative matching records returned across pages, not the count on this page. |
| total_processed | Yes | Cumulative records processed across pages, including nonmatching records scanned ahead to find the next match. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered; the description adds genuinely new behavior — that returned networks may extend beyond the requested CIDR, and that network/database must be re-sent on each page. These are non-obvious semantics an agent could not infer from the annotations and would only partially get from the schema. Not full marks because it does not surface the cost of broad scans or iterator expiration (both only implied in the schema).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, front-loaded with purpose, then the caveat, then the alternatives, then the paging contract. No filler and nothing repeated; each sentence carries a distinct decision-relevant fact.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter, paginated query tool with an output schema and full annotation coverage, the description gives exactly the missing context: overlap semantics, sibling routing, and the pagination loop termination condition. Nothing an agent needs in order to call it correctly is absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and each parameter carries a detailed description including paging retention rules, so the schema does the heavy lifting. The description's only parameter-level contribution is repeating that network and database must be repeated per page, which is largely restated from the schema. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — find stored network records — plus the defining scope condition (overlapping a CIDR) and the optional filters/field selection. It immediately distinguishes itself from lookup_range and summarize_network, so an agent can route correctly without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the two alternatives and the condition that selects each (start/end bounds → lookup_range, grouped counts → summarize_network). It also gives a paging usage rule (repeat network/database per page, stop when has_more is false), so both tool choice and call sequencing are covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_rangeQuery an address rangeARead-only
Find stored network records overlapping an inclusive start/end IP range, with optional filters and field selection. Use lookup_network when the bounds are a CIDR. Returns each overlapping network once, including networks extending beyond the bounds. Repeat the endpoints and database on each page. Stop when has_more is false.
| Name | Required | Description | Default |
|---|---|---|---|
| end_ip | Yes | Last address to include, for example 192.0.2.200. Must be at or after start_ip in the same address family, without a zone identifier. | |
| fields | No | Optional field paths. Returns an object keyed by each selected path. Use dots for map keys, numeric array indexes, or $ for the whole record. Omit or use [] for full records. Repeat on each page. | |
| filters | No | Conditions on record fields. For example, [{"field":"autonomous_system_number","operator":"equals","value":13335}]. Omit for no filtering on a new query. On paginated queries, omit to retain the original filters. | |
| database | No | Exact filename from list_databases. Required when more than one database is loaded. Repeat the same name on each page. | |
| start_ip | Yes | First IPv4 or IPv6 address to include, for example 192.0.2.10. Zone identifiers are not supported. | |
| filter_mode | No | Combine filters with and (all must match) or or (any can match). Defaults to and for a new query. Omit when paging to retain the original mode. | |
| iterator_id | No | ID from the previous page. Omit on the first request. Send with the latest resume_token to continue if the iterator expires. | |
| max_results | No | Maximum matching records to return on this page. Use a smaller page to reduce response size. | |
| resume_token | No | Token from the previous page, used if iterator_id is missing or expired. Omit on the first request. If the database build changed, start a new query. |
Output Schema
| Name | Required | Description |
|---|---|---|
| results | Yes | |
| has_more | Yes | True when another matching record exists. Continue with the same query parameters. |
| iterator_id | Yes | Identifier for continuing this live query with the same parameters. |
| resume_token | Yes | Token for resuming after the last returned record if the live iterator expires. |
| total_matched | Yes | Cumulative matching records returned across pages, not the count on this page. |
| total_processed | Yes | Cumulative records processed across pages, including nonmatching records scanned ahead to find the next match. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, non-destructive, non-idempotent behavior, and the description adds genuinely new semantics: deduplication ('Returns each overlapping network once') and the non-obvious inclusion of networks extending beyond the bounds. It further discloses pagination state handling and that a changed database build invalidates the iterator — context an agent could not get from the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, front-loaded with purpose and routing before pagination mechanics. Minor redundancy with per-parameter schema text ('Repeat the endpoints and database on each page'), but no sentence is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter paginated query tool with a full output schema, the description covers selection, the sibling alternative, overlap semantics, and the full pagination lifecycle. Return-value detail can be left to the output schema, and the one response field that matters for control flow (has_more) is named.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so start_ip, end_ip, fields, filters, database, max_results, iterator_id and resume_token are all documented in the schema. The description largely restates pagination rules already present per-parameter ('Repeat on each page'), adding only the has_more stop signal. Baseline 3 is appropriate when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Find stored network records overlapping an inclusive start/end IP range') and immediately scopes it with 'optional filters and field selection'. It also names the sibling it is not — lookup_network, for CIDR bounds — so an agent can route without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly gives the alternative and the condition that selects it: 'Use lookup_network when the bounds are a CIDR.' It also supplies the terminating condition ('Stop when has_more is false') and the pagination rule ('Repeat the endpoints and database on each page'), leaving little to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
summarize_networkSummarize a networkARead-onlyIdempotent
Group matching records by a scalar field, such as country.iso_code or autonomous_system_number. Count records and covered addresses within a CIDR. Use lookup_network to retrieve individual records. IPv4 aliases are excluded. Exceeding 10,000 scanned records or 100 groups returns an error. Use a smaller CIDR if a limit is reached.
| Name | Required | Description | Default |
|---|---|---|---|
| filters | No | Conditions on record fields. For example, [{"field":"autonomous_system_number","operator":"equals","value":13335}]. Omit for no filtering on a new query. On paginated queries, omit to retain the original filters. | |
| network | Yes | CIDR to summarize. Use an IPv4 prefix length of 8 or greater, or a native IPv6 prefix length of 32 or greater. | |
| database | Yes | Exact filename of a loaded database from list_databases. | |
| group_by | Yes | Path to a scalar field, for example country.iso_code or autonomous_system_number. Use inspect_database to find paths. Supports numeric array indexes and $ for a scalar record. Missing fields form a separate group. | |
| filter_mode | No | Combine filters with and (all must match) or or (any can match). Defaults to and for a new query. Omit when paging to retain the original mode. |
Output Schema
| Name | Required | Description |
|---|---|---|
| groups | Yes | |
| network | Yes | |
| database | Yes | |
| group_by | Yes | |
| matched_records | Yes | Stored network records passing the filters. Equals the sum of group record counts. |
| scanned_records | Yes | Stored network records examined before filtering, not individual IP addresses. |
| total_addresses | Yes | Number of addresses in the requested CIDR, including uncovered addresses. A decimal integer string preserves IPv6 precision. |
| matched_addresses | Yes | Addresses covered by matching records inside the CIDR, excluding IPv4 aliases. A decimal integer string preserves IPv6 precision. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, non-destructive safety. The description adds useful behavioral context beyond them: IPv4 aliases are excluded, and exceeding 10,000 scanned records or 100 groups returns an error.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short and front-loaded: it states the aggregation behavior first, then the alternative, exclusion, and limits. Every sentence adds useful information without waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and full schema description coverage, the description does not need to explain return values or every parameter. It supplies the key operational constraints, exclusion behavior, and sibling alternative needed to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters in detail. The description gives examples for group_by and network but does not add syntax or meaning beyond what the schema provides, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: group matching records by a scalar field and count records and covered addresses within a CIDR. It also distinguishes the tool from lookup_network by saying that lookup_network retrieves individual records.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly names the alternative for retrieving individual records and gives a concrete remedy when a limit is reached: use a smaller CIDR. That gives an agent clear routing and constraint guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_databaseVerify a databaseARead-onlyIdempotent
Check a loaded MMDB for structural corruption, such as after importing a database or encountering decode errors. Returns valid=true on success or a verification error. Use inspect_database for metadata and field samples. Only one verification runs at a time. Cancellation can stop a queued request, but verification runs to completion once started.
| Name | Required | Description | Default |
|---|---|---|---|
| database | Yes | Exact filename of a loaded database from list_databases. |
Output Schema
| Name | Required | Description |
|---|---|---|
| valid | Yes | |
| database | Yes | |
| completed_after_cancellation | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnly, idempotent, non-destructive), and the description adds non-obvious operational traits: only one verification runs at a time, cancellation can only stop a queued request, and a started verification runs to completion. It also states the success signal (valid=true) versus a verification error, which is behavior rather than schema restatement.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four tight sentences, front-loaded with purpose, then error context, then the sibling routing, then concurrency/cancellation limits. Each sentence carries distinct information an agent needs before calling.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the description nonetheless signals success/failure shape. Combined with the usage trigger, sibling routing, and concurrency/cancellation semantics, nothing needed to invoke this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is a single parameter and schema coverage is 100%, so the schema already documents 'database' fully, including that it must be an exact filename from list_databases. The description adds no syntax, format, or default information beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — checking a loaded MMDB for structural corruption — and immediately distinguishes itself from the sibling 'inspect_database for metadata and field samples'. An agent can tell verify_database apart from inspect_database without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit triggers ('after importing a database or encountering decode errors') and names the alternative tool plus the condition that selects it (metadata/field samples → inspect_database). Nothing about when to choose this tool is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
7 tool updates
v0.4.0- Changed
compare_databases1 field changed- added
Output schema / properties / scanned_segments / descriptionAdded value: +"Address segments examined on this page, including unchanged segments. Not cumulative across pages."
- Changed
inspect_database7 fields changed- added
Output schema / properties / fields_truncated / descriptionAdded value: +"True when field traversal limits or unaddressable keys omitted fields. Does not indicate whether all records were sampled." - added
Output schema / properties / metadata / properties / build_epoch / descriptionAdded value: +"Database build time in Unix seconds." - added
Output schema / properties / metadata / properties / node_count / descriptionAdded value: +"Number of search-tree nodes, not the count of data records or networks." - added
Output schema / properties / metadata / properties / record_size / descriptionAdded value: +"Size in bits of each search-tree record." - added
Output schema / properties / sample_limit / descriptionAdded value: +"Requested record sampling limit. Field traversal limits may stop sampling earlier." - added
Output schema / properties / sampled_records / descriptionAdded value: +"Network records sampled in database order, not a statistically representative sample." - added
Output schema / properties / schema_complete / descriptionAdded value: +"Always false. A field absent from this sample may exist in other records."
- Changed
install_database1 field changed- changed
Input schema / properties / database / descriptionPrevious value: -"Destination filename ending in .mmdb, without a directory path."New value: +"Destination filename ending in .mmdb, without a directory path. A name loaded from another folder is rejected, even with overwrite. MaxMind updates can replace imports named after configured or API-installed editions."
- Changed
list_databases2 fields changed- added
Output schema / properties / databases / items / properties / last_updated / descriptionAdded value: +"Database build time from MMDB metadata, not the time the file was downloaded or modified." - added
Output schema / properties / databases / items / properties / size / descriptionAdded value: +"Database file size in bytes."
- Changed
lookup_network5 fields changed- added
Output schema / properties / has_more / descriptionAdded value: +"True when another matching record exists. Continue with the same query parameters." - added
Output schema / properties / iterator_id / descriptionAdded value: +"Identifier for continuing this live query with the same parameters." - added
Output schema / properties / resume_token / descriptionAdded value: +"Token for resuming after the last returned record if the live iterator expires." - added
Output schema / properties / total_matched / descriptionAdded value: +"Cumulative matching records returned across pages, not the count on this page." - added
Output schema / properties / total_processed / descriptionAdded value: +"Cumulative records processed across pages, including nonmatching records scanned ahead to find the next match."
- Changed
lookup_range5 fields changed- added
Output schema / properties / has_more / descriptionAdded value: +"True when another matching record exists. Continue with the same query parameters." - added
Output schema / properties / iterator_id / descriptionAdded value: +"Identifier for continuing this live query with the same parameters." - added
Output schema / properties / resume_token / descriptionAdded value: +"Token for resuming after the last returned record if the live iterator expires." - added
Output schema / properties / total_matched / descriptionAdded value: +"Cumulative matching records returned across pages, not the count on this page." - added
Output schema / properties / total_processed / descriptionAdded value: +"Cumulative records processed across pages, including nonmatching records scanned ahead to find the next match."
- Changed
summarize_network7 fields changed- added
Output schema / properties / groups / items / properties / addresses / descriptionAdded value: +"Addresses covered by this group inside the requested CIDR. A decimal integer string preserves IPv6 precision." - added
Output schema / properties / groups / items / properties / missing / descriptionAdded value: +"True when the group_by field is absent. Distinguishes a missing field from a field containing null." - added
Output schema / properties / groups / items / properties / records / descriptionAdded value: +"Matching stored network records in this group, not individual IP addresses." - added
Output schema / properties / matched_addresses / descriptionAdded value: +"Addresses covered by matching records inside the CIDR, excluding IPv4 aliases. A decimal integer string preserves IPv6 precision." - added
Output schema / properties / matched_records / descriptionAdded value: +"Stored network records passing the filters. Equals the sum of group record counts." - added
Output schema / properties / scanned_records / descriptionAdded value: +"Stored network records examined before filtering, not individual IP addresses." - added
Output schema / properties / total_addresses / descriptionAdded value: +"Number of addresses in the requested CIDR, including uncovered addresses. A decimal integer string preserves IPv6 precision."
8 tool updates
v0.3.1- Changed
compare_databases5 fields changed- added
Input schema / properties / max_results / descriptionAdded value: +"Maximum changed address ranges to return on this page." - changed
Input schema / properties / network / descriptionPrevious value: -"IPv4 /8 or smaller, or IPv6 /32 or smaller"New value: +"CIDR to compare. Use an IPv4 prefix length of 8 or greater, or a native IPv6 prefix length of 32 or greater. Repeat on each page." - added
Input schema / properties / new_database / descriptionAdded value: +"Comparison database's exact filename from list_databases. Supplies the after values. Both databases must be loaded." - added
Input schema / properties / old_database / descriptionAdded value: +"Baseline database's exact filename from list_databases. Supplies the before values." - added
Input schema / properties / resume_token / descriptionAdded value: +"Token from the previous page. Omit on the first request. Repeat both database names and network. If either loaded database changed, start a new comparison."
- Changed
inspect_database2 fields changed- added
Input schema / properties / database / descriptionAdded value: +"Exact filename of a loaded database from list_databases." - added
Input schema / properties / sample_size / descriptionAdded value: +"Maximum network records to sample. Larger samples may reveal more fields. Sampling can stop early at internal field limits."
- Changed
lookup_ip2 fields changed- changed
Input schema / properties / database / descriptionPrevious value: -"Specific database to query (optional)"New value: +"Exact filename from list_databases. Omit to query all loaded databases." - changed
Input schema / properties / ip / descriptionPrevious value: -"IP address to lookup"New value: +"IPv4 or IPv6 address, for example 8.8.8.8 or 2001:4860:4860::8888."
- Changed
lookup_ips2 fields changed- changed
Input schema / properties / database / descriptionPrevious value: -"Specific database from list_databases (optional)"New value: +"Exact filename from list_databases. Omit to query all loaded databases." - added
Input schema / properties / ips / descriptionAdded value: +"IPv4 or IPv6 addresses to look up. Results preserve input order, including duplicate addresses."
- Changed
lookup_network10 fields changed- changed
Input schema / properties / database / descriptionPrevious value: -"Database name from list_databases; required when more than one is loaded"New value: +"Exact filename from list_databases. Required when more than one database is loaded. Repeat the same name on each page." - changed
Input schema / properties / filter_mode / descriptionPrevious value: -"How to combine filters: 'and' or 'or' (default: 'and')"New value: +"Combine filters with and (all must match) or or (any can match). Defaults to and for a new query. Omit when paging to retain the original mode." - changed
Input schema / properties / filters / descriptionPrevious value: -"Filters for a new query; omit to keep filters when continuing a query"New value: +"Conditions on record fields. For example, [{\"field\":\"autonomous_system_number\",\"operator\":\"equals\",\"value\":13335}]. Omit for no filtering on a new query. On paginated queries, omit to retain the original filters." - added
Input schema / properties / filters / items / properties / field / descriptionAdded value: +"Field path from inspect_database, such as country.iso_code. Use dots for nested keys or numeric array indexes, or $ for the whole record." - added
Input schema / properties / filters / items / properties / operator / descriptionAdded value: +"Comparison to apply. eq, ne, gt, lt, gte, and lte are aliases for the corresponding equality and ordering operators." - added
Input schema / properties / filters / items / properties / value / descriptionAdded value: +"Comparison value. Use an array for in/not_in, a Go regular expression string for regex, or a substring for contains. For exists, true tests for a non-null field and false tests for a missing or null field. Ordering comparisons use numbers." - changed
Input schema / properties / iterator_id / descriptionPrevious value: -"Resume existing iterator (fast path)"New value: +"ID from the previous page. Omit on the first request. Send with the latest resume_token to continue if the iterator expires." - changed
Input schema / properties / max_results / descriptionPrevious value: -"Page size from 1 to 1000"New value: +"Maximum matching records to return on this page. Use a smaller page to reduce response size." - changed
Input schema / properties / network / descriptionPrevious value: -"CIDR network to scan (e.g., '192.168.1.0/24')"New value: +"IPv4 or IPv6 CIDR to scan, for example 192.168.1.0/24 or 2001:db8::/32. Broad queries may scan many records." - changed
Input schema / properties / resume_token / descriptionPrevious value: -"Fallback token if iterator expired"New value: +"Token from the previous page, used if iterator_id is missing or expired. Omit on the first request. If the database build changed, start a new query."
- Changed
lookup_range11 fields changed- changed
Input schema / properties / database / descriptionPrevious value: -"Database name from list_databases; required when more than one is loaded"New value: +"Exact filename from list_databases. Required when more than one database is loaded. Repeat the same name on each page." - added
Input schema / properties / end_ip / descriptionAdded value: +"Last address to include, for example 192.0.2.200. Must be at or after start_ip in the same address family, without a zone identifier." - changed
Input schema / properties / filter_mode / descriptionPrevious value: -"How to combine filters: 'and' or 'or' (default: 'and')"New value: +"Combine filters with and (all must match) or or (any can match). Defaults to and for a new query. Omit when paging to retain the original mode." - changed
Input schema / properties / filters / descriptionPrevious value: -"Filters for a new query; omit to keep filters when continuing a query"New value: +"Conditions on record fields. For example, [{\"field\":\"autonomous_system_number\",\"operator\":\"equals\",\"value\":13335}]. Omit for no filtering on a new query. On paginated queries, omit to retain the original filters." - added
Input schema / properties / filters / items / properties / field / descriptionAdded value: +"Field path from inspect_database, such as country.iso_code. Use dots for nested keys or numeric array indexes, or $ for the whole record." - added
Input schema / properties / filters / items / properties / operator / descriptionAdded value: +"Comparison to apply. eq, ne, gt, lt, gte, and lte are aliases for the corresponding equality and ordering operators." - added
Input schema / properties / filters / items / properties / value / descriptionAdded value: +"Comparison value. Use an array for in/not_in, a Go regular expression string for regex, or a substring for contains. For exists, true tests for a non-null field and false tests for a missing or null field. Ordering comparisons use numbers." - changed
Input schema / properties / iterator_id / descriptionPrevious value: -"Resume existing iterator (fast path)"New value: +"ID from the previous page. Omit on the first request. Send with the latest resume_token to continue if the iterator expires." - changed
Input schema / properties / max_results / descriptionPrevious value: -"Page size from 1 to 1000"New value: +"Maximum matching records to return on this page. Use a smaller page to reduce response size." - changed
Input schema / properties / resume_token / descriptionPrevious value: -"Fallback token if iterator expired"New value: +"Token from the previous page, used if iterator_id is missing or expired. Omit on the first request. If the database build changed, start a new query." - added
Input schema / properties / start_ip / descriptionAdded value: +"First IPv4 or IPv6 address to include, for example 192.0.2.10. Zone identifiers are not supported."
- Changed
summarize_network8 fields changed- added
Input schema / properties / database / descriptionAdded value: +"Exact filename of a loaded database from list_databases." - changed
Input schema / properties / filter_mode / descriptionPrevious value: -"How to combine filters: 'and' or 'or' (default: 'and')"New value: +"Combine filters with and (all must match) or or (any can match). Defaults to and for a new query. Omit when paging to retain the original mode." - changed
Input schema / properties / filters / descriptionPrevious value: -"Filters for a new query; omit to keep filters when continuing a query"New value: +"Conditions on record fields. For example, [{\"field\":\"autonomous_system_number\",\"operator\":\"equals\",\"value\":13335}]. Omit for no filtering on a new query. On paginated queries, omit to retain the original filters." - added
Input schema / properties / filters / items / properties / field / descriptionAdded value: +"Field path from inspect_database, such as country.iso_code. Use dots for nested keys or numeric array indexes, or $ for the whole record." - added
Input schema / properties / filters / items / properties / operator / descriptionAdded value: +"Comparison to apply. eq, ne, gt, lt, gte, and lte are aliases for the corresponding equality and ordering operators." - added
Input schema / properties / filters / items / properties / value / descriptionAdded value: +"Comparison value. Use an array for in/not_in, a Go regular expression string for regex, or a substring for contains. For exists, true tests for a non-null field and false tests for a missing or null field. Ordering comparisons use numbers." - changed
Input schema / properties / group_by / descriptionPrevious value: -"Field path, array index, or $ for a scalar record. Missing fields form a separate group."New value: +"Path to a scalar field, for example country.iso_code or autonomous_system_number. Use inspect_database to find paths. Supports numeric array indexes and $ for a scalar record. Missing fields form a separate group." - changed
Input schema / properties / network / descriptionPrevious value: -"IPv4 /8 or smaller, or IPv6 /32 or smaller"New value: +"CIDR to summarize. Use an IPv4 prefix length of 8 or greater, or a native IPv6 prefix length of 32 or greater."
- Changed
verify_database1 field changed- added
Input schema / properties / database / descriptionAdded value: +"Exact filename of a loaded database from list_databases."
10 tool updates
v0.1.0- First observed
compare_databases - First observed
inspect_database - First observed
install_database - First observed
list_databases - First observed
lookup_ip - First observed
lookup_ips - First observed
lookup_network - First observed
lookup_range - First observed
summarize_network - First observed
verify_database
TDQS
Scored across 10 tools
Tools are mostly distinct: lookup_ip vs lookup_ips (batch), lookup_network (CIDR) vs lookup_range (start/end), and summarize vs lookup are clearly differentiated by descriptions. The only mild overlap is lookup_network/lookup_range and lookup_ip/lookup_ips, but each description explicitly points to the alternative tool, so misselection is unlikely.
All ten tools follow a consistent snake_case verb_noun pattern (compare_databases, lookup_network, install_database, verify_database, etc.). The only variation is singular vs plural noun (lookup_ip/lookup_ips, compare_databases), which is semantically meaningful and consistent.
Ten tools is well-scoped for a MaxMindDB server: install, list, inspect, verify, multiple lookup modes, summarize, and compare each earn a distinct role. No redundant or filler tools are present.
The surface covers the full lifecycle for loaded databases: install, list, inspect, verify, multiple lookup modes, summarize, and compare. Minor gaps remain—no explicit unload/delete of a loaded database and no bulk export—but core workflows are fully supported.
Maintenance
Related MCP Connectors
IPInfo MCP — wraps ipinfo.io (free tier, no auth required for basic usage)
Resolves IP autonomous system numbers (ASN) and geographic coordinates.
IPStack MCP Adapter turns IPStack's REST APIs into Model Context Protocol tools so any MCP-compatible client can call them directly in conversation. The first release ships IPStack IP geolocation and security lookups (single IP, caller's IP, and bulk). Additional APILayer services are added by registering them in a single config file, so the catalog grows without client-side changes.
MAC address and OUI vendor lookup over Model Context Protocol.
Related MCP Servers
- AlicenseAqualityCmaintenanceA Model Context Protocol server that retrieves detailed geographic information about IP addresses using the ipinfo.io API, helping determine user location and network details.534 PyPI44MIT
- AlicenseNot gradedqualityAmaintenanceEnables LLMs to query IP addresses against free MaxMind GeoLite2 geolocation databases.MIT
- AlicenseAqualityCmaintenanceA Model Context Protocol server that enables LLMs to perform IP geolocation, reverse geocoding, and detect the host's public IP without requiring API keys.37 npmMIT

netloc8-mcpofficial
FlicenseAqualityCmaintenanceModel Context Protocol server for the NetLoc8 IP geolocation API. Gives AI assistants access to country/city lookup, timezone reconciliation, and IP utilities.7-