{"serverId":"mcp-registry/io.github.uponex/gisgp","tools":[{"name":"analyze_location","fixed":{"name":"analyze_location","description":"Reverse-geocode a WGS84 point to country/region/locality via OSM\n    Nominatim (no key, free — fair-use rate limited, best-effort). Returns\n    JSON: {ok, display_name, country, country_code, region, locality, source}.\n    ","inputSchema":{"type":"object","title":"analyze_locationArguments","required":["lon","lat"],"properties":{"lat":{"type":"number","title":"Lat"},"lon":{"type":"number","title":"Lon"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":127,"tokensAfter":127},{"name":"bundle_create_export_schedule","fixed":{"name":"bundle_create_export_schedule","description":"PAID PER DELIVERY (30 credits each time it fires, NOT at creation — free to\n    create/cancel) — the only MCP tool that exposes GISGP's core recurring-export\n    product to agents: creates a schedule that re-exports a FeatureServer layer on\n    its own and POSTs the file straight to your own webhook_url, no email/web UI\n    account needed beyond the API key. Reuses the same scheduler that runs the paid\n    web app's scheduled exports (fires within ~5 min of the due time).\n\n    format: \"csv\", \"ge","inputSchema":{"type":"object","title":"bundle_create_export_scheduleArguments","required":["service_url","format","webhook_url"],"properties":{"token":{"type":"string","title":"Token","default":""},"where":{"type":"string","title":"Where","default":"1=1"},"format":{"type":"string","title":"Format"},"weekday":{"type":"integer","title":"Weekday","default":0},"monthday":{"type":"integer","title":"Monthday","default":1},"run_hour":{"type":"integer","title":"Run Hour","default":6},"frequency":{"type":"string","title":"Frequency","default":"daily"},"service_url":{"type":"string","title":"Service Url"},"webhook_url":{"type":"string","title":"Webhook Url"}}},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: false, idempotentHint: false (inferred from the name).","verify":true}],"tokensBefore":341,"tokensAfter":341},{"name":"bundle_export_fixed","fixed":{"name":"bundle_export_fixed","description":"PAID (150 credits) — fetch ALL records from a live FeatureServer layer\n    (no 50-record preview cap), auto-repair invalid geometries (GEOS\n    make_valid), and scan for common problems, in one call. Replaces an\n    uncapped query_features call (itself a paid-only capability) plus\n    fix_geometry plus find_layer_issues. Requires Authorization: Bearer\n    <api_key> and sufficient credits balance.\n\n    Returns JSON: {ok, feature_count, fixed_count, truncated, issues,\n    issue_count, geojson} — g","inputSchema":{"type":"object","title":"bundle_export_fixedArguments","required":["service_url"],"properties":{"token":{"type":"string","title":"Token","default":""},"where":{"type":"string","title":"Where","default":"1=1"},"service_url":{"type":"string","title":"Service Url"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":232,"tokensAfter":232},{"name":"bundle_export_multi_format","fixed":{"name":"bundle_export_multi_format","description":"PAID (120 credits) — fetch ALL records from a live FeatureServer layer\n    once, then export the same data as Shapefile + CSV + GeoJSON + KML +\n    Excel in a single ZIP (base64-encoded). Replaces an uncapped fetch plus\n    4 separate format-conversion calls. Requires Authorization: Bearer\n    <api_key> and sufficient credits balance.\n\n    Returns JSON: {ok, feature_count, truncated, zip_base64, formats}.","inputSchema":{"type":"object","title":"bundle_export_multi_formatArguments","required":["service_url"],"properties":{"token":{"type":"string","title":"Token","default":""},"where":{"type":"string","title":"Where","default":"1=1"},"service_url":{"type":"string","title":"Service Url"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":210,"tokensAfter":210},{"name":"bundle_migrate_convert","fixed":{"name":"bundle_migrate_convert","description":"PAID (40 credits) — one-call file migration: convert a raw file to\n    GeoJSON, then optionally reproject and simplify, then round coordinates.\n    Replaces 2-4 separate free tool calls (convert + reproject + simplify +\n    round) an agent would otherwise chain by hand — see estimate_cost's\n    \"replaces\" field. Requires Authorization: Bearer <api_key> and sufficient\n    credits balance.\n\n    input_format: \"shapefile\" (data = base64-encoded .zip), \"kml\", \"gpx\", or\n    \"csv\" (data = raw text for ","inputSchema":{"type":"object","title":"bundle_migrate_convertArguments","required":["input_format","data"],"properties":{"data":{"type":"string","title":"Data"},"to_epsg":{"type":"integer","title":"To Epsg","default":0},"input_format":{"type":"string","title":"Input Format"},"round_decimals":{"type":"integer","title":"Round Decimals","default":6},"simplify_tolerance":{"type":"number","title":"Simplify Tolerance","default":0}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":278,"tokensAfter":278},{"name":"bundle_migration_readiness","fixed":{"name":"bundle_migration_readiness","description":"PAID (100 credits) — migration-readiness report comparing two\n    FeatureServer layers: schema diff, coded-value domains, and field types\n    for both. Replaces compare_schemas + extract_domains×2 +\n    check_field_types×2. Requires Authorization: Bearer <api_key> and\n    sufficient credits balance.\n\n    Returns JSON: {ok, schema_diff, domains_a, domains_b, fields_a, fields_b,\n    ready, blockers} — ready is False and blockers lists the reasons if the\n    schema diff finds added/removed/changed ","inputSchema":{"type":"object","title":"bundle_migration_readinessArguments","required":["service_url_a","service_url_b"],"properties":{"token_a":{"type":"string","title":"Token A","default":""},"token_b":{"type":"string","title":"Token B","default":""},"service_url_a":{"type":"string","title":"Service Url A"},"service_url_b":{"type":"string","title":"Service Url B"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":260,"tokensAfter":260},{"name":"calculate_route","fixed":{"name":"calculate_route","description":"Real driving distance + duration between two points. Default: OSRM\n    (public demo instance, no key — fair-use limited, not a production SLA).\n    Optional agol_token: route through Esri's own World Route Service\n    instead — uses YOUR OWN AGOL credentials/quota, not GISGP's (no extra\n    charge either way, no GISGP account needed for this option).\n    Returns \"no_route\" honestly when no driving path exists (e.g. across\n    open water). Returns JSON: {ok, routable, distance_km, duration_min, s","inputSchema":{"type":"object","title":"calculate_routeArguments","required":["origin_lon","origin_lat","dest_lon","dest_lat"],"properties":{"dest_lat":{"type":"number","title":"Dest Lat"},"dest_lon":{"type":"number","title":"Dest Lon"},"agol_token":{"type":"string","title":"Agol Token","default":""},"origin_lat":{"type":"number","title":"Origin Lat"},"origin_lon":{"type":"number","title":"Origin Lon"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":267,"tokensAfter":267},{"name":"cancel_export_schedule","fixed":{"name":"cancel_export_schedule","description":"FREE — cancel a schedule created by bundle_create_export_schedule. Only\n    the API key that created it can cancel it. Returns JSON: {ok} or\n    {ok: false, error}.","inputSchema":{"type":"object","title":"cancel_export_scheduleArguments","required":["schedule_id"],"properties":{"token":{"type":"string","title":"Token","default":""},"schedule_id":{"type":"string","title":"Schedule Id"}}},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: true, idempotentHint: true (inferred from the name).","verify":true}],"tokensBefore":123,"tokensAfter":123},{"name":"check_field_types","fixed":{"name":"check_field_types","description":"Inspect the field schema of an ArcGIS FeatureServer layer.\n\n    Returns JSON: {layer_name, geometry_type, fields:[{name, alias, type,\n    length, nullable, has_domain}]} — useful before importing/mapping data.\n    ","inputSchema":{"type":"object","title":"check_field_typesArguments","required":["service_url"],"properties":{"token":{"type":"string","title":"Token","default":""},"service_url":{"type":"string","title":"Service Url"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":135,"tokensAfter":135},{"name":"check_service_health","fixed":{"name":"check_service_health","description":"Check whether an ArcGIS FeatureServer layer is reachable and responsive.\n\n    Returns JSON: {ok, ms (latency), name, geometry_type, field_count,\n    record_count, capabilities, max_record_count}.\n    ","inputSchema":{"type":"object","title":"check_service_healthArguments","required":["service_url"],"properties":{"token":{"type":"string","title":"Token","default":""},"service_url":{"type":"string","title":"Service Url"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":132,"tokensAfter":132},{"name":"check_wallet_balance","fixed":{"name":"check_wallet_balance","description":"FREE — check your own MCP credits wallet balance (the same account\n    paid tools like assess_property_hazard charge against). Requires\n    Authorization: Bearer <api_key> — an agent can call this on its own,\n    no browser/dashboard needed. Returns JSON: {ok, balance, eur_equivalent}\n    or {ok: false, error} if no API key was provided.","inputSchema":{"type":"object","title":"check_wallet_balanceArguments","properties":{}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":134,"tokensAfter":134},{"name":"compare_schemas","fixed":{"name":"compare_schemas","description":"Compare the field schemas of two ArcGIS FeatureServer layers.\n\n    Returns JSON diff: {added, removed, changed:[{field, diffs}], same,\n    geometry_match, identical} — useful for QA before an import or migration.\n    ","inputSchema":{"type":"object","title":"compare_schemasArguments","required":["service_url_a","service_url_b"],"properties":{"token_a":{"type":"string","title":"Token A","default":""},"token_b":{"type":"string","title":"Token B","default":""},"service_url_a":{"type":"string","title":"Service Url A"},"service_url_b":{"type":"string","title":"Service Url B"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":174,"tokensAfter":174},{"name":"convert_coordinates","fixed":{"name":"convert_coordinates","description":"Convert coordinate pairs between EPSG coordinate systems (max 1000 points).\n\n    points: [[x, y], ...] in from_epsg axis order (lon/lat for EPSG:4326).\n    Returns JSON: {\"points\": [[x, y], ...], \"from_epsg\": ..., \"to_epsg\": ...}.\n    ","inputSchema":{"type":"object","title":"convert_coordinatesArguments","required":["points","from_epsg","to_epsg"],"properties":{"points":{"type":"array","items":{"type":"array","items":{"type":"number"}},"title":"Points"},"to_epsg":{"type":"integer","title":"To Epsg"},"from_epsg":{"type":"integer","title":"From Epsg"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":171,"tokensAfter":171},{"name":"convert_file","fixed":{"name":"convert_file","description":"GISGP Lite ($3 a month, or $1 once for 24 hours) — pass the api_key of that\n    account (or Authorization: Bearer). convert one GIS\n    file between formats with the full site converter: input shapefile (.zip), KML/KMZ, GPX, CSV,\n    GeoJSON, GPKG, FlatGeobuf, MapInfo TAB (.zip, source=\"mapinfo-tab\"), FileGDB (.zip,\n    source=\"filegdb\"), DXF or DWG; `to` geojson | shapefile | kml | kmz | gpx | csv | xlsx | gpkg |\n    flatgeobuf | mapinfo-tab | wkt | dxf. `source_epsg` for projected CSV / a shap","inputSchema":{"type":"object","title":"convert_fileArguments","required":["filename","data_base64","to"],"properties":{"to":{"type":"string","title":"To"},"source":{"type":"string","title":"Source","default":""},"api_key":{"type":"string","title":"Api Key","default":""},"filename":{"type":"string","title":"Filename"},"data_base64":{"type":"string","title":"Data Base64"},"source_epsg":{"type":"string","title":"Source Epsg","default":""},"target_epsg":{"type":"string","title":"Target Epsg","default":""}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":295,"tokensAfter":295},{"name":"count_features","fixed":{"name":"count_features","description":"Count features in an ArcGIS FeatureServer layer, optionally filtered by a WHERE clause.\n\n    service_url: full layer URL ending in /FeatureServer/<n>. token: only for private layers.\n    Returns JSON: {\"ok\": true, \"count\": ..., \"name\": ..., \"geometry\": ...}.\n    ","inputSchema":{"type":"object","title":"count_featuresArguments","required":["service_url"],"properties":{"token":{"type":"string","title":"Token","default":""},"where":{"type":"string","title":"Where","default":"1=1"},"service_url":{"type":"string","title":"Service Url"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":165,"tokensAfter":165},{"name":"detect_coordinate_order","fixed":{"name":"detect_coordinate_order","description":"Detect whether [x, y] pairs are [lon, lat] or [lat, lon] — resolves\n    a genuinely common real-world confusion (one of the most-viewed GIS\n    StackExchange questions ever, 550k+ views). Certain when any value\n    exceeds ±90 (only longitude can); honestly reports 'inconclusive'\n    otherwise, never a fabricated guess. Pure computation, no external API.\n    Returns JSON: {ok, order, confidence, note}.\n    ","inputSchema":{"type":"object","title":"detect_coordinate_orderArguments","required":["points"],"properties":{"points":{"type":"array","items":{"type":"array","items":{"type":"number"}},"title":"Points"}}},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: false, idempotentHint: false (inferred from the name).","verify":true}],"tokensBefore":187,"tokensAfter":187},{"name":"estimate_cost","fixed":{"name":"estimate_cost","description":"FREE — quote a paid tool's cost WITHOUT executing it or charging the\n    wallet (call this before assess_property_hazard etc.).\n    `units` = candidate/item count for per-unit-priced tools (currently only\n    rank_hazard_safe_sites — pass the number of candidates you intend to\n    submit); ignored (treated as 1) for every flat-priced tool. Returns JSON:\n    {ok, tool_name, units, credits, eur_estimate} for credits-wallet tools;\n    for assess_property_hazard_x402 (paid on-chain via x402, not the","inputSchema":{"type":"object","title":"estimate_costArguments","required":["tool_name"],"properties":{"units":{"type":"integer","title":"Units","default":1},"tool_name":{"type":"string","title":"Tool Name"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":211,"tokensAfter":211},{"name":"export_geojson_to_excel","fixed":{"name":"export_geojson_to_excel","description":"PAID (80 credits) — convert a GeoJSON FeatureCollection to an Excel\n    workbook (.xlsx, base64-encoded). Point geometries get LATITUDE/LONGITUDE\n    columns; other geometry types get a GEOMETRY_WKT column. Separate from\n    the web app's own Excel export (AGOL-service-tied, quota-gated there).\n    Requires Authorization: Bearer <api_key> and sufficient credits balance.\n    Returns JSON: {ok, xlsx_base64, feature_count}.","inputSchema":{"type":"object","title":"export_geojson_to_excelArguments","required":["geojson"],"properties":{"geojson":{"type":"string","title":"Geojson"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":178,"tokensAfter":178},{"name":"export_geojson_to_pdf","fixed":{"name":"export_geojson_to_pdf","description":"PAID (150 credits) — render an ad-hoc GeoJSON FeatureCollection to a\n    one-page PDF report (static map + property table, base64-encoded PDF).\n    Separate from the web app's own PDF Builder (AGOL-service-tied, quota-\n    gated there) — this is for GeoJSON an agent already has in hand. Requires\n    Authorization: Bearer <api_key> and sufficient credits balance. Returns\n    JSON: {ok, pdf_base64, feature_count, truncated, size_bytes}.","inputSchema":{"type":"object","title":"export_geojson_to_pdfArguments","required":["geojson"],"properties":{"title":{"type":"string","title":"Title","default":"GISGP GeoJSON Export"},"accent":{"type":"string","title":"Accent","default":"#2563eb"},"geojson":{"type":"string","title":"Geojson"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":219,"tokensAfter":219},{"name":"find_layer_issues","fixed":{"name":"find_layer_issues","description":"Scan an ArcGIS FeatureServer layer for common problems: missing ObjectID,\n    disabled query, stale data, all-null fields, features without geometry.\n\n    Sample-based (first 200 records). Returns JSON: {layer_name,\n    issues:[{severity, code, message}], issue_count, sample_size, note}.\n    ","inputSchema":{"type":"object","title":"find_layer_issuesArguments","required":["service_url"],"properties":{"token":{"type":"string","title":"Token","default":""},"service_url":{"type":"string","title":"Service Url"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":157,"tokensAfter":157},{"name":"geocode_address","fixed":{"name":"geocode_address","description":"Forward-geocode a free-text address to lon/lat. Default: OSM Nominatim\n    (no key, free, fair-use rate limited) — the complement to\n    analyze_location's reverse geocode. Optional agol_token: route through\n    Esri's own World Geocoding Service instead for more authoritative\n    matches — uses YOUR OWN AGOL credentials/quota, not GISGP's (no extra\n    charge either way, no GISGP account needed for this option). Returns\n    JSON: {ok, lon, lat, display_name, type, importance, source}.\n    ","inputSchema":{"type":"object","title":"geocode_addressArguments","required":["address"],"properties":{"address":{"type":"string","title":"Address"},"agol_token":{"type":"string","title":"Agol Token","default":""}}},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: false, idempotentHint: false (inferred from the name).","verify":true}],"tokensBefore":212,"tokensAfter":212},{"name":"geometry_health_report","fixed":{"name":"geometry_health_report","description":"Complete one-call GeoJSON health check: validate + auto-repair invalid\n    geometry + stats (area/length/vertices) + bbox envelope, merged — replaces\n    4 separate calls (validate_geojson + fix_geometry + geometry_stats +\n    envelope_geojson).\n\n    Returns JSON: {ok, valid, errors, warnings, fixed_count, stats, envelope,\n    geojson} where geojson is the (possibly auto-fixed) input.\n    ","inputSchema":{"type":"object","title":"geometry_health_reportArguments","required":["geojson"],"properties":{"geojson":{"type":"string","title":"Geojson"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":169,"tokensAfter":169},{"name":"geometry_stats","fixed":{"name":"geometry_stats","description":"Compute area (m²/km²), length (m/km), vertex count, centroid and bbox of GeoJSON.\n\n    Metric measurements use an equal-area projection so area/length are real metres.\n    ","inputSchema":{"type":"object","title":"geometry_statsArguments","required":["geojson"],"properties":{"geojson":{"type":"string","title":"Geojson"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":102,"tokensAfter":102},{"name":"get_climate_history","fixed":{"name":"get_climate_history","description":"Daily historical weather for a point/date range via Open-Meteo's\n    ERA5-based archive (no key, free, data back to 1940). Dates are\n    YYYY-MM-DD. Returns JSON: {ok, daily: {time, <variables>...}, source}.\n    ","inputSchema":{"type":"object","title":"get_climate_historyArguments","required":["lon","lat","start_date","end_date"],"properties":{"lat":{"type":"number","title":"Lat"},"lon":{"type":"number","title":"Lon"},"end_date":{"type":"string","title":"End Date"},"variables":{"type":"string","title":"Variables","default":"temperature_2m_mean,precipitation_sum"},"start_date":{"type":"string","title":"Start Date"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":187,"tokensAfter":187},{"name":"get_elevation","fixed":{"name":"get_elevation","description":"GISGP Lite ($3 a month, or $1 once for 24 hours) — pass the api_key of that\n    account (or Authorization: Bearer). height above mean\n    sea level of one point from Copernicus GLO-30 (30 m), read from the public elevation model\n    (GLO-90 fallback). Returns JSON {ok, elevation_m, source, resolution_m, credit}; elevation_m is\n    null at sea. For a free, coarser answer use get_terrain_profile.","inputSchema":{"type":"object","title":"get_elevationArguments","required":["lat","lon"],"properties":{"lat":{"type":"number","title":"Lat"},"lon":{"type":"number","title":"Lon"},"api_key":{"type":"string","title":"Api Key","default":""}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":190,"tokensAfter":190},{"name":"get_elevation_profile","fixed":{"name":"get_elevation_profile","description":"PAID (50 credits) — elevation PROFILE along a line, not a single point:\n    pass points=[[lon,lat],…] (up to 100) or start=[lon,lat] + end=[lon,lat]\n    with samples (2-100, evenly spaced). Returns every point's elevation and\n    distance plus min/max, total gain/loss, net change, mean and max\n    segment slope. For \"how steep is this route\", \"line-of-sight terrain\n    between two towers\", \"elevation change along this pipeline/trail\".\n    Copernicus DEM GLO-90 via Open-Meteo (~90 m). The free\n  ","inputSchema":{"type":"object","title":"get_elevation_profileArguments","properties":{"end":{"anyOf":[{"type":"array","items":{}},{"type":"null"}],"title":"End","default":null},"start":{"anyOf":[{"type":"array","items":{}},{"type":"null"}],"title":"Start","default":null},"points":{"anyOf":[{"type":"array","items":{}},{"type":"null"}],"title":"Points","default":null},"samples":{"type":"integer","title":"Samples","default":50}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":276,"tokensAfter":276},{"name":"get_river_flow_status","fixed":{"name":"get_river_flow_status","description":"Nearest USGS real-time stream/river gauge to a point (US rivers and\n    streams only): live streamflow (ft3/s) and gauge height (ft), reported\n    honestly as provisional USGS data — no derived flood-risk score, since\n    USGS does not publish per-site flood-stage thresholds through this API.\n    First real-time (not static/historical) primitive in the catalog. No\n    key needed. Returns JSON: {ok, found, site_name, site_no,\n    distance_miles, streamflow_cfs, gauge_height_ft, observation_time,\n","inputSchema":{"type":"object","title":"get_river_flow_statusArguments","required":["lon","lat"],"properties":{"lat":{"type":"number","title":"Lat"},"lon":{"type":"number","title":"Lon"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":207,"tokensAfter":207},{"name":"get_terrain_profile","fixed":{"name":"get_terrain_profile","description":"Get the ground elevation (metres above sea level) at a coordinate —\n    e.g. \"what's the elevation here\", \"is this point in a flood-risk\n    lowland\", \"elevation at this address\". Via Open-Meteo (Copernicus DEM\n    GLO-90, no key, free, ~90m resolution).\n\n    Returns JSON: {ok, lon, lat, elevation_m, source}.\n    ","inputSchema":{"type":"object","title":"get_terrain_profileArguments","required":["lon","lat"],"properties":{"lat":{"type":"number","title":"Lat"},"lon":{"type":"number","title":"Lon"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":156,"tokensAfter":156},{"name":"list_dxf_layers","fixed":{"name":"list_dxf_layers","description":"List the distinct DXF layer names used in a drawing — e.g. \"what\n    layers does this DXF have\", \"list layers before I extract one\". Real\n    CAD exports organize entities into named layers (BOUNDARY, UTILITIES,\n    TEXT, ...); use the result with dxf_to_geojson's `layer` param to pull\n    out just one. Returns a JSON array of layer name strings.","inputSchema":{"type":"object","title":"list_dxf_layersArguments","required":["dxf"],"properties":{"dxf":{"type":"string","title":"Dxf"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":150,"tokensAfter":150},{"name":"plss_find","fixed":{"name":"plss_find","description":"GISGP Lite ($3 a month, or $1 once for 24 hours) — pass the api_key of that\n    account (or Authorization: Bearer). a legal description\n    → where it is: `q` like \"T2N R3E Sec 14\", \"NW¼ SE¼ Sec 12 T3N R4W\", \"Township 1 North, Range 2\n    East\" or BLM-coded \"1460N 0920W SEC 8\"; `state` the two-letter code (tried in every PLSS state\n    when empty). Returns JSON {ok, results: [{label, state, lat, lon, bbox, plssid, geometry…}],\n    read_as, notes}.","inputSchema":{"type":"object","title":"plss_findArguments","required":["q"],"properties":{"q":{"type":"string","title":"Q"},"state":{"type":"string","title":"State","default":""},"api_key":{"type":"string","title":"Api Key","default":""}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":207,"tokensAfter":207},{"name":"plss_lookup","fixed":{"name":"plss_lookup","description":"GISGP Lite ($3 a month, or $1 once for 24 hours) — pass the api_key of that\n    account (or Authorization: Bearer). US Public Land\n    Survey System township, range, section and meridian at a point (BLM CadNSDI). Returns JSON\n    {ok, found, township, range, section, meridian, plssid, …} or {ok, found: false, note}.","inputSchema":{"type":"object","title":"plss_lookupArguments","required":["lat","lon"],"properties":{"lat":{"type":"number","title":"Lat"},"lon":{"type":"number","title":"Lon"},"api_key":{"type":"string","title":"Api Key","default":""}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":166,"tokensAfter":166},{"name":"query_features","fixed":{"name":"query_features","description":"Fetch actual feature records (attributes + geometry) from a FeatureServer layer.\n\n    Free preview capped at 50 records (WHERE filter + chosen fields). Returns JSON:\n    {returned, total, truncated, geojson, note}. Full unlimited export is a paid operation.\n    ","inputSchema":{"type":"object","title":"query_featuresArguments","required":["service_url"],"properties":{"limit":{"type":"integer","title":"Limit","default":50},"token":{"type":"string","title":"Token","default":""},"where":{"type":"string","title":"Where","default":"1=1"},"out_fields":{"type":"string","title":"Out Fields","default":"*"},"service_url":{"type":"string","title":"Service Url"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":196,"tokensAfter":196},{"name":"query_statistics","fixed":{"name":"query_statistics","description":"Server-side aggregate stats on a numeric field of a FeatureServer layer.\n\n    No records fetched — AGOL computes sum/avg/min/max/count (also stddev/var).\n    Optional WHERE filter and group_by field. Returns JSON: {field, results:[...]}.\n    Cheap way to answer \"what's the average/total of field X\" without an export.\n    ","inputSchema":{"type":"object","title":"query_statisticsArguments","required":["service_url","field"],"properties":{"field":{"type":"string","title":"Field"},"stats":{"type":"string","title":"Stats","default":"sum,avg,min,max,count"},"token":{"type":"string","title":"Token","default":""},"where":{"type":"string","title":"Where","default":"1=1"},"group_by":{"type":"string","title":"Group By","default":""},"service_url":{"type":"string","title":"Service Url"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":233,"tokensAfter":233},{"name":"validate_geojson","fixed":{"name":"validate_geojson","description":"Check whether a GeoJSON file/string is valid — catches broken geometry,\n    malformed structure, self-intersections, and out-of-range coordinates\n    before you try to use the file elsewhere (e.g. \"is this GeoJSON valid\",\n    \"why won't my GeoJSON load\", \"lint my GeoJSON\", \"check topology errors\").\n    Validates RFC 7946 structure, topology, and WGS84 coordinate ranges.\n\n    Returns a JSON report: {valid, errors, warnings, stats}.\n    ","inputSchema":{"type":"object","title":"validate_geojsonArguments","required":["geojson"],"properties":{"geojson":{"type":"string","title":"Geojson"}}},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":181,"tokensAfter":181}],"toolsChanged":34,"tokensSaved":0,"todo":[{"tool":"analyze_location","params":["lat","lon"]},{"tool":"assess_airspace_obstruction_proximity","params":["lat","lon","proposed_height_agl_ft"]},{"tool":"assess_datacenter_site","params":["lat","lon"]},{"tool":"assess_energy_community_credit","params":["lat","lon"]},{"tool":"assess_ev_charging_site","params":["lat","lon"]},{"tool":"assess_grid_exposure","params":["lat","lon"]},{"tool":"assess_pipeline_proximity","params":["lat","lon"]},{"tool":"assess_portfolio_climate_disclosure","params":["properties"]},{"tool":"assess_property_hazard","params":["lat","lon"]},{"tool":"assess_property_hazard_x402","params":["lat","lon"]},{"tool":"assess_protected_area_proximity","params":["lat","lon"]},{"tool":"assess_reforestation_site","params":["lat","lon"]},{"tool":"assess_renewable_site","params":["lat","lon"]},{"tool":"assess_site_due_diligence","params":["lat","lon"]},{"tool":"assess_supply_chain_redundancy","params":["site_a","site_b"]},{"tool":"assess_telecom_site","params":["lat","lon"]},{"tool":"assess_wildfire_risk","params":["lat","lon"]},{"tool":"audit_service","params":["token","service_url"]},{"tool":"buffer_geojson","params":["geojson","distance_m"]},{"tool":"bundle_create_export_schedule","params":["token","where","format","weekday","monthday","run_hour","frequency","service_url","webhook_url"]},{"tool":"bundle_export_fixed","params":["token","where","service_url"]},{"tool":"bundle_export_multi_format","params":["token","where","service_url"]},{"tool":"bundle_geocode_enrich","params":["addresses"]},{"tool":"bundle_migrate_convert","params":["data","to_epsg","input_format","round_decimals","simplify_tolerance"]},{"tool":"bundle_migration_readiness","params":["token_a","token_b","service_url_a","service_url_b"]},{"tool":"calculate_route","params":["dest_lat","dest_lon","agol_token","origin_lat","origin_lon"]},{"tool":"cancel_export_schedule","params":["token","schedule_id"]},{"tool":"centroids_geojson","params":["geojson"]},{"tool":"check_field_types","params":["token","service_url"]},{"tool":"check_service_health","params":["token","service_url"]},{"tool":"classify_land_cover","params":["lat","lon"]},{"tool":"compare_schemas","params":["token_a","token_b","service_url_a","service_url_b"]},{"tool":"convert_coordinates","params":["points","to_epsg","from_epsg"]},{"tool":"convert_file","params":["to","source","api_key","filename","data_base64","source_epsg","target_epsg"]},{"tool":"convex_hull_geojson","params":["geojson"]},{"tool":"count_features","params":["token","where","service_url"]},{"tool":"csv_to_geojson","params":["csv"]},{"tool":"csv_to_gpx","params":["csv"]},{"tool":"detect_coordinate_order","params":["points"]},{"tool":"discover_open_geodata","params":["limit","query"]},{"tool":"discover_open_geodata_pro","params":["limit","query","enrich"]},{"tool":"dissolve_geojson","params":["by","geojson"]},{"tool":"dxf_to_geojson","params":["dxf","layer"]},{"tool":"dxf_to_pdf_report","params":["dxf","title"]},{"tool":"embed_map_snippet","params":["name","width","height","geojson"]},{"tool":"envelope_geojson","params":["geojson"]},{"tool":"epsg_suggest","params":["lat","lon"]},{"tool":"estimate_cost","params":["units","tool_name"]},{"tool":"export_geojson_to_excel","params":["geojson"]},{"tool":"export_geojson_to_pdf","params":["title","accent","geojson"]},{"tool":"extract_domains","params":["token","service_url"]},{"tool":"find_layer_issues","params":["token","service_url"]},{"tool":"fix_geometry","params":["geojson"]},{"tool":"flatgeobuf_to_geojson","params":["flatgeobuf_base64"]},{"tool":"format_coordinate","params":["lat","lon","mgrs_precision"]},{"tool":"full_service_audit","params":["token","service_url"]},{"tool":"generate_contours","params":["crs","bbox","units","format","source","api_key","polygon","interval","major_every"]},{"tool":"generate_static_map_image","params":["width","accent","height","basemap","geojson","agol_token"]},{"tool":"geocode_address","params":["address","agol_token"]},{"tool":"geojson_diff","params":["id_field","geojson_a","geojson_b"]},{"tool":"geojson_to_csv","params":["geojson"]},{"tool":"geojson_to_dxf","params":["geojson"]},{"tool":"geojson_to_flatgeobuf","params":["geojson"]},{"tool":"geojson_to_gpx","params":["geojson"]},{"tool":"geojson_to_kml","params":["geojson"]},{"tool":"geojson_to_mapinfo_tab","params":["geojson"]},{"tool":"geojson_to_shapefile","params":["geojson"]},{"tool":"geojson_to_wkt","params":["geojson"]},{"tool":"geometry_health_report","params":["geojson"]},{"tool":"geometry_stats","params":["geojson"]},{"tool":"georeference_dxf","params":["dxf","control_points"]},{"tool":"get_climate_history","params":["lat","lon","end_date","variables","start_date"]},{"tool":"get_elevation","params":["lat","lon","api_key"]},{"tool":"get_elevation_profile","params":["end","start","points","samples"]},{"tool":"get_river_flow_status","params":["lat","lon"]},{"tool":"get_terrain_profile","params":["lat","lon"]},{"tool":"gpx_to_csv","params":["gpx"]},{"tool":"gpx_to_geojson","params":["gpx"]},{"tool":"gpx_to_kml","params":["gpx"]},{"tool":"gpx_to_shapefile","params":["gpx"]},{"tool":"grade_service","params":["token","service_url"]},{"tool":"guess_crs","params":["lat","lon","lines","api_key","country"]},{"tool":"guess_crs_from_coordinates","params":["points"]},{"tool":"kml_to_geojson","params":["kml"]},{"tool":"kml_to_gpx","params":["kml"]},{"tool":"kml_to_shapefile","params":["kml"]},{"tool":"list_dxf_layers","params":["dxf"]},{"tool":"mapinfo_tab_to_geojson","params":["mapinfo_tab_zip_base64"]},{"tool":"minimum_rotated_rectangle","params":["geojson"]},{"tool":"nearest_features_geojson","params":["geojson_a","geojson_b"]},{"tool":"offset_coordinates","params":["lat","lon","distance_m","bearing_deg"]},{"tool":"overlay_geojson","params":["op","geojson_a","geojson_b"]},{"tool":"parse_coordinate","params":["text"]},{"tool":"plss_find","params":["q","state","api_key"]},{"tool":"plss_lookup","params":["lat","lon","api_key"]},{"tool":"query_features","params":["limit","token","where","out_fields","service_url"]},{"tool":"query_statistics","params":["field","stats","token","where","group_by","service_url"]},{"tool":"rank_hazard_safe_sites","params":["top_n","candidates"]},{"tool":"rank_renewable_sites","params":["top_n","candidates"]},{"tool":"reduce_precision","params":["geojson","decimals"]},{"tool":"reproject_geojson","params":["geojson","to_epsg","from_epsg"]},{"tool":"rest_explore","params":["token","service_url"]},{"tool":"shapefile_to_geojson","params":["shapefile_zip_base64"]},{"tool":"shapefile_to_gpx","params":["shapefile_zip_base64"]},{"tool":"share_map","params":["name","geojson"]},{"tool":"simplify_geometry","params":["geojson","tolerance"]},{"tool":"spatial_join_geojson","params":["geojson_a","geojson_b","predicate"]},{"tool":"tile_math","params":["lat","lon","zoom"]},{"tool":"validate_geojson","params":["geojson"]},{"tool":"voronoi_geojson","params":["geojson"]},{"tool":"wkt_to_geojson","params":["wkt"]}],"note":"Deterministic fixes. Changes marked verify need a human look before shipping (renames, inferred annotations, inferred types, removed text). Parameter descriptions in `todo` need to be written by someone who knows the API."}