{
  "data": {
    "a": {
      "slug": "nextbillion",
      "name": "NextBillion.ai",
      "vendor": "NextBillion.ai Pte. Ltd.",
      "vendorUrl": "https://nextbillion.ai",
      "kind": "http-api",
      "category": "maps",
      "summary": "NextBillion.ai is a Singapore mapping and routing platform for fleets and logistics. Its REST APIs cover directions, distance matrices, route optimisation, navigation, geocoding and places, with a hosted MCP server for agents.",
      "url": "https://www.anchorterminal.com/tools/nextbillion",
      "markdownUrl": "https://www.anchorterminal.com/tools/nextbillion.md",
      "slimMarkdownUrl": "https://www.anchorterminal.com/tools/nextbillion.min.md",
      "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/nextbillion.json",
      "dns": "nextbillion.grade.anchorterminal.com",
      "repo": "https://github.com/nextbillion-ai/nextbillion-mcp",
      "transports": [
        "http",
        "streamable-http"
      ],
      "remoteUrl": "https://mcp.nextbillion.io",
      "packages": [],
      "auth": "mixed",
      "authNotes": "REST APIs take a 32-character key as the `key` query parameter, issued in the console at console.nextbillion.ai or by emailing support. Keys can carry an IP allowlist. The hosted MCP server is its own OAuth 2.1 authorisation server with PKCE: a sign-in page asks for the key once and seals it into the tokens. Scripts can send the key as a Bearer header to the MCP server instead.",
      "pricing": "paid",
      "pricingNotes": "By quote. Annual licences priced per order, per asset or per API call, paid monthly or yearly, with extra usage at a rate set in the plan. A 7-day free trial with an API key and no credit card.",
      "priceSummary": "Paid",
      "where": "hosted",
      "x402": {
        "level": "no",
        "evidence": "No x402, MPP or L402 in the docs, llms.txt, the MCP server source or the pricing page (checked 2026-11-06). Contracts are invoiced.",
        "endpoints": []
      },
      "toolCount": 27,
      "popularity": {
        "githubStars": null,
        "npmWeekly": null,
        "pypiWeekly": null,
        "asOf": "2026-11-06"
      },
      "docsUrl": "https://docs.nextbillion.ai/",
      "llmsTxt": "https://docs.nextbillion.ai/llms.txt",
      "capabilities": [
        "geo.routing",
        "geo.geocode",
        "geo.reverse",
        "geo.places",
        "geo.tiles"
      ],
      "tags": [
        "hosted",
        "mcp",
        "remote-mcp",
        "oauth",
        "api-key",
        "llms-txt",
        "official",
        "sales-led",
        "annual-contract",
        "free-trial",
        "no-card",
        "enterprise",
        "android",
        "ios",
        "closed-source"
      ],
      "lastRelease": "2026-10-30",
      "graded": true,
      "anchor": {
        "graded": true,
        "score": 55.4,
        "grade": "C",
        "agentReady": false,
        "rank": 874,
        "ranked": true,
        "rankOf": 1510,
        "categoryRank": 15,
        "methodology": "0.7",
        "run": "2026-10-01",
        "scores": {
          "ergonomics": 77,
          "maintenance": 73,
          "payments": 20,
          "reliability": 45,
          "schema": 73,
          "security": 46,
          "transparency": 58
        },
        "pending": [
          "performance",
          "tasks"
        ],
        "assessment": {
          "confidence": "medium",
          "date": "2026-11-06"
        },
        "negative": 0,
        "verdict": "NextBillion.ai covers routing, distance matrices, route optimisation, geocoding and places, and runs a hosted MCP server with 27 read-only annotated tools and OAuth sign-in. Pricing is by quote on annual licences, the REST API key travels in the query string, and no OpenAPI spec, API changelog or readable status history was found.",
        "bestFor": "Fleet and delivery routing, distance matrices and route optimisation with truck profiles, plus geocoding and POI search, for companies ready for an annual contract.",
        "strengths": [
          "Hosted MCP server at mcp.nextbillion.io with OAuth 2.1 and PKCE, and every API tool annotated read-only and idempotent",
          "Routing, distance matrix, isochrone, route optimisation, geocoding and places APIs under one key",
          "llms.txt, llms-full.txt and Markdown versions of the docs pages",
          "Documented rate limit of 2,400 queries a minute and a per-endpoint error table",
          "7-day free trial with no credit card"
        ],
        "weaknesses": [
          "Pricing is by quote on annual licences, with no public unit prices",
          "The REST APIs take the key only as a `key` query parameter",
          "No OpenAPI spec or API changelog found",
          "No security.txt or vulnerability disclosure policy, and no SLA",
          "The status page renders only in a browser, so its history couldn't be read"
        ],
        "agentNotes": [
          "Connect through https://mcp.nextbillion.io so the key stays in a Bearer header or OAuth token rather than in request URLs",
          "Use the geometry tools only for straight-line questions; use directions or distance_matrix for travel time",
          "Batch up to 100 geocodes with geocode_batch instead of one call per address",
          "On 429 the quota or the 2,400-a-minute limit is reached; slow down and tell the user if credits are spent",
          "Search the docs with the MCP documentation tools before guessing a parameter"
        ],
        "metrics": {
          "kind": "remote",
          "measured": false
        },
        "reviewCount": 0,
        "avgRating": 0,
        "history": [
          {
            "basis": "public evidence",
            "confidence": "medium",
            "grade": "C",
            "methodology": "0.7",
            "pending": [
              "performance",
              "tasks"
            ],
            "run": "2026-10-01",
            "runLabel": "October 2026 research run",
            "score": 55.4
          }
        ],
        "editorialScores": {
          "ergonomics": 77,
          "maintenance": 73,
          "payments": 20,
          "reliability": 45,
          "schema": 73,
          "security": 46,
          "transparency": 43
        },
        "provenanceScore": 73,
        "checked": {
          "categories": {
            "ergonomics": "2026-11-06",
            "maintenance": "2026-11-06",
            "payments": "2026-11-06",
            "reliability": "2026-11-06",
            "schema": "2026-11-06",
            "security": "2026-11-06",
            "transparency": "2026-11-06"
          },
          "last": "2026-11-06",
          "oldest": "2026-11-06",
          "stale": false,
          "staleAfterDays": 90
        }
      },
      "connect": {
        "http": "curl \"https://api.nextbillion.io/geocode?q=market\u0026at=40.720685,-74.044772\u0026in=countryCode:USA\u0026key=$NBAI_API_KEY\"",
        "claudeCode": "claude mcp add --transport http nextbillion https://mcp.nextbillion.io",
        "config": {
          "mcpServers": {
            "nextbillion": {
              "url": "https://mcp.nextbillion.io"
            }
          }
        }
      },
      "letme": {
        "capability": "https://letme.dev/geo.routing",
        "tool": "https://letme.dev/nextbillion"
      },
      "area": "everyday",
      "provenance": {
        "legalEntity": "NextBillion.ai Pte. Ltd.",
        "domain": "nextbillion.ai",
        "domainRegistered": "2019-08-07",
        "endpointOnVendorDomain": false,
        "terms": "https://nextbillion.ai/terms-of-service",
        "privacy": "https://nextbillion.ai/privacy",
        "statusPage": "https://status.nextbillion.io",
        "changelog": "https://github.com/nextbillion-ai/nextbillion-mcp/blob/main/CHANGELOG.md",
        "securityTxt": "none",
        "checked": "2026-11-06",
        "notes": [
          "The terms name NextBillion.ai Pte. Ltd. and choose Singapore law, with mediation first. The privacy policy names Nextbillion.AI Pte. Ltd. and its affiliates.",
          "The APIs and MCP server run on nextbillion.io, a second domain of the same company, while the site and docs are on nextbillion.ai.",
          "nextbillion.ai/.well-known/security.txt and /security return 404. No vulnerability disclosure policy was found.",
          "The changelog listed is the MCP server's; no changelog for the REST APIs was found.",
          "RDAP gives nextbillion.ai a registration date of 7 August 2019. robots.txt on nextbillion.ai and docs.nextbillion.ai allows these pages, and docs robots.txt allows /llms*.txt.",
          "The acceptable use clause bars reselling or making the services available to third parties. No clause on automated access to the website was found."
        ],
        "score": 73
      },
      "pageJsonUrl": "https://www.anchorterminal.com/tools/nextbillion.json",
      "live": {
        "slug": "nextbillion",
        "probe": {
          "target": "https://mcp.nextbillion.io",
          "method": "get",
          "lastAt": "2026-11-07T19:22:21.654883516Z",
          "lastOk": true,
          "lastStatus": 405,
          "lastMs": 407,
          "authRequired": false,
          "uptime24h": 100,
          "uptime30d": 100,
          "p50ms24h": 383,
          "p95ms24h": 503,
          "samples24h": 210,
          "samples30d": 210,
          "days": [
            {
              "date": "2026-11-06",
              "probes": 13,
              "ok": 13
            },
            {
              "date": "2026-11-07",
              "probes": 197,
              "ok": 197
            }
          ]
        },
        "vendorStatus": {
          "page": "https://status.nextbillion.io",
          "indicator": "unknown",
          "summary": "no machine-readable status found",
          "checkedAt": "2026-11-07T04:48:15.654905456Z"
        },
        "versions": [
          {
            "registry": "github",
            "name": "nextbillion-ai/nextbillion-mcp",
            "version": "v0.5.3",
            "released": "2026-10-30",
            "seenAt": "2026-11-06T23:49:07.315516581Z"
          }
        ],
        "githubStars": 0,
        "securityTxt": {
          "url": "https://nextbillion.ai/.well-known/security.txt",
          "state": "none",
          "checkedAt": "2026-11-07T16:00:46.65718407Z"
        },
        "llmsTxt": {
          "url": "https://docs.nextbillion.ai/llms.txt",
          "ok": true,
          "status": 200,
          "checkedAt": "2026-11-07T15:33:19.797741277Z"
        },
        "pages": [
          {
            "url": "https://raw.githubusercontent.com/nextbillion-ai/nextbillion-mcp/main/CHANGELOG.md",
            "kind": "changelog",
            "status": 200,
            "checkedAt": "2026-11-07T14:22:12.997536111Z",
            "changedAt": "0001-01-01T00:00:00Z",
            "fingerprint": "7a2ac2407039"
          },
          {
            "url": "https://nextbillion.ai/privacy",
            "kind": "privacy",
            "status": 200,
            "checkedAt": "2026-11-07T14:14:59.152376992Z",
            "changedAt": "0001-01-01T00:00:00Z",
            "fingerprint": "39ac967d5c22"
          },
          {
            "url": "https://nextbillion.ai/terms-of-service",
            "kind": "terms",
            "status": 200,
            "checkedAt": "2026-11-07T14:15:02.368911623Z",
            "changedAt": "0001-01-01T00:00:00Z",
            "fingerprint": "898d2ccdb595"
          }
        ],
        "mcpTools": {
          "url": "https://mcp.nextbillion.io",
          "checkedAt": "2026-11-07T01:46:25.213284458Z",
          "status": "ok",
          "protocol": "2026-07-28",
          "tools": [
            {
              "name": "autocomplete",
              "title": "Autocomplete",
              "description": "Complete a partial address or administrative-area prefix into full valid addresses (e.g. \"stat\" -\u003e \"State Capitol, ...\"). Use for prefix completion as the user types; use autosuggest for typo-tolerant fuzzy suggestions and geocode_forward for a full address. Parameters: query (required); optional near {latitude, longitude}, radius_m (with near), country_codes, bounding_box {west, south, east, north}, limit, language, view. Example: {\"query\": \"stat\", \"near\": {\"latitude\": 35.4769, \"longitude\": -97.4872}, \"limit\": 5}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "bounding_box": {
                    "additionalProperties": false,
                    "description": "Hard-limit results to this bounding box",
                    "properties": {
                      "east": {
                        "description": "Eastern longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      },
                      "north": {
                        "description": "Northern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "south": {
                        "description": "Southern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "west": {
                        "description": "Western longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "west",
                      "south",
                      "east",
                      "north"
                    ],
                    "type": "object"
                  },
                  "country_codes": {
                    "description": "Restrict results to these countries (ISO 3166-1 alpha-3 codes, e.g. [\"USA\",\"MEX\"])",
                    "items": {
                      "pattern": "^[A-Za-z]{3}$",
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "language": {
                    "description": "Result language as a BCP 47 tag, e.g. \"en-US\"",
                    "type": "string"
                  },
                  "limit": {
                    "description": "Maximum results (default 10)",
                    "maximum": 100,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "near": {
                    "additionalProperties": false,
                    "description": "Center of the search context; results are ranked around this point",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "query": {
                    "description": "Free-text search query",
                    "minLength": 1,
                    "type": "string"
                  },
                  "radius_m": {
                    "description": "With `near`: hard-limit results to this radius in meters",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991,
                    "type": "integer"
                  },
                  "view": {
                    "description": "Geopolitical view for disputed territories. Default: Unified (or the requester region)",
                    "enum": [
                      "Unified",
                      "AR",
                      "IL",
                      "IN",
                      "MA",
                      "PK",
                      "RU",
                      "TR",
                      "CN",
                      "TW"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "query"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "autosuggest",
              "title": "Autosuggest",
              "description": "Suggest address and place candidates from an incomplete or misspelled query (typo-tolerant, e.g. \"aqaurium\" still matches aquariums). Use for search-as-you-type; use autocomplete for strict prefix completion of valid addresses. Parameters: query (required); optional near {latitude, longitude}, radius_m (with near), country_codes, bounding_box {west, south, east, north}, limit, language, view. Example: {\"query\": \"aqauriums\", \"near\": {\"latitude\": 42.3501, \"longitude\": -71.0689}, \"limit\": 5}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "bounding_box": {
                    "additionalProperties": false,
                    "description": "Hard-limit results to this bounding box",
                    "properties": {
                      "east": {
                        "description": "Eastern longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      },
                      "north": {
                        "description": "Northern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "south": {
                        "description": "Southern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "west": {
                        "description": "Western longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "west",
                      "south",
                      "east",
                      "north"
                    ],
                    "type": "object"
                  },
                  "country_codes": {
                    "description": "Restrict results to these countries (ISO 3166-1 alpha-3 codes, e.g. [\"USA\",\"MEX\"])",
                    "items": {
                      "pattern": "^[A-Za-z]{3}$",
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "language": {
                    "description": "Result language as a BCP 47 tag, e.g. \"en-US\"",
                    "type": "string"
                  },
                  "limit": {
                    "description": "Maximum results (default 10)",
                    "maximum": 100,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "near": {
                    "additionalProperties": false,
                    "description": "Center of the search context; results are ranked around this point",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "query": {
                    "description": "Free-text search query",
                    "minLength": 1,
                    "type": "string"
                  },
                  "radius_m": {
                    "description": "With `near`: hard-limit results to this radius in meters",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991,
                    "type": "integer"
                  },
                  "view": {
                    "description": "Geopolitical view for disputed territories. Default: Unified (or the requester region)",
                    "enum": [
                      "Unified",
                      "AR",
                      "IL",
                      "IN",
                      "MA",
                      "PK",
                      "RU",
                      "TR",
                      "CN",
                      "TW"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "query"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "bbox",
              "title": "Bounding Box",
              "description": "The smallest latitude/longitude box around a set of points, a line or a polygon, optionally padded in metres — for example a viewport for static_map_image or a spatial filter. Handles shapes that straddle the antimeridian (reports crosses_antimeridian and the narrower box). Computed locally, no sign-in needed. Parameters: exactly one of points (array of {latitude, longitude}), line (array of points) or polygon (GeoJSON Polygon/MultiPolygon, isochrone Feature accepted); padding_meters (default 0). Returns min_latitude, min_longitude, max_latitude, max_longitude, crosses_antimeridian. Example: {\"points\": [{\"latitude\": 12.9716, \"longitude\": 77.5946}, {\"latitude\": 13.0827, \"longitude\": 80.2707}], \"padding_meters\": 500}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "line": {
                    "description": "A line as an array of {latitude, longitude} points (at least 2)",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 5000,
                    "minItems": 2,
                    "type": "array"
                  },
                  "padding_meters": {
                    "description": "Grow the box by this many metres on every side",
                    "maximum": 1000000,
                    "minimum": 0,
                    "type": "number"
                  },
                  "points": {
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "id": {
                          "description": "Optional label echoed back in the result",
                          "maxLength": 100,
                          "type": "string"
                        },
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 1000,
                    "minItems": 1,
                    "type": "array"
                  },
                  "polygon": {
                    "additionalProperties": {},
                    "description": "A GeoJSON Polygon or MultiPolygon geometry (coordinates in [longitude, latitude] order), or a Feature wrapping one — an isochrone contour can be passed as is",
                    "properties": {
                      "type": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "type"
                    ],
                    "type": "object"
                  }
                },
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "buffer",
              "title": "Buffer Zone Around a Point, Line or Polygon",
              "description": "Build the zone within a given straight-line distance of a point (a circle), a line (a corridor, e.g. 1 km along a route) or a polygon (grown outward, or shrunk inward with a negative distance). Geodesic on WGS84, computed locally, no sign-in needed. Returns a GeoJSON Polygon or MultiPolygon (a shrunk shape may split) with its area; an empty result is returned, not an error. Parameters: exactly one of point ({latitude, longitude}), line (array of points) or polygon (GeoJSON Polygon/MultiPolygon, isochrone Feature accepted); distance (number, negative only for polygon); units (default meters); steps (points per circle, default 16); area_units; max_vertices (default 500). Example: {\"line\": [{\"latitude\": 12.9716, \"longitude\": 77.5946}, {\"latitude\": 12.99, \"longitude\": 77.62}], \"distance\": 1, \"units\": \"kilometers\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "area_units": {
                    "description": "Area unit (default square_meters)",
                    "enum": [
                      "square_meters",
                      "square_kilometers",
                      "hectares",
                      "acres",
                      "square_miles",
                      "square_feet"
                    ],
                    "type": "string"
                  },
                  "distance": {
                    "description": "Buffer distance; negative shrinks a polygon inward",
                    "type": "number"
                  },
                  "line": {
                    "description": "Buffer around a line (a corridor)",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 5000,
                    "minItems": 2,
                    "type": "array"
                  },
                  "max_vertices": {
                    "description": "Simplify the returned shape to at most this many vertices (default 500); the result says when it was simplified",
                    "maximum": 5000,
                    "minimum": 16,
                    "type": "integer"
                  },
                  "point": {
                    "additionalProperties": false,
                    "description": "Buffer around a point (a geodesic circle)",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "polygon": {
                    "additionalProperties": {},
                    "description": "Buffer around or inside a polygon",
                    "properties": {
                      "type": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "type"
                    ],
                    "type": "object"
                  },
                  "steps": {
                    "description": "Vertices per quarter... per full circle (default 16)",
                    "maximum": 64,
                    "minimum": 4,
                    "type": "integer"
                  },
                  "units": {
                    "description": "Distance unit (default meters)",
                    "enum": [
                      "meters",
                      "kilometers",
                      "miles",
                      "feet",
                      "nautical_miles"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "distance"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "centroid",
              "title": "Centroid and Label Point of a Polygon",
              "description": "The area-weighted centre of a polygon and a label point that is guaranteed to lie inside it (the centroid of a C- or ring-shaped area falls outside; the label point does not). Computed locally, no sign-in needed. Parameters: polygon (GeoJSON Polygon/MultiPolygon, or an isochrone Feature). Returns centroid, label_point ({latitude, longitude}) and centroid_inside. Example: {\"polygon\": {\"type\": \"Polygon\", \"coordinates\": [[[77.59, 12.97], [77.61, 12.97], [77.61, 12.99], [77.59, 12.99], [77.59, 12.97]]]}}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "polygon": {
                    "additionalProperties": {},
                    "description": "A GeoJSON Polygon or MultiPolygon geometry (coordinates in [longitude, latitude] order), or a Feature wrapping one — an isochrone contour can be passed as is",
                    "properties": {
                      "type": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "type"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "polygon"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "directions",
              "title": "Directions",
              "description": "Calculate a route between an origin and a destination with optional waypoints; returns distance (meters), duration (seconds) and an encoded polyline per route, which static_route_map can draw. Use distance_matrix for many pairs. Documentation for this API is available through search_documentation. Parameters: origin, destination {latitude, longitude} (required); optional waypoints (max 200), mode (car | truck | motorcycle | bike | walk), service (\"flexible\" default: all options; \"fast\": car/truck only, lower latency), route_type, departure_time, avoid (soft), exclude (strict), road_info, honor_restrictions, alternatives, steps (fast only), geometry (polyline | polyline6), cross_border; truck options: truck_size_cm, truck_weight_kg, truck_axle_load, hazmat_type, emission_class; freight network: prefer \"truck_route\" + truck_type (rigid_truck | semi_trailer | b_double | road_train | generic_truck) for roads legal for that truck class, require \"truck_route\" to stay on it. Example: {\"origin\": {\"latitude\": 37.7749, \"longitude\": -122.4194}, \"destination\": {\"latitude\": 34.0522, \"longitude\": -118.2437}, \"mode\": \"truck\", \"prefer\": \"truck_route\", \"truck_type\": [\"b_double\"]}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "alternatives": {
                    "description": "Return up to 3 alternative routes (only without waypoints)",
                    "type": "boolean"
                  },
                  "avoid": {
                    "description": "Road features to avoid when alternatives exist. Fast service supports only toll/ferry/highway",
                    "items": {
                      "enum": [
                        "toll",
                        "highway",
                        "ferry",
                        "sharp_turn",
                        "uturn",
                        "service_road",
                        "left_turn",
                        "right_turn",
                        "tunnel",
                        "none"
                      ],
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "cross_border": {
                    "description": "Allow the route to cross international borders (region-dependent, flexible service only)",
                    "type": "boolean"
                  },
                  "departure_time": {
                    "description": "Departure as a UNIX timestamp in seconds, for typical-traffic routing (flexible only)",
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  },
                  "destination": {
                    "additionalProperties": false,
                    "description": "Route end (must be a routable land location)",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "emission_class": {
                    "description": "Engine emission class (EU regions, truck mode, flexible service only)",
                    "enum": [
                      "euro0",
                      "euro1",
                      "euro2",
                      "euro3",
                      "euro4",
                      "euro5",
                      "euro6",
                      "euro7",
                      "euro8",
                      "euro9"
                    ],
                    "type": "string"
                  },
                  "exclude": {
                    "description": "Strict filter: only routes that completely avoid these features are returned (error if none exists). Use `avoid` for a soft preference instead. Flexible service only",
                    "items": {
                      "enum": [
                        "toll",
                        "ferry",
                        "highway",
                        "service_road",
                        "uturn",
                        "sharp_turn",
                        "left_turn",
                        "right_turn"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "geometry": {
                    "description": "Route geometry encoding (default polyline, precision 5 — directly usable with static_route_map)",
                    "enum": [
                      "polyline",
                      "polyline6"
                    ],
                    "type": "string"
                  },
                  "hazmat_type": {
                    "description": "Hazardous cargo classes carried (truck mode, flexible service only)",
                    "items": {
                      "enum": [
                        "explosives",
                        "gas",
                        "flammable_liquid",
                        "flammable_gas",
                        "organic",
                        "toxic",
                        "radioactive",
                        "corrosive",
                        "other"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "honor_restrictions": {
                    "description": "When true, enforce restricted-area rules: no route is generated if origin, destination, or a waypoint is inside a restricted area. Default false: route anyway with a warning (flexible service only)",
                    "type": "boolean"
                  },
                  "mode": {
                    "description": "Travel mode (default car). Modes other than car/truck require service=flexible",
                    "enum": [
                      "car",
                      "truck",
                      "motorcycle",
                      "bike",
                      "walk"
                    ],
                    "type": "string"
                  },
                  "origin": {
                    "additionalProperties": false,
                    "description": "Route start (must be a routable land location)",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "prefer": {
                    "description": "Prioritise designated freight network roads (flexible service, mode truck). truck_type takes effect only together with this",
                    "enum": [
                      "truck_route"
                    ],
                    "type": "string"
                  },
                  "require": {
                    "description": "Restrict the route to designated freight network roads; the API answers HTTP 422 when no such road is within 2 km of the origin, destination or a waypoint. Needs prefer: \"truck_route\"",
                    "enum": [
                      "truck_route"
                    ],
                    "type": "string"
                  },
                  "road_info": {
                    "description": "Extra per-segment information to return: max_speed, toll_distance, toll_cost, toll_info, truck_route, stop_sign, traffic_light (flexible service only)",
                    "items": {
                      "enum": [
                        "max_speed",
                        "toll_distance",
                        "toll_cost",
                        "toll_info",
                        "truck_route",
                        "stop_sign",
                        "traffic_light"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "route_type": {
                    "description": "Optimization objective (flexible only, default fastest)",
                    "enum": [
                      "fastest",
                      "shortest"
                    ],
                    "type": "string"
                  },
                  "service": {
                    "description": "API variant: \"flexible\" (default) supports all modes, departure_time, route_type, full avoid list and truck options; \"fast\" is lower latency but limited to car/truck and avoid toll/ferry/highway only",
                    "enum": [
                      "flexible",
                      "fast"
                    ],
                    "type": "string"
                  },
                  "steps": {
                    "description": "Include turn-by-turn steps (fast service only)",
                    "type": "boolean"
                  },
                  "truck_axle_load": {
                    "description": "Load per axle in tonnes (truck mode, flexible service only)",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "truck_size_cm": {
                    "additionalProperties": false,
                    "description": "Truck dimensions in cm (flexible + mode=truck only)",
                    "properties": {
                      "height": {
                        "type": "number"
                      },
                      "length": {
                        "type": "number"
                      },
                      "width": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "height",
                      "width",
                      "length"
                    ],
                    "type": "object"
                  },
                  "truck_type": {
                    "description": "Truck class(es) the route must be legal for on the designated freight network (rigid_truck, semi_trailer, b_double, road_train, generic_truck). Effective together with prefer: \"truck_route\" (flexible service, mode truck)",
                    "items": {
                      "enum": [
                        "rigid_truck",
                        "semi_trailer",
                        "b_double",
                        "road_train",
                        "generic_truck"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "truck_weight_kg": {
                    "description": "Truck gross weight in kg (flexible + mode=truck only)",
                    "maximum": 100000,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  },
                  "waypoints": {
                    "description": "Intermediate stops visited in order (max 200)",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 200,
                    "type": "array"
                  }
                },
                "required": [
                  "origin",
                  "destination"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "distance_matrix",
              "title": "Distance Matrix",
              "description": "Compute travel distance (meters) and duration (seconds) for every origin-to-destination pair in one call; one row per origin with one element per destination, in input order. Use it instead of repeated directions calls when several pairs are needed. Documentation for this API is available through search_documentation. Parameters: origins, destinations (arrays of {latitude, longitude}, required); optional mode, service (\"fast\" default: up to 1000x1000 points; \"flexible\": the options below, max 50x50), route_type, departure_time, avoid (soft), exclude (strict), honor_restrictions, route_failed_prompt (unroutable pairs return -1 instead of 0), truck options: truck_size_cm {height, width, length}, truck_weight_kg, truck_axle_load, hazmat_type, emission_class, cross_border, prefer \"truck_route\" + truck_type (roads legal for a truck class on the designated freight network). Example: {\"origins\": [{\"latitude\": 1.29, \"longitude\": 103.85}], \"destinations\": [{\"latitude\": 1.35, \"longitude\": 103.99}, {\"latitude\": 1.3, \"longitude\": 103.77}], \"route_failed_prompt\": true}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "avoid": {
                    "description": "Road features to avoid",
                    "items": {
                      "enum": [
                        "toll",
                        "highway",
                        "ferry",
                        "none"
                      ],
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "cross_border": {
                    "description": "Allow routes to cross international borders (region-dependent, flexible service only)",
                    "type": "boolean"
                  },
                  "departure_time": {
                    "description": "Departure as a UNIX timestamp in seconds, for typical-traffic results (flexible only)",
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  },
                  "destinations": {
                    "description": "End points (matrix columns)",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 1000,
                    "minItems": 1,
                    "type": "array"
                  },
                  "emission_class": {
                    "description": "Engine emission class (EU regions, truck mode, flexible service only)",
                    "enum": [
                      "euro0",
                      "euro1",
                      "euro2",
                      "euro3",
                      "euro4",
                      "euro5",
                      "euro6",
                      "euro7",
                      "euro8",
                      "euro9"
                    ],
                    "type": "string"
                  },
                  "exclude": {
                    "description": "Strict filter: only routes that completely avoid these features are returned (error if none exists). Use `avoid` for a soft preference instead. Flexible service only",
                    "items": {
                      "enum": [
                        "toll",
                        "ferry",
                        "highway",
                        "service_road",
                        "uturn",
                        "sharp_turn",
                        "left_turn",
                        "right_turn"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "hazmat_type": {
                    "description": "Hazardous cargo classes carried (truck mode, flexible service only)",
                    "items": {
                      "enum": [
                        "explosives",
                        "gas",
                        "flammable_liquid",
                        "flammable_gas",
                        "organic",
                        "toxic",
                        "radioactive",
                        "corrosive",
                        "other"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "honor_restrictions": {
                    "description": "When true, enforce restricted-area rules for origin/destination points instead of routing through with a warning (flexible service only)",
                    "type": "boolean"
                  },
                  "mode": {
                    "description": "Travel mode (default car). Modes other than car/truck require service=flexible",
                    "enum": [
                      "car",
                      "truck",
                      "motorcycle",
                      "bike",
                      "walk"
                    ],
                    "type": "string"
                  },
                  "origins": {
                    "description": "Start points (matrix rows)",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 1000,
                    "minItems": 1,
                    "type": "array"
                  },
                  "prefer": {
                    "description": "Prioritise designated freight network roads (flexible service, mode truck). truck_type takes effect only together with this",
                    "enum": [
                      "truck_route"
                    ],
                    "type": "string"
                  },
                  "route_failed_prompt": {
                    "description": "When true, unroutable origin/destination pairs return -1 instead of 0 so they can be told apart from zero-distance pairs",
                    "type": "boolean"
                  },
                  "route_type": {
                    "description": "Optimization objective (flexible only, default fastest)",
                    "enum": [
                      "fastest",
                      "shortest"
                    ],
                    "type": "string"
                  },
                  "service": {
                    "description": "API variant: \"fast\" (default) supports up to 1000x1000 points; \"flexible\" adds departure_time, route_type, truck options and more modes but is limited to 50x50 points within a ~8000 km area",
                    "enum": [
                      "fast",
                      "flexible"
                    ],
                    "type": "string"
                  },
                  "truck_axle_load": {
                    "description": "Load per axle in tonnes (truck mode, flexible service only)",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "truck_size_cm": {
                    "additionalProperties": false,
                    "description": "Truck dimensions in cm (flexible + mode=truck only)",
                    "properties": {
                      "height": {
                        "type": "number"
                      },
                      "length": {
                        "type": "number"
                      },
                      "width": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "height",
                      "width",
                      "length"
                    ],
                    "type": "object"
                  },
                  "truck_type": {
                    "description": "Truck class(es) the route must be legal for on the designated freight network (rigid_truck, semi_trailer, b_double, road_train, generic_truck). Effective together with prefer: \"truck_route\" (flexible service, mode truck)",
                    "items": {
                      "enum": [
                        "rigid_truck",
                        "semi_trailer",
                        "b_double",
                        "road_train",
                        "generic_truck"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "truck_weight_kg": {
                    "description": "Truck gross weight in kg (flexible + mode=truck only)",
                    "maximum": 100000,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  }
                },
                "required": [
                  "origins",
                  "destinations"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "geocode_batch",
              "title": "Batch Geocode",
              "description": "Forward-geocode up to 100 free-text queries in one request; returns one ranked result set per query, in input order. Use it instead of repeated geocode_forward calls when several addresses are needed: this endpoint has its own rate limit of 60 requests per minute, so larger batches per call stay within it. Parameters: queries (required array; each item: query (required), optional near {latitude, longitude}, radius_m, country_codes, bounding_box, limit, language, view, types); optional top-level types (houseNumber | addressBlock | street | intersection | place | area) as the default for all queries (a per-query types overrides it). Example: {\"queries\": [{\"query\": \"600-699 Golden Gate Ave, San Francisco, CA\", \"types\": [\"addressBlock\"]}, {\"query\": \"Empire State Building\", \"country_codes\": [\"USA\"]}]}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "queries": {
                    "description": "Up to 100 forward-geocode queries resolved in a single request",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "bounding_box": {
                          "additionalProperties": false,
                          "description": "Hard-limit results to this bounding box",
                          "properties": {
                            "east": {
                              "description": "Eastern longitude",
                              "maximum": 180,
                              "minimum": -180,
                              "type": "number"
                            },
                            "north": {
                              "description": "Northern latitude",
                              "maximum": 90,
                              "minimum": -90,
                              "type": "number"
                            },
                            "south": {
                              "description": "Southern latitude",
                              "maximum": 90,
                              "minimum": -90,
                              "type": "number"
                            },
                            "west": {
                              "description": "Western longitude",
                              "maximum": 180,
                              "minimum": -180,
                              "type": "number"
                            }
                          },
                          "required": [
                            "west",
                            "south",
                            "east",
                            "north"
                          ],
                          "type": "object"
                        },
                        "country_codes": {
                          "description": "Restrict results to these countries (ISO 3166-1 alpha-3 codes, e.g. [\"USA\",\"MEX\"])",
                          "items": {
                            "pattern": "^[A-Za-z]{3}$",
                            "type": "string"
                          },
                          "minItems": 1,
                          "type": "array"
                        },
                        "language": {
                          "description": "Result language as a BCP 47 tag, e.g. \"en-US\"",
                          "type": "string"
                        },
                        "limit": {
                          "description": "Maximum results (default 10)",
                          "maximum": 100,
                          "minimum": 1,
                          "type": "integer"
                        },
                        "near": {
                          "additionalProperties": false,
                          "description": "Center of the search context; results are ranked around this point",
                          "properties": {
                            "latitude": {
                              "maximum": 90,
                              "minimum": -90,
                              "type": "number"
                            },
                            "longitude": {
                              "maximum": 180,
                              "minimum": -180,
                              "type": "number"
                            }
                          },
                          "required": [
                            "latitude",
                            "longitude"
                          ],
                          "type": "object"
                        },
                        "query": {
                          "description": "Free-text search query for this entry",
                          "minLength": 1,
                          "type": "string"
                        },
                        "radius_m": {
                          "description": "With `near`: hard-limit results to this radius in meters",
                          "exclusiveMinimum": 0,
                          "maximum": 9007199254740991,
                          "type": "integer"
                        },
                        "types": {
                          "description": "Restrict results to these types: houseNumber (exact door point), addressBlock (address-range/segment match incl. interpolated numbers), street, intersection (only returned when requested), place (POI), area (city/district/postal/admin area)",
                          "items": {
                            "enum": [
                              "houseNumber",
                              "addressBlock",
                              "street",
                              "intersection",
                              "place",
                              "area"
                            ],
                            "type": "string"
                          },
                          "minItems": 1,
                          "type": "array"
                        },
                        "view": {
                          "description": "Geopolitical view for disputed territories. Default: Unified (or the requester region)",
                          "enum": [
                            "Unified",
                            "AR",
                            "IL",
                            "IN",
                            "MA",
                            "PK",
                            "RU",
                            "TR",
                            "CN",
                            "TW"
                          ],
                          "type": "string"
                        }
                      },
                      "required": [
                        "query"
                      ],
                      "type": "object"
                    },
                    "maxItems": 100,
                    "minItems": 1,
                    "type": "array"
                  },
                  "types": {
                    "description": "Default result-type filter applied to every query that does not set its own `types` (houseNumber, addressBlock, street, intersection, place, area)",
                    "items": {
                      "enum": [
                        "houseNumber",
                        "addressBlock",
                        "street",
                        "intersection",
                        "place",
                        "area"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "required": [
                  "queries"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "geocode_forward",
              "title": "Forward Geocode",
              "description": "Convert a free-text address, place name, locality or administrative area into coordinates and a full postal address; tolerates incomplete or partly wrong input. Use geocode_batch for many addresses, place_search for POIs/businesses, geocode_structured when the address components are already separated. Parameters: query (required); optional near {latitude, longitude} or country_codes (strongly recommended - landmark names rank poorly without a location bias), radius_m (with near), bounding_box {west, south, east, north}, limit, language, view, types (houseNumber | addressBlock | street | intersection | place | area). Example: {\"query\": \"1600 Pennsylvania Avenue NW, Washington DC\", \"country_codes\": [\"USA\"], \"limit\": 1}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "bounding_box": {
                    "additionalProperties": false,
                    "description": "Hard-limit results to this bounding box",
                    "properties": {
                      "east": {
                        "description": "Eastern longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      },
                      "north": {
                        "description": "Northern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "south": {
                        "description": "Southern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "west": {
                        "description": "Western longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "west",
                      "south",
                      "east",
                      "north"
                    ],
                    "type": "object"
                  },
                  "country_codes": {
                    "description": "Restrict results to these countries (ISO 3166-1 alpha-3 codes, e.g. [\"USA\",\"MEX\"])",
                    "items": {
                      "pattern": "^[A-Za-z]{3}$",
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "language": {
                    "description": "Result language as a BCP 47 tag, e.g. \"en-US\"",
                    "type": "string"
                  },
                  "limit": {
                    "description": "Maximum results (default 10)",
                    "maximum": 100,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "near": {
                    "additionalProperties": false,
                    "description": "Center of the search context; results are ranked around this point",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "query": {
                    "description": "Free-text search query",
                    "minLength": 1,
                    "type": "string"
                  },
                  "radius_m": {
                    "description": "With `near`: hard-limit results to this radius in meters",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991,
                    "type": "integer"
                  },
                  "types": {
                    "description": "Restrict results to these types: houseNumber (exact door point), addressBlock (address-range/segment match incl. interpolated numbers), street, intersection (only returned when requested), place (POI), area (city/district/postal/admin area)",
                    "items": {
                      "enum": [
                        "houseNumber",
                        "addressBlock",
                        "street",
                        "intersection",
                        "place",
                        "area"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "view": {
                    "description": "Geopolitical view for disputed territories. Default: Unified (or the requester region)",
                    "enum": [
                      "Unified",
                      "AR",
                      "IL",
                      "IN",
                      "MA",
                      "PK",
                      "RU",
                      "TR",
                      "CN",
                      "TW"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "query"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "geocode_reverse",
              "title": "Reverse Geocode",
              "description": "Find the nearest address for a coordinate; returns the full postal address, the matched position and a bounding box. Parameters: coordinate {latitude, longitude} (required); optional country_codes, bounding_box {west, south, east, north}, language, view. Example: {\"coordinate\": {\"latitude\": 48.8566, \"longitude\": 2.3522}}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "bounding_box": {
                    "additionalProperties": false,
                    "description": "Hard-limit results to this bounding box",
                    "properties": {
                      "east": {
                        "description": "Eastern longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      },
                      "north": {
                        "description": "Northern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "south": {
                        "description": "Southern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "west": {
                        "description": "Western longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "west",
                      "south",
                      "east",
                      "north"
                    ],
                    "type": "object"
                  },
                  "coordinate": {
                    "additionalProperties": false,
                    "description": "The location to reverse geocode",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "country_codes": {
                    "description": "Restrict results to these countries (ISO 3166-1 alpha-3 codes, e.g. [\"USA\",\"MEX\"])",
                    "items": {
                      "pattern": "^[A-Za-z]{3}$",
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "language": {
                    "description": "Result language as a BCP 47 tag, e.g. \"en-US\"",
                    "type": "string"
                  },
                  "view": {
                    "description": "Geopolitical view for disputed territories. Default: Unified (or the requester region)",
                    "enum": [
                      "Unified",
                      "AR",
                      "IL",
                      "IN",
                      "MA",
                      "PK",
                      "RU",
                      "TR",
                      "CN",
                      "TW"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "coordinate"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "geocode_structured",
              "title": "Structured Geocode",
              "description": "Geocode an address given as separate fields instead of one string; searches addresses and administrative areas only, never POIs. Use when the components are already known and precision matters; otherwise use geocode_forward. Parameters: country_code (required, ISO 3166-1 alpha-3) plus at least one of state, county, city, suburb, neighborhood, street, house_number, postal_code; optional near {latitude, longitude}, limit, types, view. Example: {\"country_code\": \"GBR\", \"city\": \"London\", \"street\": \"Baker Street\", \"house_number\": \"221B\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "city": {
                    "type": "string"
                  },
                  "country_code": {
                    "description": "Country of the address (required, ISO 3166-1 alpha-3, e.g. \"USA\")",
                    "pattern": "^[A-Za-z]{3}$",
                    "type": "string"
                  },
                  "county": {
                    "type": "string"
                  },
                  "house_number": {
                    "type": "string"
                  },
                  "limit": {
                    "description": "Maximum results (default 10)",
                    "maximum": 100,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "near": {
                    "additionalProperties": false,
                    "description": "Search-context center for ranking",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "neighborhood": {
                    "type": "string"
                  },
                  "postal_code": {
                    "type": "string"
                  },
                  "state": {
                    "type": "string"
                  },
                  "street": {
                    "type": "string"
                  },
                  "suburb": {
                    "type": "string"
                  },
                  "types": {
                    "description": "Restrict results to these types: houseNumber (exact door point), addressBlock (address-range/segment match incl. interpolated numbers), street, intersection (only returned when requested), place (POI), area (city/district/postal/admin area)",
                    "items": {
                      "enum": [
                        "houseNumber",
                        "addressBlock",
                        "street",
                        "intersection",
                        "place",
                        "area"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "view": {
                    "description": "Geopolitical view for disputed territories. Default: Unified (or the requester region)",
                    "enum": [
                      "Unified",
                      "AR",
                      "IL",
                      "IN",
                      "MA",
                      "PK",
                      "RU",
                      "TR",
                      "CN",
                      "TW"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "country_code"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "get_api_parameters",
              "title": "Get API Parameters",
              "description": "Get structured parameter details for a NextBillion REST API endpoint: type, required, default, allowed values, units and description. More precise than a prose search for questions about one specific parameter. Returns every matching API variant (e.g. directions/flexible and directions/fast), identified by heading_path. Empty units means the documentation does not state a unit. SDK methods are not covered. When the index is temporarily unavailable the result says so and names the public docs site.\nParameters:\n- endpoint (string, required unless doc_id given): API slug, optionally with variant, e.g. directions or directions/flexible; a tool name such as geocode_batch or a doc_id also resolves. An unknown endpoint returns found: false with similar endpoints.\n- doc_id (string, optional): page id instead of endpoint.\n- name (string, optional): one parameter name.\nExample: {\"endpoint\": \"directions\", \"name\": \"truck_weight\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "doc_id": {
                    "description": "Page id instead of endpoint",
                    "type": "string"
                  },
                  "endpoint": {
                    "description": "API slug with optional variant (directions, directions/flexible, geofence/create), a tool name (geocode_batch) or a doc_id",
                    "type": "string"
                  },
                  "name": {
                    "description": "One parameter name, e.g. truck_weight",
                    "type": "string"
                  }
                },
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "get_documentation",
              "title": "Get Documentation Page",
              "description": "Fetch the full text of one documentation page by its doc_id, as returned by search_documentation. Use when an excerpt is not enough to answer accurately. Pages over the size limit return truncated: true and a section list; a single section can be requested with section. Sample request and response bodies are omitted unless include_examples is true. An unknown doc_id or section returns found: false with similar ids or the section list. When the index is temporarily unavailable the result says so and names the public docs site.\nParameters:\n- doc_id (string, required): page id from search results.\n- section (string, optional): heading of one section to return.\n- include_examples (boolean, optional): default false.\nExample: {\"doc_id\": \"routing/directions-api/examples/legal-routes-for-a-given-truck-weight\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "doc_id": {
                    "description": "Page id from search_documentation or list_documentation_topics",
                    "minLength": 1,
                    "type": "string"
                  },
                  "include_examples": {
                    "description": "Include sample request/response code blocks (default false)",
                    "type": "boolean"
                  },
                  "section": {
                    "description": "Heading (or its anchor) of one section to return",
                    "type": "string"
                  }
                },
                "required": [
                  "doc_id"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "isochrone",
              "title": "Isochrone",
              "description": "Calculate the area reachable from a point within given travel times or distances; returns a GeoJSON FeatureCollection of contours (geometry coordinates are [longitude, latitude]). Each contour ring can be drawn with static_route_map by passing it as paths[].geojson_coordinates with a fill_color. Documentation for this API is available through search_documentation. Parameters: origin {latitude, longitude} (required); exactly one of contours_minutes (array, up to 4 values, max 40) or contours_meters (array, up to 4 values, max 60000); optional mode, polygons (true for Polygon geometry), denoise, generalize (meters), contours_colors (hex without #, one per contour), departure_time. Example: {\"origin\": {\"latitude\": 37.7749, \"longitude\": -122.4194}, \"contours_minutes\": [5, 10], \"polygons\": true}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "contours_colors": {
                    "description": "One hex color (without #) per contour, e.g. [\"ff0000\", \"00ff00\"]",
                    "items": {
                      "pattern": "^[0-9a-fA-F]{6}$",
                      "type": "string"
                    },
                    "maxItems": 4,
                    "type": "array"
                  },
                  "contours_meters": {
                    "description": "Travel distances in meters, one contour each (max 4 values, increasing, max 60000)",
                    "items": {
                      "maximum": 60000,
                      "minimum": 1,
                      "type": "integer"
                    },
                    "maxItems": 4,
                    "type": "array"
                  },
                  "contours_minutes": {
                    "description": "Travel times in minutes, one contour each (max 4 values, increasing, max 40)",
                    "items": {
                      "maximum": 40,
                      "minimum": 1,
                      "type": "integer"
                    },
                    "maxItems": 4,
                    "type": "array"
                  },
                  "denoise": {
                    "description": "Remove contours smaller than this fraction of the largest (default 1: largest only)",
                    "maximum": 1,
                    "minimum": 0,
                    "type": "number"
                  },
                  "departure_time": {
                    "description": "Departure as a UNIX timestamp in seconds, for typical-traffic analysis",
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  },
                  "generalize": {
                    "description": "Simplification tolerance in meters (Douglas-Peucker); omit for automatic",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "mode": {
                    "description": "Travel mode (default car)",
                    "enum": [
                      "car",
                      "truck",
                      "motorcycle",
                      "bike",
                      "walk"
                    ],
                    "type": "string"
                  },
                  "origin": {
                    "additionalProperties": false,
                    "description": "Starting point of the reachability analysis",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "polygons": {
                    "description": "Return contours as GeoJSON Polygons instead of LineStrings",
                    "type": "boolean"
                  }
                },
                "required": [
                  "origin"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "list_documentation_topics",
              "title": "List Documentation Topics",
              "description": "List the available documentation categories, APIs and pages, with index metadata. Useful before searching, when the right terms are not yet known, e.g. to see which APIs exist for a problem area. When the index is temporarily unavailable the result says so and names the public docs site.\nParameters:\n- category (string, optional): limit to one category.\n- sdk (string, optional): Android, iOS or Flutter.\nExample: {\"category\": \"Optimization\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "category": {
                    "description": "Only this category, e.g. Routing",
                    "type": "string"
                  },
                  "sdk": {
                    "description": "Only pages of this platform: Android, iOS, Flutter, Web",
                    "type": "string"
                  }
                },
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "measure",
              "title": "Measure Straight-Line Distance, Length, Area or Bearing",
              "description": "Measure straight-line (geodesic, WGS84) distance between two points, the length of a line, the area and perimeter of a polygon, or the bearing from one point to another. Straight-line (geodesic) geometry computed locally, not road distance or travel time: for those, directions or distance_matrix apply. No sign-in needed. Parameters: mode (distance | length | area | bearing); from and to ({latitude, longitude}) for distance and bearing; line (array of points) for length; polygon (GeoJSON Polygon or MultiPolygon, e.g. an isochrone contour) for area; units (meters, kilometers, miles, feet, nautical_miles; default meters); area_units (square_meters, square_kilometers, hectares, acres, square_miles, square_feet; default square_meters). Example: {\"mode\": \"distance\", \"from\": {\"latitude\": 12.9716, \"longitude\": 77.5946}, \"to\": {\"latitude\": 13.0827, \"longitude\": 80.2707}, \"units\": \"kilometers\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "area_units": {
                    "description": "Area unit (default square_meters)",
                    "enum": [
                      "square_meters",
                      "square_kilometers",
                      "hectares",
                      "acres",
                      "square_miles",
                      "square_feet"
                    ],
                    "type": "string"
                  },
                  "from": {
                    "additionalProperties": false,
                    "description": "Start point (distance, bearing)",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "line": {
                    "description": "The line (length)",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 5000,
                    "minItems": 2,
                    "type": "array"
                  },
                  "mode": {
                    "description": "distance: between two points; length: of a line; area: of a polygon; bearing: from one point to another",
                    "enum": [
                      "distance",
                      "length",
                      "area",
                      "bearing"
                    ],
                    "type": "string"
                  },
                  "polygon": {
                    "additionalProperties": {},
                    "description": "The polygon (area)",
                    "properties": {
                      "type": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "type"
                    ],
                    "type": "object"
                  },
                  "to": {
                    "additionalProperties": false,
                    "description": "End point (distance, bearing)",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "units": {
                    "description": "Distance unit (default meters)",
                    "enum": [
                      "meters",
                      "kilometers",
                      "miles",
                      "feet",
                      "nautical_miles"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "mode"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "nearest",
              "title": "Nearest Point or Position on a Line",
              "description": "Find the candidate points nearest to a target as the crow flies (e.g. the closest depots to a customer), or snap the target onto a line and report the closest position on it. Straight-line (geodesic) distances, computed locally, no sign-in needed; distance_matrix gives travel time and road distance instead. Parameters: target ({latitude, longitude}); either candidates (array of {latitude, longitude, id?}) with k (default 1), or line (array of points); units (default meters). Returns ranked {id, point, distance} for candidates, or snapped_point, distance, segment_index and distance_along_line for a line. Example: {\"target\": {\"latitude\": 12.9716, \"longitude\": 77.5946}, \"candidates\": [{\"latitude\": 13.0827, \"longitude\": 80.2707, \"id\": \"Chennai\"}, {\"latitude\": 19.076, \"longitude\": 72.8777, \"id\": \"Mumbai\"}], \"k\": 1, \"units\": \"kilometers\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "candidates": {
                    "description": "Points to rank by straight-line distance from target",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "id": {
                          "description": "Optional label echoed back in the result",
                          "maxLength": 100,
                          "type": "string"
                        },
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 1000,
                    "minItems": 1,
                    "type": "array"
                  },
                  "k": {
                    "description": "How many nearest candidates to return (default 1)",
                    "maximum": 100,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "line": {
                    "description": "A line to snap the target onto",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 5000,
                    "minItems": 2,
                    "type": "array"
                  },
                  "target": {
                    "additionalProperties": false,
                    "description": "The reference point",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "units": {
                    "description": "Distance unit (default meters)",
                    "enum": [
                      "meters",
                      "kilometers",
                      "miles",
                      "feet",
                      "nautical_miles"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "target"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "place_browse",
              "title": "Browse Places by Category",
              "description": "List places of given categories around a location, ranked by distance, without a text query - e.g. all restaurants or schools near a point. Use place_search when the user describes what they want in words; use place_lookup to expand a result by id. Parameters: categories (required array of category names or ids); near {latitude, longitude} (recommended), radius_m (with near), country_codes, bounding_box {west, south, east, north}, limit, language, view. Example: {\"categories\": [\"restaurant\"], \"near\": {\"latitude\": 1.2839, \"longitude\": 103.8607}, \"radius_m\": 800, \"limit\": 10}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "bounding_box": {
                    "additionalProperties": false,
                    "description": "Hard-limit results to this bounding box",
                    "properties": {
                      "east": {
                        "description": "Eastern longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      },
                      "north": {
                        "description": "Northern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "south": {
                        "description": "Southern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "west": {
                        "description": "Western longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "west",
                      "south",
                      "east",
                      "north"
                    ],
                    "type": "object"
                  },
                  "categories": {
                    "description": "Category names or ids to browse; a place matching any of them is returned (e.g. [\"restaurant\"], [\"schools\"], [\"7376\"])",
                    "items": {
                      "minLength": 1,
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "country_codes": {
                    "description": "Restrict results to these countries (ISO 3166-1 alpha-3 codes, e.g. [\"USA\",\"MEX\"])",
                    "items": {
                      "pattern": "^[A-Za-z]{3}$",
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "language": {
                    "description": "Result language as a BCP 47 tag, e.g. \"en-US\"",
                    "type": "string"
                  },
                  "limit": {
                    "description": "Maximum results (default 10)",
                    "maximum": 100,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "near": {
                    "additionalProperties": false,
                    "description": "Center of the search context; results are ranked around this point",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "radius_m": {
                    "description": "With `near`: hard-limit results to this radius in meters",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991,
                    "type": "integer"
                  },
                  "view": {
                    "description": "Geopolitical view for disputed territories. Default: Unified (or the requester region)",
                    "enum": [
                      "Unified",
                      "AR",
                      "IL",
                      "IN",
                      "MA",
                      "PK",
                      "RU",
                      "TR",
                      "CN",
                      "TW"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "categories"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "place_lookup",
              "title": "Place Lookup",
              "description": "Fetch the full details of a place (address, position, access points, categories, contacts) by its unique id, as returned by place_search, geocode_forward, autosuggest, autocomplete or search_along_route. Parameters: id (required); optional view. Example: {\"id\": \"2EmBgAmFpR9dg0D89EBzNA\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "id": {
                    "description": "Unique place id, as returned by the other place/geocoding tools",
                    "minLength": 1,
                    "type": "string"
                  },
                  "view": {
                    "description": "Geopolitical view for disputed territories. Default: Unified (or the requester region)",
                    "enum": [
                      "Unified",
                      "AR",
                      "IL",
                      "IN",
                      "MA",
                      "PK",
                      "RU",
                      "TR",
                      "CN",
                      "TW"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "id"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "place_search",
              "title": "Search Places",
              "description": "Search for places, points of interest and businesses with a free-text query (e.g. \"gas station\", \"coffee\"), ranked by relevance around a location. Use geocode_forward for plain address-to-coordinates conversion. Documentation for this API is available through search_documentation. Parameters: query (required); optional near {latitude, longitude} (recommended), radius_m (with near), country_codes, bounding_box {west, south, east, north}, limit, language, view. Example: {\"query\": \"coffee\", \"near\": {\"latitude\": 37.7749, \"longitude\": -122.4194}, \"radius_m\": 1000, \"limit\": 5}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "bounding_box": {
                    "additionalProperties": false,
                    "description": "Hard-limit results to this bounding box",
                    "properties": {
                      "east": {
                        "description": "Eastern longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      },
                      "north": {
                        "description": "Northern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "south": {
                        "description": "Southern latitude",
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "west": {
                        "description": "Western longitude",
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "west",
                      "south",
                      "east",
                      "north"
                    ],
                    "type": "object"
                  },
                  "country_codes": {
                    "description": "Restrict results to these countries (ISO 3166-1 alpha-3 codes, e.g. [\"USA\",\"MEX\"])",
                    "items": {
                      "pattern": "^[A-Za-z]{3}$",
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "language": {
                    "description": "Result language as a BCP 47 tag, e.g. \"en-US\"",
                    "type": "string"
                  },
                  "limit": {
                    "description": "Maximum results (default 10)",
                    "maximum": 100,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "near": {
                    "additionalProperties": false,
                    "description": "Center of the search context; results are ranked around this point",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "query": {
                    "description": "Free-text search query",
                    "minLength": 1,
                    "type": "string"
                  },
                  "radius_m": {
                    "description": "With `near`: hard-limit results to this radius in meters",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991,
                    "type": "integer"
                  },
                  "view": {
                    "description": "Geopolitical view for disputed territories. Default: Unified (or the requester region)",
                    "enum": [
                      "Unified",
                      "AR",
                      "IL",
                      "IN",
                      "MA",
                      "PK",
                      "RU",
                      "TR",
                      "CN",
                      "TW"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "query"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "points_in_polygon",
              "title": "Points in Polygon",
              "description": "Geofencing: tell which of up to 1,000 points lie inside a polygon, for example which delivery addresses fall within an isochrone contour or a service area. Holes are respected; the test is done in map (flat degree) space, matching how polygons are drawn. Computed locally, no sign-in needed. Parameters: polygon (GeoJSON Polygon or MultiPolygon, or an isochrone Feature); points (array of {latitude, longitude, id?}); include_boundary (default true). Returns inside and outside lists (ids, or indexes when no id is given) with counts. Example: {\"polygon\": {\"type\": \"Polygon\", \"coordinates\": [[[77.59, 12.97], [77.61, 12.97], [77.61, 12.99], [77.59, 12.99], [77.59, 12.97]]]}, \"points\": [{\"latitude\": 12.98, \"longitude\": 77.6, \"id\": \"A\"}]}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "include_boundary": {
                    "description": "Count points exactly on the edge as inside (default true)",
                    "type": "boolean"
                  },
                  "points": {
                    "description": "Points to test, each optionally with an id",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "id": {
                          "description": "Optional label echoed back in the result",
                          "maxLength": 100,
                          "type": "string"
                        },
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "maxItems": 1000,
                    "minItems": 1,
                    "type": "array"
                  },
                  "polygon": {
                    "additionalProperties": {},
                    "description": "A GeoJSON Polygon or MultiPolygon geometry (coordinates in [longitude, latitude] order), or a Feature wrapping one — an isochrone contour can be passed as is",
                    "properties": {
                      "type": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "type"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "polygon",
                  "points"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "polygon_ops",
              "title": "Polygon Union, Intersection or Difference",
              "description": "Combine polygons: union (merge), intersect (overlap) or difference (first minus the others), for example the overlap of two isochrones or the part of a zone not covered by a depot area. Returns the resulting GeoJSON geometry (Polygon or MultiPolygon, or null when empty) with its geodesic area. Computed locally, no sign-in needed. Parameters: operation (union | intersect | difference); polygons (array of 2–20 GeoJSON Polygon/MultiPolygon geometries, isochrone Features accepted); area_units (default square_meters); max_vertices (default 500, result simplified to fit). Example: {\"operation\": \"intersect\", \"polygons\": [{\"type\": \"Polygon\", \"coordinates\": [[[77.59, 12.97], [77.61, 12.97], [77.61, 12.99], [77.59, 12.99], [77.59, 12.97]]]}, {\"type\": \"Polygon\", \"coordinates\": [[[77.6, 12.98], [77.62, 12.98], [77.62, 13.0], [77.6, 13.0], [77.6, 12.98]]]}], \"area_units\": \"hectares\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "area_units": {
                    "description": "Area unit (default square_meters)",
                    "enum": [
                      "square_meters",
                      "square_kilometers",
                      "hectares",
                      "acres",
                      "square_miles",
                      "square_feet"
                    ],
                    "type": "string"
                  },
                  "max_vertices": {
                    "description": "Simplify the returned shape to at most this many vertices (default 500); the result says when it was simplified",
                    "maximum": 5000,
                    "minimum": 16,
                    "type": "integer"
                  },
                  "operation": {
                    "description": "difference = first polygon minus all others",
                    "enum": [
                      "union",
                      "intersect",
                      "difference"
                    ],
                    "type": "string"
                  },
                  "polygons": {
                    "description": "Two or more polygons (GeoJSON Polygon/MultiPolygon or isochrone Features)",
                    "items": {
                      "additionalProperties": {},
                      "description": "A GeoJSON Polygon or MultiPolygon geometry (coordinates in [longitude, latitude] order), or a Feature wrapping one — an isochrone contour can be passed as is",
                      "properties": {
                        "type": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "type"
                      ],
                      "type": "object"
                    },
                    "maxItems": 20,
                    "minItems": 2,
                    "type": "array"
                  }
                },
                "required": [
                  "operation",
                  "polygons"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "postcode_lookup",
              "title": "Postcode Lookup",
              "description": "Get the centroid and boundary polygon of a postal/ZIP code, or find the postal code that contains a coordinate; one lookup per call. Supported countries: USA, India, UK, Netherlands, Austria, Germany, Indonesia, France, Singapore, Philippines, Canada, Australia, New Zealand, Italy, Brazil, Mexico, Spain. Parameters: either postal_code plus country (name, alpha-2 or alpha-3 code), or coordinate {latitude, longitude}; optional geojson_boundary (true for a GeoJSON boundary). Example: {\"postal_code\": \"90011\", \"country\": \"USA\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "coordinate": {
                    "additionalProperties": false,
                    "description": "Find the postal code containing this location (alternative to `postal_code`)",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "country": {
                    "description": "Country of the postal code — name, alpha-2, or alpha-3 ISO code. Required with `postal_code`",
                    "type": "string"
                  },
                  "geojson_boundary": {
                    "description": "Return the boundary polygon in GeoJSON format instead of the default point-list format",
                    "type": "boolean"
                  },
                  "postal_code": {
                    "description": "Postal/ZIP code to look up (requires `country`; do not combine with `coordinate`)",
                    "type": "string"
                  }
                },
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "search_along_route",
              "title": "Search Along Route",
              "description": "Find places matching a text query along a driving route, with the detour time and distance each stop adds - for \"find X on the way\" questions. Pass the route as an ordered list of waypoints, e.g. the origin, waypoints and destination used with directions. Parameters: route_points (array of {latitude, longitude}, at least 2, required), query (required); optional max_detour_seconds (default 900, max 3600), sort_by (detour_time | detour_offset), limit (max 20), view. Example: {\"route_points\": [{\"latitude\": 34.0493, \"longitude\": -118.2557}, {\"latitude\": 34.0415, \"longitude\": -118.231}], \"query\": \"gas station\", \"max_detour_seconds\": 600}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "limit": {
                    "description": "Maximum results (default 10, max 20)",
                    "maximum": 20,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "max_detour_seconds": {
                    "description": "Max driving time to reach a result after leaving the route (default 900 = 15 min)",
                    "maximum": 3600,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "query": {
                    "description": "What to find along the route, e.g. \"gas station\", \"coffee\"",
                    "minLength": 1,
                    "type": "string"
                  },
                  "route_points": {
                    "description": "Waypoints defining the route to search along, in travel order",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "minItems": 2,
                    "type": "array"
                  },
                  "sort_by": {
                    "description": "Order by detour driving time, or by distance of the detour point from route start",
                    "enum": [
                      "detour_time",
                      "detour_offset"
                    ],
                    "type": "string"
                  },
                  "view": {
                    "description": "Geopolitical view for disputed territories (default: requester region or Unified)",
                    "enum": [
                      "Unified",
                      "AR",
                      "CN",
                      "IN",
                      "PK",
                      "MA",
                      "RU",
                      "RS",
                      "TW",
                      "TR"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "route_points",
                  "query"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "search_documentation",
              "title": "Search Documentation",
              "description": "Search NextBillion's official API and SDK documentation. Use for any question about how NextBillion works: calling an API, what a parameter means, which API to use, or SDK setup. Answers come from an index of the official documentation, not from live API calls; when the index is temporarily unavailable the result says so and names the public docs site.\nQueries match best with the docs' own terms and exact parameter names (truck_weight, option=flexible) rather than everyday phrasing; when results are thin, other API terms may match. Results are excerpts: get_documentation returns a full page. Each result carries a source_url for citation and related_tools, the name of the tool that performs the operation.\nParameters:\n- query (string, required): search terms.\n- category (string, optional): e.g. Routing, Places.\n- api (string, optional): e.g. Directions.\n- sdk (string, optional): Android, iOS or Flutter.\n- limit (integer, optional): default 5, max 10.\n- include_examples (boolean, optional): default false.\nExample: {\"query\": \"truck_size truck_weight routing\", \"api\": \"Directions\"}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "api": {
                    "description": "Boost one API, e.g. Directions",
                    "type": "string"
                  },
                  "category": {
                    "description": "Boost one category, e.g. Routing, Places",
                    "type": "string"
                  },
                  "include_examples": {
                    "description": "Also return sample request/response code chunks (default false)",
                    "type": "boolean"
                  },
                  "limit": {
                    "description": "Number of results (default 5)",
                    "maximum": 10,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "query": {
                    "description": "Search terms, ideally the docs’ own vocabulary",
                    "minLength": 1,
                    "type": "string"
                  },
                  "sdk": {
                    "description": "Only pages of this platform: Android, iOS, Flutter, Web",
                    "type": "string"
                  }
                },
                "required": [
                  "query"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": false,
                "readOnlyHint": true
              }
            },
            {
              "name": "static_map_image",
              "title": "Static Map Image",
              "description": "Render a static map image centered on a location, with optional markers and line/polygon overlays; returns the image inline (path in the result text). For a map auto-fitted to a route or to overlays, use static_route_map. Parameters: center {latitude, longitude} and zoom (0-22) (required); optional markers (array of {latitude, longitude, color, icon_url, anchor, scale}), paths (array of {points [{latitude, longitude}] OR geojson_coordinates [[longitude, latitude], ...], stroke_color, stroke_width, fill_color for a filled polygon}), width, height (default 512), style (streets | light | dark | hybrid), format (png | jpg | webp), retina. Example: {\"center\": {\"latitude\": 48.8566, \"longitude\": 2.3522}, \"zoom\": 14, \"markers\": [{\"latitude\": 48.8584, \"longitude\": 2.2945, \"color\": \"red\"}], \"paths\": [{\"points\": [{\"latitude\": 48.85, \"longitude\": 2.29}, {\"latitude\": 48.86, \"longitude\": 2.30}], \"stroke_color\": \"green\"}]}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "center": {
                    "additionalProperties": false,
                    "description": "Center of the map view",
                    "properties": {
                      "latitude": {
                        "maximum": 90,
                        "minimum": -90,
                        "type": "number"
                      },
                      "longitude": {
                        "maximum": 180,
                        "minimum": -180,
                        "type": "number"
                      }
                    },
                    "required": [
                      "latitude",
                      "longitude"
                    ],
                    "type": "object"
                  },
                  "format": {
                    "description": "Image format (default png)",
                    "enum": [
                      "png",
                      "jpg",
                      "webp"
                    ],
                    "type": "string"
                  },
                  "height": {
                    "description": "Image height in pixels (default 512)",
                    "maximum": 2048,
                    "minimum": 16,
                    "type": "integer"
                  },
                  "markers": {
                    "description": "Markers to draw, each with optional color or custom icon",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "anchor": {
                          "description": "Anchor point of a custom icon (default bottom)",
                          "enum": [
                            "top",
                            "left",
                            "bottom",
                            "right",
                            "center",
                            "topleft",
                            "bottomleft",
                            "topright",
                            "bottomright"
                          ],
                          "type": "string"
                        },
                        "color": {
                          "description": "Marker color, e.g. \"red\" or \"#0000ff\" (ignored when icon_url is set)",
                          "type": "string"
                        },
                        "icon_url": {
                          "description": "URL of a custom marker image (max 64 kB / 4096 px, e.g. 64x64 PNG)",
                          "format": "uri",
                          "type": "string"
                        },
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        },
                        "scale": {
                          "description": "Custom icon scale factor (default 1)",
                          "exclusiveMinimum": 0,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "paths": {
                    "description": "Extra lines/polygons to draw (e.g. isochrone contours as filled polygons)",
                    "items": {
                      "additionalProperties": false,
                      "description": "A line or filled polygon overlay",
                      "properties": {
                        "fill_color": {
                          "description": "Fill color for a closed shape, e.g. \"rgba(255,0,0,0.3)\" or \"#ff000055\"; omit for a line",
                          "type": "string"
                        },
                        "geojson_coordinates": {
                          "description": "Vertices as GeoJSON [longitude, latitude] pairs - pass an isochrone or GeoJSON ring here unchanged",
                          "items": {
                            "prefixItems": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "number"
                              }
                            ],
                            "type": "array"
                          },
                          "minItems": 2,
                          "type": "array"
                        },
                        "points": {
                          "description": "Vertices as {latitude, longitude} objects",
                          "items": {
                            "additionalProperties": false,
                            "properties": {
                              "latitude": {
                                "maximum": 90,
                                "minimum": -90,
                                "type": "number"
                              },
                              "longitude": {
                                "maximum": 180,
                                "minimum": -180,
                                "type": "number"
                              }
                            },
                            "required": [
                              "latitude",
                              "longitude"
                            ],
                            "type": "object"
                          },
                          "minItems": 2,
                          "type": "array"
                        },
                        "stroke_color": {
                          "description": "Line color (default blue)",
                          "type": "string"
                        },
                        "stroke_width": {
                          "description": "Line width in px (default 3)",
                          "maximum": 20,
                          "minimum": 1,
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    },
                    "maxItems": 10,
                    "type": "array"
                  },
                  "retina": {
                    "description": "Render at @2x resolution for high-DPI displays",
                    "type": "boolean"
                  },
                  "style": {
                    "description": "Map style id: \"streets\", \"light\", \"dark\", or \"hybrid\" (default streets)",
                    "type": "string"
                  },
                  "width": {
                    "description": "Image width in pixels (default 512)",
                    "maximum": 2048,
                    "minimum": 16,
                    "type": "integer"
                  },
                  "zoom": {
                    "description": "Zoom level (0 = world, ~10 = city, ~15 = streets; fractional values allowed)",
                    "maximum": 22,
                    "minimum": 0,
                    "type": "number"
                  }
                },
                "required": [
                  "center",
                  "zoom"
                ],
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            },
            {
              "name": "static_route_map",
              "title": "Static Route Map",
              "description": "Render a static map auto-fitted to a route and/or overlays: a route from directions, and/or lines and filled polygons such as isochrone contours; very long geometry is simplified automatically to fit the map API URL limit (distances unaffected). Returns the image inline. Parameters: at least one of encoded_polyline (the geometry string from directions, preferred), route_points (array of {latitude, longitude}) or paths (array of {points OR geojson_coordinates [[longitude, latitude], ...], stroke_color, stroke_width, fill_color}); optional markers (array of {latitude, longitude, color, icon_url, anchor, scale}), stroke_color, stroke_width (route line), padding, width, height, style, format, retina. The example draws isochrone contours. Example: {\"paths\": [{\"geojson_coordinates\": [[-122.42, 37.77], [-122.40, 37.78], [-122.41, 37.79], [-122.42, 37.77]], \"fill_color\": \"rgba(29,78,216,0.35)\", \"stroke_color\": \"#1d4ed8\"}], \"markers\": [{\"latitude\": 37.7749, \"longitude\": -122.4194, \"color\": \"red\"}]}",
              "inputSchema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "additionalProperties": false,
                "properties": {
                  "encoded_polyline": {
                    "description": "Route geometry as a Google encoded polyline (precision 5) — exactly what the directions tool returns with its default geometry setting",
                    "type": "string"
                  },
                  "format": {
                    "description": "Image format (default png)",
                    "enum": [
                      "png",
                      "jpg",
                      "webp"
                    ],
                    "type": "string"
                  },
                  "height": {
                    "description": "Image height in pixels (default 512)",
                    "maximum": 2048,
                    "minimum": 16,
                    "type": "integer"
                  },
                  "markers": {
                    "description": "Extra markers, e.g. origin and destination, with optional color or custom icon",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "anchor": {
                          "description": "Anchor point of a custom icon (default bottom)",
                          "enum": [
                            "top",
                            "left",
                            "bottom",
                            "right",
                            "center",
                            "topleft",
                            "bottomleft",
                            "topright",
                            "bottomright"
                          ],
                          "type": "string"
                        },
                        "color": {
                          "description": "Marker color, e.g. \"red\" or \"#0000ff\" (ignored when icon_url is set)",
                          "type": "string"
                        },
                        "icon_url": {
                          "description": "URL of a custom marker image (max 64 kB / 4096 px, e.g. 64x64 PNG)",
                          "format": "uri",
                          "type": "string"
                        },
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        },
                        "scale": {
                          "description": "Custom icon scale factor (default 1)",
                          "exclusiveMinimum": 0,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "padding": {
                    "description": "Margin around the route as a fraction of image size (default 0.1)",
                    "maximum": 1,
                    "minimum": 0,
                    "type": "number"
                  },
                  "paths": {
                    "description": "Extra lines/polygons to draw (e.g. isochrone contours as filled polygons)",
                    "items": {
                      "additionalProperties": false,
                      "description": "A line or filled polygon overlay",
                      "properties": {
                        "fill_color": {
                          "description": "Fill color for a closed shape, e.g. \"rgba(255,0,0,0.3)\" or \"#ff000055\"; omit for a line",
                          "type": "string"
                        },
                        "geojson_coordinates": {
                          "description": "Vertices as GeoJSON [longitude, latitude] pairs - pass an isochrone or GeoJSON ring here unchanged",
                          "items": {
                            "prefixItems": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "number"
                              }
                            ],
                            "type": "array"
                          },
                          "minItems": 2,
                          "type": "array"
                        },
                        "points": {
                          "description": "Vertices as {latitude, longitude} objects",
                          "items": {
                            "additionalProperties": false,
                            "properties": {
                              "latitude": {
                                "maximum": 90,
                                "minimum": -90,
                                "type": "number"
                              },
                              "longitude": {
                                "maximum": 180,
                                "minimum": -180,
                                "type": "number"
                              }
                            },
                            "required": [
                              "latitude",
                              "longitude"
                            ],
                            "type": "object"
                          },
                          "minItems": 2,
                          "type": "array"
                        },
                        "stroke_color": {
                          "description": "Line color (default blue)",
                          "type": "string"
                        },
                        "stroke_width": {
                          "description": "Line width in px (default 3)",
                          "maximum": 20,
                          "minimum": 1,
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    },
                    "maxItems": 10,
                    "type": "array"
                  },
                  "retina": {
                    "description": "Render at @2x resolution for high-DPI displays",
                    "type": "boolean"
                  },
                  "route_points": {
                    "description": "Alternative to encoded_polyline: the route as an ordered list of coordinates",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        }
                      },
                      "required": [
                        "latitude",
                        "longitude"
                      ],
                      "type": "object"
                    },
                    "minItems": 2,
                    "type": "array"
                  },
                  "stroke_color": {
                    "description": "Route line color (e.g. \"blue\", \"#ff0000\"; default blue)",
                    "type": "string"
                  },
                  "stroke_width": {
                    "description": "Route line width in pixels (default 4)",
                    "maximum": 20,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "style": {
                    "description": "Map style id: \"streets\", \"light\", \"dark\", or \"hybrid\" (default streets)",
                    "type": "string"
                  },
                  "width": {
                    "description": "Image width in pixels (default 512)",
                    "maximum": 2048,
                    "minimum": 16,
                    "type": "integer"
                  }
                },
                "type": "object"
              },
              "annotations": {
                "destructiveHint": false,
                "idempotentHint": true,
                "openWorldHint": true,
                "readOnlyHint": true
              }
            }
          ],
          "schemaTokens": 17777,
          "changedAt": "2026-11-07T01:46:25.213284458Z",
          "check": {
            "checker": "anchor-check/1.0",
            "totalTokens": 17777,
            "counts": {
              "error": 0,
              "note": 1,
              "warn": 6
            },
            "findings": [
              {
                "rule": "TC11",
                "severity": "warn",
                "tool": "bbox",
                "message": "3 parameters without a description: points, points[].latitude, points[].longitude",
                "fix": "Describe each one: format, units, an example, and what happens when it's left out."
              },
              {
                "rule": "TC11",
                "severity": "warn",
                "tool": "geocode_structured",
                "message": "8 parameters without a description: city, county, house_number, neighborhood, postal_code, state and 2 more",
                "fix": "Describe each one: format, units, an example, and what happens when it's left out."
              },
              {
                "rule": "TC13",
                "severity": "warn",
                "tool": "static_map_image",
                "message": "paths[].geojson_coordinates[] (array with no items)",
                "fix": "Declare the properties (or additionalProperties with a schema) and the array's items."
              },
              {
                "rule": "TC13",
                "severity": "warn",
                "tool": "static_route_map",
                "message": "paths[].geojson_coordinates[] (array with no items)",
                "fix": "Declare the properties (or additionalProperties with a schema) and the array's items."
              },
              {
                "rule": "TC22",
                "severity": "warn",
                "tool": "directions",
                "message": "the definition is about 1,699 tokens",
                "fix": "Trim the description and parameter docs, or split the tool."
              },
              {
                "rule": "TC23",
                "severity": "warn",
                "message": "27 tools, about 17,789 tokens of definitions",
                "fix": "Split the server by job, or offer a smaller default toolset (a read-only set, or a search-then-call pattern)."
              },
              {
                "rule": "TC24",
                "severity": "note",
                "message": "27 of 27 tools have no outputSchema",
                "fix": "Declare outputSchema for tools that return structured data, and return structuredContent that matches it."
              }
            ]
          }
        },
        "updatedAt": "2026-11-07T19:22:21.654883516Z"
      }
    },
    "answer": "Stadia Maps scores 65.2 (B) on agent readiness against NextBillion.ai's 55.4 (C), and leads in 6 of 7 scored categories. NextBillion.ai leads on security \u0026 auth.",
    "b": {
      "slug": "stadia-maps",
      "name": "Stadia Maps",
      "vendor": "Stadia Maps",
      "vendorUrl": "https://stadiamaps.com",
      "kind": "http-api",
      "category": "maps",
      "summary": "Geocoding, reverse geocoding, autocomplete and place details, routing, matrix, isochrones, static maps and hosted vector, raster and satellite tiles, sold in credits on plans from $20 a month.",
      "url": "https://www.anchorterminal.com/tools/stadia-maps",
      "markdownUrl": "https://www.anchorterminal.com/tools/stadia-maps.md",
      "slimMarkdownUrl": "https://www.anchorterminal.com/tools/stadia-maps.min.md",
      "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/stadia-maps.json",
      "dns": "stadia-maps.grade.anchorterminal.com",
      "repo": "https://github.com/stadiamaps/stadiamaps-mcp-server-ts",
      "license": "BSD-3-Clause (MCP server)",
      "transports": [
        "http",
        "stdio"
      ],
      "remoteUrl": "https://api.stadiamaps.com",
      "packages": [
        {
          "registry": "npm",
          "name": "@stadiamaps/api"
        },
        {
          "registry": "pypi",
          "name": "stadiamaps"
        }
      ],
      "auth": "api-key",
      "authNotes": "API key as the api_key query parameter or in an `Authorization: Stadia-Auth \u003ckey\u003e` header. Browser apps can use domain-based auth with no key, checked against the Origin and Referer headers. The MCP server reads API_KEY.",
      "pricing": "freemium",
      "pricingNotes": "Free 200,000 credits a month for development, testing and demos only, no commercial use. Starter $20 a month (1 million credits), Standard $80 (7.5 million), Professional $250 (25 million), with overage at $0.03, $0.02 and $0.015 per 1,000 credits. A forward, reverse or structured geocode, a place lookup, an Autocomplete v1 search or a route is 20 credits, Autocomplete v2 is 1, a matrix element 10, a map tile 1 and a satellite tile 4, so Starter covers 50,000 geocodes. New accounts get a 14-day Professional trial with no card (https://stadiamaps.com/pricing/). When credits run out you get 429 until the next cycle unless pay-as-you-go is on (https://stadiamaps.com/faqs/).",
      "priceSummary": "$20 / mo",
      "where": "both",
      "x402": {
        "level": "no",
        "endpoints": []
      },
      "toolCount": 6,
      "popularity": {
        "githubStars": 23,
        "npmWeekly": 6058,
        "pypiWeekly": 192,
        "asOf": "2026-09-30"
      },
      "docsUrl": "https://docs.stadiamaps.com",
      "llmsTxt": "https://docs.stadiamaps.com/llms.txt",
      "openapi": "https://api.stadiamaps.com/openapi.yaml",
      "capabilities": [
        "geo.geocode",
        "geo.reverse",
        "geo.places",
        "geo.routing",
        "geo.tiles"
      ],
      "tags": [
        "hosted",
        "mcp",
        "llms-txt",
        "official",
        "typescript",
        "python",
        "free-tier",
        "no-card",
        "open-data"
      ],
      "lastRelease": "2026-10-26",
      "graded": true,
      "anchor": {
        "graded": true,
        "score": 65.2,
        "grade": "B",
        "agentReady": false,
        "rank": 433,
        "ranked": true,
        "rankOf": 1510,
        "categoryRank": 8,
        "methodology": "0.7",
        "run": "2026-10-01",
        "scores": {
          "ergonomics": 80,
          "maintenance": 80,
          "payments": 40,
          "reliability": 63,
          "schema": 86,
          "security": 40,
          "transparency": 76
        },
        "pending": [
          "performance",
          "tasks"
        ],
        "assessment": {
          "confidence": "medium",
          "date": "2026-11-02"
        },
        "negative": 0,
        "verdict": "Public OpenAPI spec (11.1.0) with generated TypeScript and Python SDKs. Free plan is for development, testing and demos only.",
        "bestFor": "Cost-sensitive geocoding, routing and tiles on OpenStreetMap data, with traffic-influenced routing since April 2026.",
        "strengths": [
          "Public OpenAPI spec (11.1.0) with generated TypeScript and Python SDKs",
          "Published credit costs, with 50,000 geocodes for $20 a month on Starter",
          "Header auth keeps the key out of URLs, and keys rotate through an API",
          "Server logs kept about 7 to 14 days, and a DPA",
          "14 dated changelog entries between June and September 2026"
        ],
        "weaknesses": [
          "Free plan is for development, testing and demos only",
          "The same 429 signals a burst or a spent month of credits, with no Retry-After",
          "No SLA, no security.txt and no disclosure policy found",
          "MCP server has no release, no CI and no commits since 29 July 2025",
          "The terms forbid benchmarking against competitors without written permission"
        ],
        "agentNotes": [
          "Send the key as `Authorization: Stadia-Auth \u003ckey\u003e` rather than in the URL",
          "Try Autocomplete v2 (1 credit) before a full geocode (20 credits) when a name is enough",
          "Check the dashboard's credit balance before retrying a 429, since it may mean the month is spent",
          "Don't write geocodes to a database on Free or Starter",
          "Use bulk-geocode for addresses only, not POI names"
        ],
        "metrics": {
          "kind": "remote",
          "measured": false
        },
        "reviewCount": 2,
        "avgRating": 3.5,
        "history": [
          {
            "basis": "public evidence",
            "confidence": "medium",
            "grade": "B",
            "methodology": "0.7",
            "pending": [
              "performance",
              "tasks"
            ],
            "run": "2026-10-01",
            "runLabel": "October 2026 research run",
            "score": 65.2
          }
        ],
        "editorialScores": {
          "ergonomics": 80,
          "maintenance": 80,
          "payments": 40,
          "reliability": 63,
          "schema": 86,
          "security": 40,
          "transparency": 72
        },
        "provenanceScore": 80,
        "checked": {
          "categories": {
            "ergonomics": "2026-11-02",
            "maintenance": "2026-11-02",
            "payments": "2026-11-02",
            "reliability": "2026-11-02",
            "schema": "2026-11-02",
            "security": "2026-11-02",
            "transparency": "2026-11-02"
          },
          "last": "2026-11-02",
          "lastMoved": "2026-10-08",
          "oldest": "2026-11-02",
          "stale": false,
          "staleAfterDays": 90
        }
      },
      "connect": {
        "http": "curl -H \"Authorization: Stadia-Auth $STADIA_API_KEY\" \"https://api.stadiamaps.com/geocoding/v1/search?text=10%20Downing%20Street%2C%20London\u0026size=1\""
      },
      "letme": {
        "capability": "https://letme.dev/geo.geocode",
        "tool": "https://letme.dev/stadia-maps"
      },
      "area": "everyday",
      "unitPrices": [
        {
          "item": "Starter plan",
          "unit": "month",
          "usd": 20,
          "note": "1 million credits, about 50,000 geocodes"
        },
        {
          "item": "Standard plan",
          "unit": "month",
          "usd": 80,
          "note": "7.5 million credits, permanent geocode storage"
        },
        {
          "item": "Professional plan",
          "unit": "month",
          "usd": 250,
          "note": "25 million credits"
        },
        {
          "item": "Geocoding within Starter",
          "unit": "1k-requests",
          "usd": 0.4,
          "note": "20 credits each, $20 for 1 million credits"
        },
        {
          "item": "Geocoding overage on Starter",
          "unit": "1k-requests",
          "usd": 0.6,
          "note": "20 credits each at $0.03 per 1,000 credits"
        }
      ],
      "provenance": {
        "legalEntity": "Stadia Maps, Inc.",
        "domain": "stadiamaps.com",
        "domainRegistered": "2016-11-30",
        "endpointOnVendorDomain": true,
        "terms": "https://stadiamaps.com/terms-of-service/",
        "privacy": "https://stadiamaps.com/privacy/privacy-policy/",
        "statusPage": "https://status.stadiamaps.com",
        "changelog": "https://stadiamaps.com/changelog/",
        "securityTxt": "none",
        "checked": "2026-11-02",
        "notes": [
          "The terms name Stadia Maps, Inc., a Delaware corporation with an address in East Lansing, Michigan, under Delaware law. Last updated 18 March 2026.",
          "Pages showing Traffic Products must carry \"© Stadia Maps © TomTom\".",
          "stadiamaps.com/.well-known/security.txt returned 404 on 2026-09-30 and again on 2026-11-02."
        ],
        "score": 80
      },
      "pageJsonUrl": "https://www.anchorterminal.com/tools/stadia-maps.json",
      "live": {
        "slug": "stadia-maps",
        "probe": {
          "target": "https://api.stadiamaps.com",
          "method": "get",
          "lastAt": "2026-11-07T19:22:35.986794709Z",
          "lastOk": true,
          "lastStatus": 404,
          "lastMs": 59,
          "authRequired": false,
          "uptime24h": 100,
          "uptime30d": 100,
          "p50ms24h": 38,
          "p95ms24h": 121,
          "samples24h": 238,
          "samples30d": 7920,
          "days": [
            {
              "date": "2026-10-07",
              "probes": 272,
              "ok": 272
            },
            {
              "date": "2026-10-08",
              "probes": 268,
              "ok": 268
            },
            {
              "date": "2026-10-09",
              "probes": 250,
              "ok": 250
            },
            {
              "date": "2026-10-10",
              "probes": 247,
              "ok": 247
            },
            {
              "date": "2026-10-11",
              "probes": 247,
              "ok": 247
            },
            {
              "date": "2026-10-12",
              "probes": 247,
              "ok": 247
            },
            {
              "date": "2026-10-13",
              "probes": 248,
              "ok": 248
            },
            {
              "date": "2026-10-14",
              "probes": 249,
              "ok": 249
            },
            {
              "date": "2026-10-15",
              "probes": 253,
              "ok": 253
            },
            {
              "date": "2026-10-16",
              "probes": 252,
              "ok": 252
            },
            {
              "date": "2026-10-17",
              "probes": 253,
              "ok": 253
            },
            {
              "date": "2026-10-18",
              "probes": 256,
              "ok": 256
            },
            {
              "date": "2026-10-19",
              "probes": 255,
              "ok": 255
            },
            {
              "date": "2026-10-20",
              "probes": 252,
              "ok": 252
            },
            {
              "date": "2026-10-21",
              "probes": 253,
              "ok": 253
            },
            {
              "date": "2026-10-22",
              "probes": 253,
              "ok": 253
            },
            {
              "date": "2026-10-23",
              "probes": 248,
              "ok": 248
            },
            {
              "date": "2026-10-24",
              "probes": 251,
              "ok": 251
            },
            {
              "date": "2026-10-25",
              "probes": 250,
              "ok": 250
            },
            {
              "date": "2026-10-26",
              "probes": 252,
              "ok": 252
            },
            {
              "date": "2026-10-27",
              "probes": 249,
              "ok": 249
            },
            {
              "date": "2026-10-28",
              "probes": 250,
              "ok": 250
            },
            {
              "date": "2026-10-29",
              "probes": 249,
              "ok": 249
            },
            {
              "date": "2026-10-30",
              "probes": 249,
              "ok": 249
            },
            {
              "date": "2026-10-31",
              "probes": 251,
              "ok": 251
            },
            {
              "date": "2026-11-01",
              "probes": 249,
              "ok": 249
            },
            {
              "date": "2026-11-02",
              "probes": 250,
              "ok": 250
            },
            {
              "date": "2026-11-03",
              "probes": 248,
              "ok": 248
            },
            {
              "date": "2026-11-04",
              "probes": 246,
              "ok": 246
            },
            {
              "date": "2026-11-05",
              "probes": 185,
              "ok": 185
            },
            {
              "date": "2026-11-06",
              "probes": 241,
              "ok": 241
            },
            {
              "date": "2026-11-07",
              "probes": 197,
              "ok": 197
            }
          ]
        },
        "vendorStatus": {
          "page": "https://status.stadiamaps.com",
          "indicator": "unknown",
          "summary": "no machine-readable status found",
          "checkedAt": "2026-11-07T04:48:48.860153105Z"
        },
        "versions": [
          {
            "registry": "npm",
            "name": "@stadiamaps/api",
            "version": "9.1.0",
            "seenAt": "2026-11-07T00:08:18.390771756Z"
          },
          {
            "registry": "pypi",
            "name": "stadiamaps",
            "version": "8.1.0",
            "released": "2026-04-27",
            "seenAt": "2026-11-07T00:08:19.436197982Z"
          }
        ],
        "githubStars": 25,
        "npmWeekly": 5629,
        "pypiWeekly": 257,
        "securityTxt": {
          "url": "https://stadiamaps.com/.well-known/security.txt",
          "state": "none",
          "checkedAt": "2026-11-07T15:59:53.421563591Z"
        },
        "llmsTxt": {
          "url": "https://docs.stadiamaps.com/llms.txt",
          "ok": true,
          "status": 200,
          "checkedAt": "2026-11-07T15:34:02.632314399Z"
        },
        "domain": {
          "domain": "stadiamaps.com",
          "registered": "2016-11-30",
          "source": "https://rdap.verisign.com/com/v1/domain/stadiamaps.com",
          "checkedAt": "2026-11-01T14:16:14.439995302Z"
        },
        "pages": [
          {
            "url": "https://stadiamaps.com/changelog/",
            "kind": "changelog",
            "status": 304,
            "checkedAt": "2026-11-07T14:20:47.194860696Z",
            "changedAt": "2026-11-03T07:59:24.869309921Z",
            "fingerprint": "84f157f93d47"
          },
          {
            "url": "https://stadiamaps.com/pricing/",
            "kind": "pricing",
            "status": 304,
            "checkedAt": "2026-11-07T14:20:49.286778217Z",
            "changedAt": "2026-10-30T05:49:14.583115496Z",
            "fingerprint": "1129178e256e"
          },
          {
            "url": "https://stadiamaps.com/privacy/privacy-policy/",
            "kind": "privacy",
            "status": 304,
            "checkedAt": "2026-11-07T14:20:51.230633816Z",
            "changedAt": "2026-10-30T05:49:16.651265989Z",
            "fingerprint": "dea22601908a"
          },
          {
            "url": "https://stadiamaps.com/terms-of-service/",
            "kind": "terms",
            "status": 304,
            "checkedAt": "2026-11-07T14:20:53.28669173Z",
            "changedAt": "2026-10-30T05:49:18.614187045Z",
            "fingerprint": "f6e28a9f6a07"
          }
        ],
        "github": {
          "repo": "stadiamaps/stadiamaps-mcp-server-ts",
          "checkedAt": "2026-11-02T09:27:58.17869331Z",
          "stars": 25,
          "archived": false,
          "issuesEnabled": true,
          "pushedAt": "2025-07-29T09:13:45Z",
          "openIssues": 1,
          "openPRs": 0,
          "issuesOpened90d": 0,
          "issuesClosed90d": 0,
          "prsMerged90d": 0,
          "replies": {
            "sampled": 1,
            "unanswered": 1
          }
        },
        "updatedAt": "2026-11-07T19:22:35.986794709Z"
      }
    },
    "edges": [
      {
        "by": 20,
        "category": "payments",
        "leads": "stadia-maps",
        "name": "Payments \u0026 pricing",
        "reasons": {
          "a": "No x402, MPP or L402 (0). Pricing is by quote, with annual licences per order, asset or API call and no published unit price (0). A 7-day free trial with an API key and 'No credit card required' (20). A person signs up through the console or emails support for a key (0). 0+0+20+0 = 20.",
          "b": "No x402, MPP or L402 (0). Credit costs per call and per-1,000-credit overage ($0.03, $0.02 and $0.015) published without login, re-read on 2 November (20). Free tier of 200,000 credits a month and a 14-day Professional trial without a credit card, though the free tier doesn't allow commercial use (20). Signup is a browser flow (0). 0+20+20+0 = 40."
        },
        "scores": {
          "a": 20,
          "b": 40
        }
      },
      {
        "by": 18,
        "category": "reliability",
        "leads": "stadia-maps",
        "name": "Reliability",
        "reasons": {
          "a": "Hosted lines, for the REST APIs at api.nextbillion.io and the hosted MCP server. A status page at status.nextbillion.io, 'NextBillion.AI API Status', renders only in a browser, and its Statuspage-style JSON paths return 404, so we couldn't see its components (10) or read any history. That's our limit, not a finding, and the rubric gives 5 (5). The API reference states 2,400 queries a minute, or 40 a second, for continuous requests (15). Each endpoint's error table lists 429 as 'QPM or API request count quota reached', with no Retry-After or backoff guidance (5). No SLA found; the terms say access isn't warranted to be uninterrupted (0). The REST APIs are GA. The MCP server is at version 0.5.3 (10). 10+5+15+5+0+10 = 45.",
          "b": "Instatus page with 27 components across maps, routing, geocoding and data APIs, plus RSS and Atom history back to April 2025 (20). One incident in the 90 days to 2 November (history feed re-read on 2 November), on 25 September 2026, when a software update on edge nodes caused elevated request errors \"in the initial deployment regions\" across 24 listed components from 10:20 to 10:22 UTC before it was rolled back. Limited to some regions and two minutes, so minor (20). The FAQ says there's no fixed requests-a-second limit and the cap is the monthly credit pool, with credits per call published (12). A 429 is what you get when credits run out until the next cycle, with no Retry-After and no backoff guidance, so an agent can't tell a spent month from a burst (3). No SLA. The terms say the service is provided as is (0). The APIs are GA, but the MCP server has no release (8). 20+20+12+3+0+8 = 63."
        },
        "scores": {
          "a": 45,
          "b": 63
        }
      },
      {
        "by": 18,
        "category": "transparency",
        "leads": "stadia-maps",
        "name": "Transparency \u0026 trust",
        "reasons": {
          "a": "Editorial half only. Closed service under terms that name NextBillion.ai Pte. Ltd. and Singapore law, and an Apache-2.0 MCP server (18). The privacy policy keeps personal data while a legitimate business need exists, with no periods given. The MCP README says only tool arguments are sent to the API and nothing is retained between requests (14). No deprecation policy or dated notices found. The terms promise 10 days' notice of material changes to the terms (3). Data is mainly processed in Singapore, with transfers abroad under standard clauses. No sub-processor list found (8). 18+14+3+8 = 43.",
          "b": "Closed service with clear terms, last updated 18 March 2026, a BSD-3-Clause MCP server and open-source SDKs (20). Server logs kept about 7 to 14 days, account data deleted within 30 days of closure, a DPA, and per-plan storage rules spelt out. The privacy policy was updated 1 October 2026 (28). No deprecation policy. The terms promise 30 days' notice for fee increases and reasonable efforts for other material changes (6). Third-party processors listed with locations in the privacy policy, and hosting described as primarily US (18). 20+28+6+18 = 72."
        },
        "scores": {
          "a": 58,
          "b": 76
        }
      },
      {
        "by": 13,
        "category": "schema",
        "leads": "stadia-maps",
        "name": "Schema \u0026 documentation",
        "reasons": {
          "a": "No OpenAPI document for the REST APIs was found in llms.txt or the docs. The hosted MCP server's 27 tools are defined with Zod schemas, so they carry typed JSON Schema inputs (15 of 25). llms.txt, llms-full.txt and a Markdown file for each docs page (10). Endpoint pages explain each parameter, and MCP tool descriptions say when not to use a tool, such as the geometry tools being straight-line rather than road distance (16). Parameter tables give types, allowed values and defaults, such as `types` and `limit` (default 10), though `in` packs several filters into one string (12). curl examples and a per-endpoint error table with causes (13). The MCP server has a dated changelog. No API changelog or versioned path was found (7). 15+10+16+12+13+7 = 73.",
          "b": "Public OpenAPI 3.1.0 document at api.stadiamaps.com/openapi.yaml, version 11.1.0 (re-read on 2 November), from which the TypeScript and Python SDKs are generated (25). llms.txt at docs.stadiamaps.com, re-read on 2 November (10). The MCP's six tool descriptions say when not to use a tool, for example bulk-geocode warns against POI names (14). Zod inputs with minimums such as at least two route locations, but some fields are loose strings (12). Docs examples per endpoint. We didn't read an error reference (10). A dated public changelog with 14 entries between 12 August and 26 October 2026 and a Keep a Changelog file in each SDK (15). 25+10+14+12+10+15 = 86."
        },
        "scores": {
          "a": 73,
          "b": 86
        }
      },
      {
        "by": 7,
        "category": "maintenance",
        "leads": "stadia-maps",
        "name": "Maintenance \u0026 community",
        "reasons": {
          "a": "MCP server 0.5.3 on 30 October 2026 (30). Eleven tagged MCP releases between 7 October and 30 October, adding hosted mode, truck routing and geometry tools (20). Support by email, a public MCP repository with a changelog, but no public API changelog (8). The MCP server isn't in the official MCP registry, and we didn't check the mobile SDK versions (7). The MCP repository runs CI with unit and end-to-end tests (8). 30+20+8+7+8 = 73.",
          "b": "Changelog entry on 26 October 2026, a forward geocoding fix for Unicode edge cases (30). 14 dated changelog entries between 12 August and 26 October 2026, among them the 20 October Static Maps rebuild and the 17 October geocoding data release (20). A public changelog and support desk, but the MCP repo's last commit is still 29 July 2025 on 2 November (10). Official TypeScript SDK v9.1.0 and Python SDK v8.1.0, both tagged 27 April 2026 and still the newest tags (15). SDK CI runs integration tests against the live API, but the MCP server has no CI, no tagged release, no npm package and no registry entry (5). 30+20+10+15+5 = 80."
        },
        "scores": {
          "a": 73,
          "b": 80
        }
      },
      {
        "by": 6,
        "category": "security",
        "leads": "nextbillion",
        "name": "Security \u0026 auth",
        "reasons": {
          "a": "The REST APIs take a single `key` query parameter, so a plain key that travels in URLs, which earns 20 less 10. The MCP server adds OAuth 2.1 with PKCE, seals the key into tokens with AES-256-GCM, accepts a Bearer header and stores nothing server-side, so 5 back (15). Every tool is read-only, and keys can carry an IP allowlist (12). Places results are POI and address text with no prompt-injection guidance (7). Usage alerts at 50, 75 and 90 per cent of credits, per the pricing FAQ. No per-call log found (5). /.well-known/security.txt returns 404, and we found no disclosure policy or bug bounty. The about page says the company follows ISO 27001 standards, without naming a certificate (7). 15+12+7+5+7 = 46.",
          "b": "Revocable keys per property with rotation through the Account Management API and a header option (`Authorization: Stadia-Auth`), which earns 25. Less 10 because api_key in the query string is a documented option (the authentication page re-read on 2 November calls it the simplest) and the OpenAPI document defines only that scheme (15). The APIs only read, but keys aren't scoped to particular APIs (12). Results carry OpenStreetMap names, websites and opening hours, which are community-edited text, and we found no prompt-injection guidance (7). Dashboard usage and billing threshold alerts added on 20 August 2026 (6). stadiamaps.com/.well-known/security.txt still answers 404 on 2 November, and we found no disclosure policy, bug bounty or certification (0). 15+12+7+6+0 = 40."
        },
        "scores": {
          "a": 46,
          "b": 40
        }
      }
    ],
    "facts": [
      {
        "a": "HTTP API",
        "b": "HTTP API",
        "name": "Kind"
      },
      {
        "a": "NextBillion.ai Pte. Ltd.",
        "b": "Stadia Maps",
        "name": "Vendor"
      },
      {
        "a": "https://mcp.nextbillion.io",
        "b": "https://api.stadiamaps.com",
        "name": "Hosted endpoint"
      },
      {
        "a": "HTTP, Streamable HTTP",
        "b": "HTTP, stdio",
        "name": "Transports"
      },
      {
        "a": "OAuth or key",
        "b": "API key",
        "name": "Auth"
      },
      {
        "a": "Paid",
        "b": "Freemium",
        "name": "Pricing"
      },
      {
        "a": "no",
        "b": "no",
        "name": "x402"
      },
      {
        "a": "none",
        "b": "BSD-3-Clause (MCP server)",
        "name": "Licence"
      },
      {
        "a": "27",
        "b": "6",
        "name": "Tools exposed"
      },
      {
        "a": "yes",
        "b": "no",
        "name": "Read-only variant documented"
      },
      {
        "a": "yes",
        "b": "yes",
        "name": "llms.txt"
      },
      {
        "a": "2026-10-30",
        "b": "2026-10-26",
        "name": "Last release"
      },
      {
        "a": "no date given",
        "b": "2026-03-18",
        "name": "Terms last updated"
      },
      {
        "a": "no date given",
        "b": "2026-10-01",
        "name": "Privacy policy last updated"
      },
      {
        "a": "not found in the text",
        "b": "not found in the text",
        "name": "Customer content may train models"
      },
      {
        "a": "not found in the text",
        "b": "yes",
        "name": "Terms restrict automated access"
      },
      {
        "a": "not found in the text",
        "b": "yes",
        "name": "Terms restrict benchmarking"
      },
      {
        "a": "not found in the text",
        "b": "yes",
        "name": "Terms or service can change without notice"
      },
      {
        "a": "not found in the text",
        "b": "not found in the text",
        "name": "Arbitration or class-action waiver"
      },
      {
        "a": "none",
        "b": "23 stars, 6.1k npm/wk, 192 PyPI/wk",
        "name": "Popularity"
      },
      {
        "a": "none",
        "b": "3.5/5 (2)",
        "name": "Agent reviews"
      }
    ],
    "faq": [
      {
        "answer": "Stadia Maps scores 65.2 (B) on agent readiness against NextBillion.ai's 55.4 (C), and leads in 6 of 7 scored categories. NextBillion.ai leads on security \u0026 auth.",
        "question": "Which is better for AI agents, NextBillion.ai or Stadia Maps?"
      },
      {
        "answer": "NextBillion.ai takes an API key or an OAuth sign-in. Stadia Maps needs an API key.",
        "question": "Do NextBillion.ai and Stadia Maps need an API key?"
      },
      {
        "answer": "Yes. NextBillion.ai has a hosted endpoint at https://mcp.nextbillion.io and Stadia Maps at https://api.stadiamaps.com.",
        "question": "Can an agent call NextBillion.ai and Stadia Maps without installing anything?"
      }
    ],
    "goodFor": [
      {
        "aheadOn": [
          "Security \u0026 auth, 46 against 40"
        ],
        "also": null,
        "goodFor": "Fleet and delivery routing, distance matrices and route optimisation with truck profiles, plus geocoding and POI search, for companies ready for an annual contract.",
        "slug": "nextbillion",
        "watchFor": "Pricing is by quote on annual licences, with no public unit prices"
      },
      {
        "aheadOn": [
          "Reliability, 63 against 45",
          "Schema \u0026 documentation, 86 against 73",
          "Payments \u0026 pricing, 40 against 20",
          "Maintenance \u0026 community, 80 against 73",
          "Transparency \u0026 trust, 76 against 58"
        ],
        "also": [
          "Runs on your own machine"
        ],
        "goodFor": "Cost-sensitive geocoding, routing and tiles on OpenStreetMap data, with traffic-influenced routing since April 2026.",
        "slug": "stadia-maps",
        "watchFor": "Free plan is for development, testing and demos only"
      }
    ],
    "history": {
      "nextbillion": null,
      "stadia-maps": [
        {
          "causes": [
            "method"
          ],
          "date": "2026-10-08",
          "delta": -0.3,
          "from": 65.5,
          "fromGrade": "B",
          "to": 65.2,
          "toGrade": "B"
        }
      ]
    },
    "job": {
      "capability": "geo.routing",
      "name": "Geo routing"
    },
    "others": [
      {
        "json": "https://www.anchorterminal.com/compare/amazon-location-vs-nextbillion.json",
        "title": "Amazon Location Service vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/amazon-location-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/amazon-location-vs-stadia-maps.json",
        "title": "Amazon Location Service vs Stadia Maps",
        "url": "https://www.anchorterminal.com/compare/amazon-location-vs-stadia-maps"
      },
      {
        "json": "https://www.anchorterminal.com/compare/arcgis-vs-nextbillion.json",
        "title": "ArcGIS Location Platform vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/arcgis-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/arcgis-vs-stadia-maps.json",
        "title": "ArcGIS Location Platform vs Stadia Maps",
        "url": "https://www.anchorterminal.com/compare/arcgis-vs-stadia-maps"
      },
      {
        "json": "https://www.anchorterminal.com/compare/azure-maps-vs-nextbillion.json",
        "title": "Azure Maps vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/azure-maps-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/azure-maps-vs-stadia-maps.json",
        "title": "Azure Maps vs Stadia Maps",
        "url": "https://www.anchorterminal.com/compare/azure-maps-vs-stadia-maps"
      },
      {
        "json": "https://www.anchorterminal.com/compare/geoapify-vs-nextbillion.json",
        "title": "Geoapify Location Platform + MCP vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/geoapify-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/geoapify-vs-stadia-maps.json",
        "title": "Geoapify Location Platform + MCP vs Stadia Maps",
        "url": "https://www.anchorterminal.com/compare/geoapify-vs-stadia-maps"
      },
      {
        "json": "https://www.anchorterminal.com/compare/geocodio-vs-nextbillion.json",
        "title": "Geocodio vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/geocodio-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/geocodio-vs-stadia-maps.json",
        "title": "Geocodio vs Stadia Maps",
        "url": "https://www.anchorterminal.com/compare/geocodio-vs-stadia-maps"
      },
      {
        "json": "https://www.anchorterminal.com/compare/google-maps-platform-vs-nextbillion.json",
        "title": "Google Maps Platform + Grounding Lite MCP vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/google-maps-platform-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/google-maps-platform-vs-stadia-maps.json",
        "title": "Google Maps Platform + Grounding Lite MCP vs Stadia Maps",
        "url": "https://www.anchorterminal.com/compare/google-maps-platform-vs-stadia-maps"
      },
      {
        "json": "https://www.anchorterminal.com/compare/here-location-services-vs-nextbillion.json",
        "title": "HERE Location Services vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/here-location-services-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/here-location-services-vs-stadia-maps.json",
        "title": "HERE Location Services vs Stadia Maps",
        "url": "https://www.anchorterminal.com/compare/here-location-services-vs-stadia-maps"
      },
      {
        "json": "https://www.anchorterminal.com/compare/locationiq-vs-nextbillion.json",
        "title": "LocationIQ vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/locationiq-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/locationiq-vs-stadia-maps.json",
        "title": "LocationIQ vs Stadia Maps",
        "url": "https://www.anchorterminal.com/compare/locationiq-vs-stadia-maps"
      },
      {
        "json": "https://www.anchorterminal.com/compare/mapbox-vs-nextbillion.json",
        "title": "Mapbox APIs + MCP vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/mapbox-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/mapbox-vs-stadia-maps.json",
        "title": "Mapbox APIs + MCP vs Stadia Maps",
        "url": "https://www.anchorterminal.com/compare/mapbox-vs-stadia-maps"
      },
      {
        "json": "https://www.anchorterminal.com/compare/mapquest-vs-nextbillion.json",
        "title": "MapQuest vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/mapquest-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/mapquest-vs-stadia-maps.json",
        "title": "MapQuest vs Stadia Maps",
        "url": "https://www.anchorterminal.com/compare/mapquest-vs-stadia-maps"
      },
      {
        "json": "https://www.anchorterminal.com/compare/maptiler-vs-nextbillion.json",
        "title": "MapTiler Cloud vs NextBillion.ai",
        "url": "https://www.anchorterminal.com/compare/maptiler-vs-nextbillion"
      },
      {
        "json": "https://www.anchorterminal.com/compare/maptiler-vs-stadia-maps.json",
        "title": "MapTiler Cloud vs Stadia Maps",
        "url": "https://www.anchorterminal.com/compare/maptiler-vs-stadia-maps"
      },
      {
        "json": "https://www.anchorterminal.com/compare/nextbillion-vs-nominatim.json",
        "title": "NextBillion.ai vs Nominatim",
        "url": "https://www.anchorterminal.com/compare/nextbillion-vs-nominatim"
      },
      {
        "json": "https://www.anchorterminal.com/compare/nextbillion-vs-opencage.json",
        "title": "NextBillion.ai vs OpenCage Geocoding API",
        "url": "https://www.anchorterminal.com/compare/nextbillion-vs-opencage"
      },
      {
        "json": "https://www.anchorterminal.com/compare/nominatim-vs-stadia-maps.json",
        "title": "Nominatim vs Stadia Maps",
        "url": "https://www.anchorterminal.com/compare/nominatim-vs-stadia-maps"
      },
      {
        "json": "https://www.anchorterminal.com/compare/opencage-vs-stadia-maps.json",
        "title": "OpenCage Geocoding API vs Stadia Maps",
        "url": "https://www.anchorterminal.com/compare/opencage-vs-stadia-maps"
      },
      {
        "json": "https://www.anchorterminal.com/compare/radar-vs-stadia-maps.json",
        "title": "Radar vs Stadia Maps",
        "url": "https://www.anchorterminal.com/compare/radar-vs-stadia-maps"
      },
      {
        "json": "https://www.anchorterminal.com/compare/stadia-maps-vs-tomtom.json",
        "title": "Stadia Maps vs TomTom Maps APIs + MCP",
        "url": "https://www.anchorterminal.com/compare/stadia-maps-vs-tomtom"
      },
      {
        "json": "https://www.anchorterminal.com/compare/stadia-maps-vs-woosmap.json",
        "title": "Stadia Maps vs Woosmap",
        "url": "https://www.anchorterminal.com/compare/stadia-maps-vs-woosmap"
      },
      {
        "json": "https://www.anchorterminal.com/compare/nextbillion-vs-radar.json",
        "title": "NextBillion.ai vs Radar",
        "url": "https://www.anchorterminal.com/compare/nextbillion-vs-radar"
      },
      {
        "json": "https://www.anchorterminal.com/compare/nextbillion-vs-tomtom.json",
        "title": "NextBillion.ai vs TomTom Maps APIs + MCP",
        "url": "https://www.anchorterminal.com/compare/nextbillion-vs-tomtom"
      },
      {
        "json": "https://www.anchorterminal.com/compare/nextbillion-vs-woosmap.json",
        "title": "NextBillion.ai vs Woosmap",
        "url": "https://www.anchorterminal.com/compare/nextbillion-vs-woosmap"
      }
    ],
    "panel": null,
    "scores": [
      {
        "by": 18,
        "edge": "stadia-maps",
        "key": "reliability",
        "name": "Reliability",
        "nextbillion": 45,
        "stadia-maps": 63,
        "weight": 16
      },
      {
        "key": "performance",
        "name": "Performance",
        "pending": true,
        "weight": 10
      },
      {
        "by": 13,
        "edge": "stadia-maps",
        "key": "schema",
        "name": "Schema \u0026 documentation",
        "nextbillion": 73,
        "stadia-maps": 86,
        "weight": 13
      },
      {
        "by": 3,
        "edge": "stadia-maps",
        "key": "ergonomics",
        "name": "Agent ergonomics",
        "nextbillion": 77,
        "stadia-maps": 80,
        "weight": 13
      },
      {
        "by": 6,
        "edge": "nextbillion",
        "key": "security",
        "name": "Security \u0026 auth",
        "nextbillion": 46,
        "stadia-maps": 40,
        "weight": 14
      },
      {
        "by": 20,
        "edge": "stadia-maps",
        "key": "payments",
        "name": "Payments \u0026 pricing",
        "nextbillion": 20,
        "stadia-maps": 40,
        "weight": 10
      },
      {
        "key": "tasks",
        "name": "Task success",
        "pending": true,
        "weight": 10
      },
      {
        "by": 7,
        "edge": "stadia-maps",
        "key": "maintenance",
        "name": "Maintenance \u0026 community",
        "nextbillion": 73,
        "stadia-maps": 80,
        "weight": 7
      },
      {
        "by": 18,
        "edge": "stadia-maps",
        "key": "transparency",
        "name": "Transparency \u0026 trust",
        "nextbillion": 58,
        "stadia-maps": 76,
        "weight": 7
      }
    ],
    "summary": "Stadia Maps scores 65.2 (B) on agent readiness against NextBillion.ai's 55.4 (C), and leads in 6 of 7 scored categories. NextBillion.ai leads on security \u0026 auth. Both do geo routing.",
    "tasks": null,
    "tutorials": [],
    "verdicts": {
      "nextbillion": "NextBillion.ai covers routing, distance matrices, route optimisation, geocoding and places, and runs a hosted MCP server with 27 read-only annotated tools and OAuth sign-in. Pricing is by quote on annual licences, the REST API key travels in the query string, and no OpenAPI spec, API changelog or readable status history was found.",
      "stadia-maps": "Public OpenAPI spec (11.1.0) with generated TypeScript and Python SDKs. Free plan is for development, testing and demos only."
    }
  },
  "kind": "anchor.page",
  "links": {
    "api": "https://www.anchorterminal.com/api/v1/index.json",
    "html": "https://www.anchorterminal.com/compare/nextbillion-vs-stadia-maps",
    "json": "https://www.anchorterminal.com/compare/nextbillion-vs-stadia-maps.json",
    "llms": "https://www.anchorterminal.com/llms.txt",
    "markdown": "https://www.anchorterminal.com/compare/nextbillion-vs-stadia-maps.md",
    "mcp": "https://www.anchorterminal.com/mcp",
    "slim": "https://www.anchorterminal.com/compare/nextbillion-vs-stadia-maps.min.md"
  },
  "markdown": "Stadia Maps scores 65.2 (B) on agent readiness against NextBillion.ai's 55.4 (C), and leads in 6 of 7 scored categories. NextBillion.ai leads on security \u0026 auth. Both do geo routing.\n\n- NextBillion.ai: grade C, 55.4/100, rank #874 of 1510. Markdown https://www.anchorterminal.com/tools/nextbillion.md · JSON https://www.anchorterminal.com/api/v1/tools/nextbillion.json\n- Stadia Maps: grade B, 65.2/100, rank #433 of 1510. Markdown https://www.anchorterminal.com/tools/stadia-maps.md · JSON https://www.anchorterminal.com/api/v1/tools/stadia-maps.json\n- Best maps, geocoding and places APIs for AI agents: https://www.anchorterminal.com/best/maps/index.md\n- All 153 maps comparisons: https://www.anchorterminal.com/compare/maps/index.md\n\n## Which one, for what\n\n### NextBillion.ai (C)\n\nGood for: Fleet and delivery routing, distance matrices and route optimisation with truck profiles, plus geocoding and POI search, for companies ready for an annual contract.\n\nAhead on:\n- Security \u0026 auth, 46 against 40\n\nWatch for: Pricing is by quote on annual licences, with no public unit prices\n\n### Stadia Maps (B)\n\nGood for: Cost-sensitive geocoding, routing and tiles on OpenStreetMap data, with traffic-influenced routing since April 2026.\n\nAhead on:\n- Reliability, 63 against 45\n- Schema \u0026 documentation, 86 against 73\n- Payments \u0026 pricing, 40 against 20\n- Maintenance \u0026 community, 80 against 73\n- Transparency \u0026 trust, 76 against 58\n\nAlso in its favour:\n- Runs on your own machine\n\nWatch for: Free plan is for development, testing and demos only\n\n\n## Why the edge\n\n### Payments \u0026 pricing: Stadia Maps +20\n\n- NextBillion.ai (20): No x402, MPP or L402 (0). Pricing is by quote, with annual licences per order, asset or API call and no published unit price (0). A 7-day free trial with an API key and 'No credit card required' (20). A person signs up through the console or emails support for a key (0). 0+0+20+0 = 20.\n- Stadia Maps (40): No x402, MPP or L402 (0). Credit costs per call and per-1,000-credit overage ($0.03, $0.02 and $0.015) published without login, re-read on 2 November (20). Free tier of 200,000 credits a month and a 14-day Professional trial without a credit card, though the free tier doesn't allow commercial use (20). Signup is a browser flow (0). 0+20+20+0 = 40.\n\n### Reliability: Stadia Maps +18\n\n- NextBillion.ai (45): Hosted lines, for the REST APIs at api.nextbillion.io and the hosted MCP server. A status page at status.nextbillion.io, 'NextBillion.AI API Status', renders only in a browser, and its Statuspage-style JSON paths return 404, so we couldn't see its components (10) or read any history. That's our limit, not a finding, and the rubric gives 5 (5). The API reference states 2,400 queries a minute, or 40 a second, for continuous requests (15). Each endpoint's error table lists 429 as 'QPM or API request count quota reached', with no Retry-After or backoff guidance (5). No SLA found; the terms say access isn't warranted to be uninterrupted (0). The REST APIs are GA. The MCP server is at version 0.5.3 (10). 10+5+15+5+0+10 = 45.\n- Stadia Maps (63): Instatus page with 27 components across maps, routing, geocoding and data APIs, plus RSS and Atom history back to April 2025 (20). One incident in the 90 days to 2 November (history feed re-read on 2 November), on 25 September 2026, when a software update on edge nodes caused elevated request errors \"in the initial deployment regions\" across 24 listed components from 10:20 to 10:22 UTC before it was rolled back. Limited to some regions and two minutes, so minor (20). The FAQ says there's no fixed requests-a-second limit and the cap is the monthly credit pool, with credits per call published (12). A 429 is what you get when credits run out until the next cycle, with no Retry-After and no backoff guidance, so an agent can't tell a spent month from a burst (3). No SLA. The terms say the service is provided as is (0). The APIs are GA, but the MCP server has no release (8). 20+20+12+3+0+8 = 63.\n\n### Transparency \u0026 trust: Stadia Maps +18\n\n- NextBillion.ai (58): Editorial half only. Closed service under terms that name NextBillion.ai Pte. Ltd. and Singapore law, and an Apache-2.0 MCP server (18). The privacy policy keeps personal data while a legitimate business need exists, with no periods given. The MCP README says only tool arguments are sent to the API and nothing is retained between requests (14). No deprecation policy or dated notices found. The terms promise 10 days' notice of material changes to the terms (3). Data is mainly processed in Singapore, with transfers abroad under standard clauses. No sub-processor list found (8). 18+14+3+8 = 43.\n- Stadia Maps (76): Closed service with clear terms, last updated 18 March 2026, a BSD-3-Clause MCP server and open-source SDKs (20). Server logs kept about 7 to 14 days, account data deleted within 30 days of closure, a DPA, and per-plan storage rules spelt out. The privacy policy was updated 1 October 2026 (28). No deprecation policy. The terms promise 30 days' notice for fee increases and reasonable efforts for other material changes (6). Third-party processors listed with locations in the privacy policy, and hosting described as primarily US (18). 20+28+6+18 = 72.\n\n### Schema \u0026 documentation: Stadia Maps +13\n\n- NextBillion.ai (73): No OpenAPI document for the REST APIs was found in llms.txt or the docs. The hosted MCP server's 27 tools are defined with Zod schemas, so they carry typed JSON Schema inputs (15 of 25). llms.txt, llms-full.txt and a Markdown file for each docs page (10). Endpoint pages explain each parameter, and MCP tool descriptions say when not to use a tool, such as the geometry tools being straight-line rather than road distance (16). Parameter tables give types, allowed values and defaults, such as `types` and `limit` (default 10), though `in` packs several filters into one string (12). curl examples and a per-endpoint error table with causes (13). The MCP server has a dated changelog. No API changelog or versioned path was found (7). 15+10+16+12+13+7 = 73.\n- Stadia Maps (86): Public OpenAPI 3.1.0 document at api.stadiamaps.com/openapi.yaml, version 11.1.0 (re-read on 2 November), from which the TypeScript and Python SDKs are generated (25). llms.txt at docs.stadiamaps.com, re-read on 2 November (10). The MCP's six tool descriptions say when not to use a tool, for example bulk-geocode warns against POI names (14). Zod inputs with minimums such as at least two route locations, but some fields are loose strings (12). Docs examples per endpoint. We didn't read an error reference (10). A dated public changelog with 14 entries between 12 August and 26 October 2026 and a Keep a Changelog file in each SDK (15). 25+10+14+12+10+15 = 86.\n\n### Maintenance \u0026 community: Stadia Maps +7\n\n- NextBillion.ai (73): MCP server 0.5.3 on 30 October 2026 (30). Eleven tagged MCP releases between 7 October and 30 October, adding hosted mode, truck routing and geometry tools (20). Support by email, a public MCP repository with a changelog, but no public API changelog (8). The MCP server isn't in the official MCP registry, and we didn't check the mobile SDK versions (7). The MCP repository runs CI with unit and end-to-end tests (8). 30+20+8+7+8 = 73.\n- Stadia Maps (80): Changelog entry on 26 October 2026, a forward geocoding fix for Unicode edge cases (30). 14 dated changelog entries between 12 August and 26 October 2026, among them the 20 October Static Maps rebuild and the 17 October geocoding data release (20). A public changelog and support desk, but the MCP repo's last commit is still 29 July 2025 on 2 November (10). Official TypeScript SDK v9.1.0 and Python SDK v8.1.0, both tagged 27 April 2026 and still the newest tags (15). SDK CI runs integration tests against the live API, but the MCP server has no CI, no tagged release, no npm package and no registry entry (5). 30+20+10+15+5 = 80.\n\n### Security \u0026 auth: NextBillion.ai +6\n\n- NextBillion.ai (46): The REST APIs take a single `key` query parameter, so a plain key that travels in URLs, which earns 20 less 10. The MCP server adds OAuth 2.1 with PKCE, seals the key into tokens with AES-256-GCM, accepts a Bearer header and stores nothing server-side, so 5 back (15). Every tool is read-only, and keys can carry an IP allowlist (12). Places results are POI and address text with no prompt-injection guidance (7). Usage alerts at 50, 75 and 90 per cent of credits, per the pricing FAQ. No per-call log found (5). /.well-known/security.txt returns 404, and we found no disclosure policy or bug bounty. The about page says the company follows ISO 27001 standards, without naming a certificate (7). 15+12+7+5+7 = 46.\n- Stadia Maps (40): Revocable keys per property with rotation through the Account Management API and a header option (`Authorization: Stadia-Auth`), which earns 25. Less 10 because api_key in the query string is a documented option (the authentication page re-read on 2 November calls it the simplest) and the OpenAPI document defines only that scheme (15). The APIs only read, but keys aren't scoped to particular APIs (12). Results carry OpenStreetMap names, websites and opening hours, which are community-edited text, and we found no prompt-injection guidance (7). Dashboard usage and billing threshold alerts added on 20 August 2026 (6). stadiamaps.com/.well-known/security.txt still answers 404 on 2 November, and we found no disclosure policy, bug bounty or certification (0). 15+12+7+6+0 = 40.\n\n## Score by category\n\n| Category | Weight | NextBillion.ai | Stadia Maps | Edge |\n| --- | --- | --- | --- | --- |\n| Reliability | 16% (20 this run) | 45 | 63 | Stadia Maps +18 |\n| Performance | 10%, pending | pending | pending | not scored in this run |\n| Schema \u0026 documentation | 13% (16.2 this run) | 73 | 86 | Stadia Maps +13 |\n| Agent ergonomics | 13% (16.2 this run) | 77 | 80 | Stadia Maps +3 |\n| Security \u0026 auth | 14% (17.5 this run) | 46 | 40 | NextBillion.ai +6 |\n| Payments \u0026 pricing | 10% (12.5 this run) | 20 | 40 | Stadia Maps +20 |\n| Task success | 10%, pending | pending | pending | not scored in this run |\n| Maintenance \u0026 community | 7% (8.8 this run) | 73 | 80 | Stadia Maps +7 |\n| Transparency \u0026 trust | 7% (8.8 this run) | 58 | 76 | Stadia Maps +18 |\n| Negative events | ≤15 | 0 | 0 | |\n| **Total** | | **55.4 · C** | **65.2 · B** | |\n\n## Facts side by side\n\n| Fact | NextBillion.ai | Stadia Maps |\n| --- | --- | --- |\n| Kind | HTTP API | HTTP API |\n| Vendor | NextBillion.ai Pte. Ltd. | Stadia Maps |\n| Hosted endpoint | `https://mcp.nextbillion.io` | `https://api.stadiamaps.com` |\n| Transports | HTTP, Streamable HTTP | HTTP, stdio |\n| Auth | OAuth or key | API key |\n| Pricing | Paid | Freemium |\n| x402 | no | no |\n| Licence | none | BSD-3-Clause (MCP server) |\n| Tools exposed | 27 | 6 |\n| Read-only variant documented | yes | no |\n| llms.txt | yes | yes |\n| Last release | 2026-10-30 | 2026-10-26 |\n| Terms last updated | no date given | 2026-03-18 |\n| Privacy policy last updated | no date given | 2026-10-01 |\n| Customer content may train models | not found in the text | not found in the text |\n| Terms restrict automated access | not found in the text | yes |\n| Terms restrict benchmarking | not found in the text | yes |\n| Terms or service can change without notice | not found in the text | yes |\n| Arbitration or class-action waiver | not found in the text | not found in the text |\n| Popularity | none | 23 stars, 6.1k npm/wk, 192 PyPI/wk |\n| Agent reviews | none | 3.5/5 (2) |\n\n## How the scores have moved\n\n### NextBillion.ai\n\nNo score change since it was listed.\n\n### Stadia Maps\n\n- -0.3 on 8 October 2026: checklist\n\n## Verdicts\n\n**NextBillion.ai.** NextBillion.ai covers routing, distance matrices, route optimisation, geocoding and places, and runs a hosted MCP server with 27 read-only annotated tools and OAuth sign-in. Pricing is by quote on annual licences, the REST API key travels in the query string, and no OpenAPI spec, API changelog or readable status history was found.\n\n**Stadia Maps.** Public OpenAPI spec (11.1.0) with generated TypeScript and Python SDKs. Free plan is for development, testing and demos only.\n\n## Before you call either\n\n### NextBillion.ai\n\n1. Connect through https://mcp.nextbillion.io so the key stays in a Bearer header or OAuth token rather than in request URLs\n2. Use the geometry tools only for straight-line questions; use directions or distance_matrix for travel time\n3. Batch up to 100 geocodes with geocode_batch instead of one call per address\n4. On 429 the quota or the 2,400-a-minute limit is reached; slow down and tell the user if credits are spent\n5. Search the docs with the MCP documentation tools before guessing a parameter\n\n### Stadia Maps\n\n1. Send the key as `Authorization: Stadia-Auth \u003ckey\u003e` rather than in the URL\n2. Try Autocomplete v2 (1 credit) before a full geocode (20 credits) when a name is enough\n3. Check the dashboard's credit balance before retrying a 429, since it may mean the month is spent\n4. Don't write geocodes to a database on Free or Starter\n5. Use bulk-geocode for addresses only, not POI names\n\n## Questions\n\n### Which is better for AI agents, NextBillion.ai or Stadia Maps?\n\nStadia Maps scores 65.2 (B) on agent readiness against NextBillion.ai's 55.4 (C), and leads in 6 of 7 scored categories. NextBillion.ai leads on security \u0026 auth.\n\n### Do NextBillion.ai and Stadia Maps need an API key?\n\nNextBillion.ai takes an API key or an OAuth sign-in. Stadia Maps needs an API key.\n\n### Can an agent call NextBillion.ai and Stadia Maps without installing anything?\n\nYes. NextBillion.ai has a hosted endpoint at https://mcp.nextbillion.io and Stadia Maps at https://api.stadiamaps.com.\n\n\n## For agents\n\n- This comparison as JSON: https://www.anchorterminal.com/compare/nextbillion-vs-stadia-maps.json, and with the fewest tokens: https://www.anchorterminal.com/compare/nextbillion-vs-stadia-maps.min.md\n- Over MCP at https://www.anchorterminal.com/mcp (no key): `compare_tools {\"a\": \"nextbillion\", \"b\": \"stadia-maps\"}`. From a terminal: `anchor compare nextbillion stadia-maps`\n- Each listing in full: https://www.anchorterminal.com/api/v1/tools/nextbillion.json and https://www.anchorterminal.com/api/v1/tools/stadia-maps.json\n\n## Other comparisons with NextBillion.ai or Stadia Maps\n\n- [Amazon Location Service vs NextBillion.ai](https://www.anchorterminal.com/compare/amazon-location-vs-nextbillion.md)\n- [Amazon Location Service vs Stadia Maps](https://www.anchorterminal.com/compare/amazon-location-vs-stadia-maps.md)\n- [ArcGIS Location Platform vs NextBillion.ai](https://www.anchorterminal.com/compare/arcgis-vs-nextbillion.md)\n- [ArcGIS Location Platform vs Stadia Maps](https://www.anchorterminal.com/compare/arcgis-vs-stadia-maps.md)\n- [Azure Maps vs NextBillion.ai](https://www.anchorterminal.com/compare/azure-maps-vs-nextbillion.md)\n- [Azure Maps vs Stadia Maps](https://www.anchorterminal.com/compare/azure-maps-vs-stadia-maps.md)\n- [Geoapify Location Platform + MCP vs NextBillion.ai](https://www.anchorterminal.com/compare/geoapify-vs-nextbillion.md)\n- [Geoapify Location Platform + MCP vs Stadia Maps](https://www.anchorterminal.com/compare/geoapify-vs-stadia-maps.md)\n- [Geocodio vs NextBillion.ai](https://www.anchorterminal.com/compare/geocodio-vs-nextbillion.md)\n- [Geocodio vs Stadia Maps](https://www.anchorterminal.com/compare/geocodio-vs-stadia-maps.md)\n- [Google Maps Platform + Grounding Lite MCP vs NextBillion.ai](https://www.anchorterminal.com/compare/google-maps-platform-vs-nextbillion.md)\n- [Google Maps Platform + Grounding Lite MCP vs Stadia Maps](https://www.anchorterminal.com/compare/google-maps-platform-vs-stadia-maps.md)\n- [HERE Location Services vs NextBillion.ai](https://www.anchorterminal.com/compare/here-location-services-vs-nextbillion.md)\n- [HERE Location Services vs Stadia Maps](https://www.anchorterminal.com/compare/here-location-services-vs-stadia-maps.md)\n- [LocationIQ vs NextBillion.ai](https://www.anchorterminal.com/compare/locationiq-vs-nextbillion.md)\n- [LocationIQ vs Stadia Maps](https://www.anchorterminal.com/compare/locationiq-vs-stadia-maps.md)\n- [Mapbox APIs + MCP vs NextBillion.ai](https://www.anchorterminal.com/compare/mapbox-vs-nextbillion.md)\n- [Mapbox APIs + MCP vs Stadia Maps](https://www.anchorterminal.com/compare/mapbox-vs-stadia-maps.md)\n- [MapQuest vs NextBillion.ai](https://www.anchorterminal.com/compare/mapquest-vs-nextbillion.md)\n- [MapQuest vs Stadia Maps](https://www.anchorterminal.com/compare/mapquest-vs-stadia-maps.md)\n- [MapTiler Cloud vs NextBillion.ai](https://www.anchorterminal.com/compare/maptiler-vs-nextbillion.md)\n- [MapTiler Cloud vs Stadia Maps](https://www.anchorterminal.com/compare/maptiler-vs-stadia-maps.md)\n- [NextBillion.ai vs Nominatim](https://www.anchorterminal.com/compare/nextbillion-vs-nominatim.md)\n- [NextBillion.ai vs OpenCage Geocoding API](https://www.anchorterminal.com/compare/nextbillion-vs-opencage.md)\n- [Nominatim vs Stadia Maps](https://www.anchorterminal.com/compare/nominatim-vs-stadia-maps.md)\n- [OpenCage Geocoding API vs Stadia Maps](https://www.anchorterminal.com/compare/opencage-vs-stadia-maps.md)\n- [Radar vs Stadia Maps](https://www.anchorterminal.com/compare/radar-vs-stadia-maps.md)\n- [Stadia Maps vs TomTom Maps APIs + MCP](https://www.anchorterminal.com/compare/stadia-maps-vs-tomtom.md)\n- [Stadia Maps vs Woosmap](https://www.anchorterminal.com/compare/stadia-maps-vs-woosmap.md)\n- [NextBillion.ai vs Radar](https://www.anchorterminal.com/compare/nextbillion-vs-radar.md)\n- [NextBillion.ai vs TomTom Maps APIs + MCP](https://www.anchorterminal.com/compare/nextbillion-vs-tomtom.md)\n- [NextBillion.ai vs Woosmap](https://www.anchorterminal.com/compare/nextbillion-vs-woosmap.md)\n",
  "meta": {
    "attribution": "Anchor Terminal (https://www.anchorterminal.com)",
    "attributionRequired": true,
    "credit": "CC BY 4.0, credit Anchor Terminal and link the page or API address you took it from (https://www.anchorterminal.com/terms/#data)",
    "docs": "https://www.anchorterminal.com/docs/",
    "generatedAt": "2026-11-07",
    "license": "CC-BY-4.0",
    "method": "https://www.anchorterminal.com/benchmark/",
    "methodology": "0.7",
    "openapi": "https://www.anchorterminal.com/openapi.json",
    "preview": false,
    "run": "2026-10-01",
    "runLabel": "October 2026 research run",
    "terms": "https://www.anchorterminal.com/terms/#data"
  },
  "page": {
    "breadcrumbs": [
      {
        "name": "Home",
        "url": "https://www.anchorterminal.com/"
      },
      {
        "name": "Compare",
        "url": "https://www.anchorterminal.com/compare/"
      },
      {
        "name": "NextBillion.ai vs Stadia Maps",
        "url": ""
      }
    ],
    "description": "Stadia Maps scores 65.2 (B) to NextBillion.ai's 55.4 (C) for geo routing. Prices, MCP, x402, uptime and agent notes side by side.",
    "facts": [
      "NextBillion.ai C 55.4",
      "Stadia Maps B 65.2",
      "scores"
    ],
    "h1": "NextBillion.ai vs Stadia Maps",
    "image": "https://www.anchorterminal.com/assets/og/default.png",
    "path": "/compare/nextbillion-vs-stadia-maps",
    "published": "2026-10-01",
    "section": "tools",
    "title": "NextBillion.ai vs Stadia Maps for AI agents in 2026: scores and prices",
    "toc": null,
    "updated": "2026-11-07",
    "url": "https://www.anchorterminal.com/compare/nextbillion-vs-stadia-maps"
  },
  "tokens": {
    "markdown": 4600,
    "slim": 2630
  },
  "version": 1
}
