Skip to main content
Glama

GeoSource MCP 🌍

🗺️ 交互与检索看板: 访问 viewer.html 即可在纯黑白灰工程风界面中查询 11,147 条空间服务,或切换到「全球态势地图」进行多边形面交互与中国 34 省级行政区无缝下钻。


🌐 English

Overview

GeoSource MCP is an open-source Model Context Protocol (MCP) server providing structured access to an indexed catalog of 11,147 global GIS spatial services and 56,969 sub-layers.

When developers build maps, spatial analysis pipelines, or GIS crawlers using AI assistants (Claude Desktop, Cursor, Windsurf, etc.), large language models frequently struggle to locate real-world endpoints or generate non-functional URLs. GeoSource MCP connects AI environments directly to an indexed local SQLite database (gis_services.db), enabling low-latency, multi-criteria discovery of verified spatial services across OGC WMS, WFS, WMTS, XYZ Tiles, ArcGIS REST, STAC, and Open Data APIs.

Key Engineering Features

  • Structured Discovery: Helps AI models locate existing, functional endpoints rather than guessing URLs.

  • Interactive Global Map & Explorer: Browse services visually via viewer.html with dark brutalist monochrome aesthetics, boundary polygon highlighting, One-China compliant provincial drilldown, and one-click URL copying.

  • Low-Overhead Retrieval: Fetches only matching records (typically 200 ~ 500 tokens per search) on demand, avoiding the cost and latency of loading megabytes of raw files into prompts.

  • Transparent Verification: Tracks explicit availability statuses, each backed by a recorded method in verify_method:

    • 6,137 Verified Active: Confirmed accessible. 5,122 of them carry protocol-level proof (a WMS that actually returns WMS_Capabilities, a STAC API that returns stac_version, an ArcGIS REST service document).

    • 4,956 Pending / Unverified: Cataloged entries whose portal is reachable but no anonymous protocol-level endpoint was found (twelve-path battery: GeoServer/CKAN/ArcGIS Hub/REST/GeoNode/Socrata + THREDDS/CSW/ERDDAP/data.json variants); each entry records the probe result in notes.

    • 54 Deprecated / Inactive: Documented legacy services retained for reference.

    • A failed probe never downgrades an entry on its own: a single failure cannot distinguish a dead service from a blocked cross-border route or UA filtering, so the reason is recorded instead.

  • Two-Way Maintenance: Supports Excel synchronization and provides tools for AI agents to report status updates and new endpoints.

Catalog Contents & Protocols

Category

Protocols Supported

Notable Data Sources

Open Data Portals (9,832)

CKAN, DKAN, ArcGIS Hub, REST API, HTTP download

Data.gov, Eurostat, Thai DSD, Indonesian Satu Data, county/municipal ArcGIS hubs

OGC Standard Services (687)

WMS 1.1.1/1.3.0, WFS 1.0/2.0, WMTS 1.0.0, OGC API Features/Records

PDOK (Netherlands), geo.admin.ch (Switzerland), municipal GeoServers worldwide

ArcGIS Platforms (295)

ArcGIS Server REST, FeatureServer, MapServer, ImageServer

Esri Living Atlas, federal & municipal ArcGIS REST endpoints

Basemap Tiles (86)

XYZ Slippy Maps, TMS, WMTS, PMTiles, Entwine

OpenStreetMap, Carto, Stadia, OpenTopoMap, MapTiler

Remote Sensing / STAC (72)

STAC API 1.0, OGC API Records, COG

Earth Search, Microsoft Planetary Computer, USGS Landsat

3D Geospatial (20)

3D Tiles, CityGML, I3S, Cesium terrain

Cesium ion open assets, municipal 3D building models

Transit & Routing (14)

GTFS, GTFS-RT, OSRM, Valhalla

OpenRouteService, Transitland, city transit agencies

Protocol strings are grouped by family and overlap slightly (e.g. an ArcGIS Hub portal is also an open-data portal). A per-category breakdown is available from list_categories_and_stats; the catalog spans 319 countries/regions across 102 categories.

Available MCP Tools

Tool

Parameters

Purpose

search_gis_services

keyword, country, protocol, category, is_free, need_no_key, status, limit

Searches services based on multiple criteria with case-insensitive matching.

get_service_detail

service_id

Retrieves full metadata (50+ fields) and child layers for a specific service ID (case-insensitive).

list_categories_and_stats

(None)

Returns summary statistics of categories, protocols, countries, and verification statuses.

query_gis_sql

query

Executes safe, read-only SELECT queries against the SQLite database (capped at 100 rows).

probe_service_api

service_id, url, timeout

Live-probes an entry and auto-detects its open-data platform (CKAN / DKAN / ArcGIS Hub / Socrata), returning the working JSON API entry. Use before recommending an unverified portal.

update_service_status

service_id, new_url, status, notes

Updates service availability, URLs, or notes with validated status enums.

resolve_admin_region

region

Resolves a Chinese name/adcode through DataV; returns candidates for ambiguous names.

fetch_admin_boundary

region, output_dir, include_children, target_crs

Downloads DataV GeoJSON and a provenance manifest, returning paths instead of inline geometry.

inspect_data_url

url

Inspects a public URL by content/protocol; lists layers or candidate links and explicitly hands webpages to client browser tools.

fetch_data

url, output_dir, where, bbox, fields, max_features

Unified acquisition of GeoJSON, common data files and ArcGIS FeatureServer layers, with provenance and explicit subset flags.

Administrative-boundary acquisition and the portable agent skill are documented in docs/data-acquisition.md. Catalog discovery alone does not download a dataset.

Verification Scripts

Two scripts back the "verified" claims with real evidence rather than a bare HTTP 200:

# Platform detection for open-data portals -> writes the real API URL into service_url
python scripts/probe_portal_api.py --dry-run            # probe only
python scripts/probe_portal_api.py --apply --workers 20 # probe and write back

# Protocol-aware service verification -> writes status / verify_method / last_verified
python scripts/verify_services.py --limit 50             # no --apply means probe only
python scripts/verify_services.py --apply --workers 20
python scripts/verify_services.py --apply --only-status 已验证   # re-audit existing claims

verify_services.py checks that a service answers in its declared protocol — a WMS endpoint must return WMS_Capabilities, a STAC endpoint must return stac_version, an ArcGIS REST endpoint must return a ?f=json service document, and so on. Results are graded strong (protocol-level proof) or weak (reachable but unproven), and the grade is stored in verify_method.

The detection rules for each platform:

Platform

Probe

Positive signal

CKAN

GET {root}/api/3/action/status_show

"ckan_version" in JSON

DKAN

GET {root}/api/3/action/package_search?rows=1

"result" + "success": true

ArcGIS Hub

GET {root}/api/v3/datasets?page[size]=1

"data" array in JSON

Socrata

GET {root}/api/catalog/v1

dataset array or resultsSetSize

A third script keeps the offline viewer in step with the database:

# Rebuild the inlined dataset inside viewer.html from gis_services.db -> always run after a DB change
python scripts/build_viewer.py

scripts/verify_endpoints.py is a separate, read-only reachability check (--sample N or --id WMS-0001). It reports HTTP status only and never writes to the database.

Chinese Government Portals Are a Different Animal

Domestic 省市"公共数据开放平台" do not run CKAN-style catalogs. scripts/probe_cn_portals.py handles them separately (matches entries whose URL is under gov.cn):

  • DExchangeOpen (Yinchuan, Xuzhou, …): Vue SPA; the real gateway is {root}/dexchangeOpen/appauth/getappid — live, but every data call requires SSO login and an appId token, so anonymous API access returns {"code":401,"msg":"sso not login."}.

  • Jspm platform (Dongying, Binzhou, Weihai, Shandong, …): server-rendered pages with the data catalog HTML delivered directly (/{city}/catalog/). There is no public JSON search API to register; the site itself is the interface.

  • Entries whose domain no longer resolves anywhere (checked against both the local resolver and AliDNS DoH 223.5.5.5) are recorded as cn-probe:dns-dead in verify_method with the evidence in notes — status is left untouched, because several cities folded their portals into provincial platforms (e.g. Guangdong's gddata.gd.gov.cn, Jiangsu's data.jiangsu.gov.cn) and the entry should follow the new address rather than be declared dead.

Statuses after the 2026-09-30 pass over 118 domestic entries: 96 alive (13 with a concrete API or catalog URL written into service_url), 12 domains confirmed gone.

python scripts/probe_cn_portals.py            # probe only
python scripts/probe_cn_portals.py --apply    # write back status/verify_method/notes

Bulk Harvesting from a Portal Registry

The 2026-10-02 expansion admitted 8,845 services in one pass by harvesting the dataportals-registry (43k catalog records), filtering to geospatial platforms, de-duplicating against service_url domains already in the database, then live-probing every remaining host with the platform-appropriate request (/api/3/action/status_show for CKAN, /api/v3/datasets for ArcGIS Hub, /geoserver/wms for GeoServer, …). Roughly 35,000 real HTTP requests ran; only hosts returning a protocol-level response were admitted as protocol-probe:strong, and hosts answering with a real page but no discoverable endpoint were admitted as protocol-probe:weak with the reason recorded in notes.

Two failure modes worth knowing if you rerun this:

  • Writing a URL list from Python in text mode leaves \r line endings, which makes every curl call fail with HTTP 000 in ~0.03 ms — it looks exactly like "every host is dead". Strip them (tr -d '\r') or write with newline='\n'.

  • CKAN returns "success":true with no space. Matching on "success": true silently drops hundreds of live CKAN portals.

The admission scripts are kept per batch under scripts/add_new_sources_*.py.

Catalog Maintenance Pass (2026-10-02)

A data-quality pass normalized the catalog after the bulk harvest:

  • verify_method was reduced from 40 ad-hoc strings to 8 canonical values (protocol-probe:strong|weak|unreachable, metadata-only, cn-probe:*); the original free-text evidence was preserved in notes.

  • protocol was normalized from 132 spellings to 40 protocol families (e.g. OGC WMS 1.3.0 and ArcGIS WMS both fold into OGC WMS); originals are recorded in notes as [protocol归一].

  • 5,097 portal entries that only pointed at a homepage were re-probed with six common service paths (~30k requests). 239 entries were upgraded to protocol-probe:strong with the discovered endpoint written into service_url; 4,668 homepages-only entries were honestly re-classified as 未验证 with the probe result in notes.

  • crs no longer claims EPSG:4326 where it was a placeholder: platform-API portals read 随数据集, and WMS/WFS rows carry the CRS list parsed from their live Capabilities (254 rows); unresolved ones are marked 待复测.

  • Layers: WMS/WFS GetCapabilities responses were parsed and their layer lists inserted, growing layers from 1,561 to 18,292 rows across 1,201 services.

viewer.html Is a Build Artifact (2026-10-03)

viewer.html is a single self-contained offline browser UI — its dataset is inlined as a JSON literal, not fetched at runtime. It does not track the database: through the entire bulk harvest it still showed the 2026-09-29 snapshot (2,198 records / 1,495 verified) while the catalog held 11,054 / 5,755. Regenerate it after any database change:

python scripts/build_viewer.py

The script locates the DATA = [...] block and the ST stats object by marker and replaces only those, so the page's CSS, markup and static help text survive. It is idempotent — running it twice produces the same file. Two things it also fixes:

  • The detail panel used to splice data_description, layer_or_endpoint and notes straight into innerHTML; bulk-harvested notes legitimately contain $ and >, which broke the page. All three are escaped now.

  • The stats bar gains a protocol-level strong evidence column (4,749) alongside the others.

Gotchas if you modify the generator: find the end of the DATA array with rindex("];", 0, <position of "const ST">) — searching forward with index matches the ]; of the later chips array and silently deletes the whole script between them. And stop the replaced slice at ], not ];, so the array's own terminator is preserved.

Connectivity Baseline (2026-10-03)

A 500-row random sample of verified services, probed with real requests at 40-way concurrency, returned 97.2% reachable (p50 2.0 s, p90 2.9 s). Read that number with care: 12 of the 14 non-200 responses were 400 (endpoint requires parameters), 401/403 (API key required or bot-blocking) or 412/418 (WAF) — all of which prove the server is alive. Only 2 endpoints (0.4%) genuinely timed out. Per the project rule, a single failed probe never downgrades an entry, so no status was changed.

70 catalog rows (TILE-*, HIST-*) carry {z}/{x}/{y} placeholders in service_url. That is the standard published form for a tile endpoint, not an error, but a probe must substitute real tile numbers to mean anything: with z=11 substituted, 24 of the 44 verified tile services returned a real 200 image, and the rest answered 401/403 for want of a key — which the catalog already records.

Re-verification & Thematic Round (2026-10-07)

Round 10 re-probed all 5,245 unverified entries with a twelve-path battery (~67k real requests) and added 93 new sources from curated registries:

  • Battery upgrades, then an honest audit. 216 hosts answered at protocol level on paths the previous six-path battery never tried (/wms, /ows, /geoserver/ows, THREDDS, GeoNetwork, Opendatasoft, pycsw, data.json, DKAN). A strict re-check of every hit then reverted 94 whose "data.json"/"THREDDS" match was just an HTML page referencing those strings; 5 hard-signature hits (real WMS_Capabilities/WFS XML) whose re-check failed on transient SSL/timeout were restored. Net: +215 verified (5,755 → 5,970).

  • awesome-erddap registry: 45 servers, 32 not yet in the catalog; 22 admitted (21 with a protocol-level search/index.csv response, 1 weak), 10 dead or gated.

  • STAC Index registry: 148 catalogs, 73 public ones missing; 52 admitted after confirming stac_version in the response (incl. Google Earth Engine's catalog, confirmed by full read); 2 skipped because their URLs embed an API key; 14 dead.

  • GeoNode gallery leftovers: 24 instances still unexplored, 9 admitted with live WMS_Capabilities — including 6 that earlier rounds had recorded as "unreachable from this machine" (Thünen Atlas, Sardegna CEDOC, …), a direct payoff of re-probing stale failures.

  • Thematic depth: GLIMS glacier WMS (54 layers incl. RGI 7.0), NOAA NCEP OpenGeo (940 layers), BOM THREDDS, NT Geological Survey, BGS 1:50k geology, FEMA GeoServer.

  • Layers: parsed Capabilities for every verified WMS/WFS lacking a layer list — layers grew from 18,292 to 56,969 rows across 1,394 services. Parse failures were recorded in notes, not used to change any status.

  • Two Excel deliverables were rebuilt from the database (scripts/build_xlsx.py), fixing months of drift; xlsx now also has a regenerable build script like viewer.html.

Freshness Pass & Battery Round 2 (2026-10-07)

  • Rolling freshness re-probe: the 2,411 entries verified before 2026-10-02 were re-probed against their declared protocol. 1,461 reconfirmed at protocol level and had last_verified refreshed; failures were recorded in notes only — no status was changed, per the standing rule. This is now a repeating maintenance step: oldest first, every round.

  • Battery round 2 tried nine new service mounts on all 4,956 still-unverified hosts (~45k requests): /arcgis/rest/services, /server/rest/services, /rest/services, WMTS endpoints, OGC API Features /collections, pycsw, Lizmap. 167 upgrades, of which 162 were ArcGIS Servers hiding at non-/arcgis paths — the previous batteries only looked under /arcgis. Net verified: 5,970 → 6,137.

  • Semantic reclassification round 2: description-keyword rules moved 137 entries out of the generic pool (cadastral → 测绘, groundwater → 水文, orthophoto → 遥感/影像, national statistics → 人口/社会经济…), with a multi-domain guard that keeps country-scale portals generic. A dataset-title classifier (fetch 20 live dataset titles per portal) was also tested and rejected: portal-level titles are too noisy to justify automated moves.

  • viewer.html's map payload is now self-contained: boundaries live in assets/, counts and service lists are computed from the database at build time — the build no longer depends on a scratch file from another machine. Map verified in-browser (world choropleth, China provincial drilldown, per-country service cards).

Getting Started

1. Requirements & Installation

Requires Python 3.10+:

git clone https://github.com/Wukeeeeee/GeoSource-MCP.git
cd GeoSource-MCP
pip install -r requirements.txt

2. Run Self-Test

Verify that the database and all MCP tools function as expected:

python server.py --test

You should see: [TEST] All tests passed! Ready for MCP clients.

3. Client Configuration

Claude Desktop

Add to your claude_desktop_config.json:

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "geosource": {
      "command": "python",
      "args": ["<FULL_PATH_TO_GEOSOURCE>/server.py"]
    }
  }
}
Cursor / IDEs

In your IDE's MCP settings, add a new stdio server:

  • Command: python

  • Args: <FULL_PATH_TO_GEOSOURCE>/server.py


Related MCP server: GeoSpatial MCP Server

🇨🇳 中文说明

项目简介

GeoSource MCP 是一个基于 Model Context Protocol (MCP) 标准的开源数据服务程序。它为各类 AI 编程与分析助手(Claude Desktop、Cursor、Windsurf 等)提供对本地结构化索引的 11,147 个全球真实 GIS 空间服务 与 56,969 个地图图层 的检索工具。

在开发地图应用或编写空间数据处理脚本时,大模型通常无法准确掌握全球各机构公开的实时服务接口,容易推断出不可用的链接。GeoSource MCP 直接连接本地 SQLite 数据库(gis_services.db),帮助 AI 快速检索真实的可用服务与图层参数。

工程特性与设计原则

  • 结构化发现,降低幻觉:提供经过结构化收录的真实服务端点,辅助 AI 编写准确的地图调用代码。

  • 集成全球态势地图与属地化下钻:在 viewer.html 内置直角黑白灰工程风交互地图,支持国际版图多边形高亮交互,严格遵循一个中国原则并支持全国 34 省级行政区无缝下钻与服务条目筛选复制。

  • 按需低开销检索:每次仅检索返回匹配的 35 条记录(约 200500 Tokens),避免将数兆字节的原始表格强行填入上下文窗口。

  • 透明的可用性状态(每条的验证方式都记录在 verify_method 字段,可逐条追溯):

    • 已验证(5,771 条):经探测确认为可用。其中 4,749 条带协议级实证——WMS 真的返回了 WMS_Capabilities、STAC 真的返回了 stac_version、ArcGIS REST 真的返回了服务文档。

    • 未验证(5,245 条):门户可达但未探到匿名可调用的协议级接口(六条常见路径探测无果),或受跨国网络连通性限制;每条的探测结果都写在 notes。

    • 已停止(54 条):已下线或历史归档服务,保留供查阅追溯。

    • 探测失败不会直接改判为"未验证":单次失败无法区分"服务真下线"、"本地到该站的跨境链路被阻断"、"对脚本 UA 返回 403 但浏览器正常"这三种情况,因此只记录失败原因,保留原状态。

  • 双向维护支持:支持与 Excel 表格双向数据同步,并提供更新接口供 AI 助手汇报失效链接与新地址。

数据分类与协议支持

分类

协议类型

典型代表

开放数据门户 (9,832 条)

CKAN, DKAN, ArcGIS Hub, REST API, HTTP 下载

Data.gov、欧盟数据门户、开放广东、泰国 DSD、印尼 Satu Data、各县市开放数据门户

OGC 标准服务 (687 条)

OGC WMS (1.1.1/1.3.0), WFS, WMTS, OGC API Features/Records

荷兰 PDOK、瑞士联邦地图、芬兰测绘局,以及各国市政 GeoServer

ArcGIS 平台 (295 条)

ArcGIS REST (MapServer, FeatureServer, ImageServer)

Esri Living Atlas、各国政府与水务气象机构 REST 服务

底图瓦片 (86 条)

XYZ 栅格瓦片, TMS, WMTS, PMTiles, Entwine

OpenStreetMap, Carto, Stadia Maps, OpenTopoMap

遥感时空资产 (72 条)

STAC API 1.0, OGC API Records, COG

Earth Search、行星计算机、USGS Landsat

三维空间数据 (20 条)

3D Tiles, CityGML, I3S, Cesium terrain

Cesium ion 开放资产、城市级白模与倾斜摄影服务

交通与路网 (14 条)

GTFS, GTFS-RT, OSRM, Valhalla

OpenRouteService、Transitland、各地铁公交调度 API

协议按族群归类、彼此有少量重叠(例如 ArcGIS Hub 门户同时也算开放数据门户)。按细分类目的实时 分布可通过 list_categories_and_stats 获取;当前目录覆盖 319 个国家/地区、102 个分类。

MCP 工具一览

工具名称

输入参数

功能说明

search_gis_services

keyword, country, protocol, category, is_free, need_no_key, status, limit

多条件筛选查询空间服务(支持大小写无关模糊匹配)。

get_service_detail

service_id

获取该服务的 50 余项详细元数据与关联子图层列表。

list_categories_and_stats

无

获取数据库总体量、各大类、协议分布及验证状态统计。

query_gis_sql

query

对 SQLite 数据库执行只读 SELECT SQL 查询(内置上限 100 行保护)。

probe_service_api

service_id, url, timeout

实时探测条目是否真的可访问,并自动识别底层平台(CKAN / DKAN / ArcGIS Hub / Socrata),返回真正能调用的 JSON 接口地址。推荐未验证的门户前先调用它,避免给出死链。

update_service_status

service_id, new_url, status, notes

经枚举校验后更新服务的可用状态、新 URL 或备注信息。

resolve_admin_region

region

通过 DataV 索引匹配中国行政区名称或代码;重名返回候选项,不自动选取。

fetch_admin_boundary

region, output_dir, include_children, target_crs

真正下载 DataV 边界,返回 GeoJSON 路径和来源记录,不把几何正文塞进上下文。

inspect_data_url

url

统一检查公开网址,识别文件、图层服务或网页;网页返回候选链接和浏览器交接指引。

fetch_data

url, output_dir, where, bbox, fields, max_features

通用获取 GeoJSON、常见数据文件和 FeatureServer 要素;记录来源并明确是否仅获取子集。

统一网址入口(0.3.0)

给出公开数据网址,先用 inspect_data_url 判断内容,再用 fetch_data 获取。按格式和协议处理,不要求为每个网站编写 Python。支持 GeoJSON、ZIP/GPKG/TIFF/CSV/KML/KMZ 文件链接,以及 ArcGIS FeatureServer 具体图层。文件类型仅做基础检查;不会自动解压或认证数据集内容。

普通网页返回 browser_required 和候选下载链接,交给客户端已有的浏览器工具探索后,将实际数据网址交回 GeoSource。本服务没有内置浏览器控制;网页交接不代表浏览器已经执行或文件已经获取。

GeoJSON/FeatureServer 默认最多保存 1000 个要素,可设置至 10000;数量受限时明确返回 truncated=true。FeatureServer 支持条件、WGS84 范围和字段筛选,并检查分批返回的 ID;二进制/CSV 文件整体下载,单个响应/输出上限 30 MiB。通用入口保留文件坐标,只有 FeatureServer 明确请求 outSR=4326。详细流程见 数据获取说明。

数据获取:说明文档与真正执行的区别(0.2.0)

Skill 是调用说明;MCP 工具执行本机 Python 代码,通过 HTTPS 请求 DataV 公开端点并写入本地文件。这不是模型临时生成脚本,也不是模拟浏览器抓取网页。目录检索只返回线索,不代表数据已下载。

示例:调用 fetch_admin_boundary(region="440100", include_children=true) 获取广州各区边界;只有 status="success" 才表示下载成功。结果包含文件路径、原始网址、时间、SHA256 和坐标处理记录,并写入同名 .provenance.json 文件。

默认输出到 ~/.local/share/geosource/downloads,可用 output_dir 或环境变量 GEOSOURCE_OUTPUT_DIR 指定目录。默认按 DataV 的 GCJ-02 约定近似转换到 WGS-84;返回结果明确记录来源坐标假设,不能视为测绘精度认证。设 target_crs="source" 保留来源坐标,不应直接当成 EPSG:4326 使用。

使用方式、限制和可移植 skill 见 数据获取说明。新增工具无需安装 skill 即可通过 MCP 调用;复制 Markdown 本身不会注册工具或加载地图。

数据可信度是怎么做出来的

"已验证"不是随手贴的标签,而是有脚本用真实请求跑出来的。两个脚本:

# 1) 门户接口识别:探测底层平台,把真正能调用的 API 地址写回 service_url
python scripts/probe_portal_api.py --dry-run            # 只探测不写库
python scripts/probe_portal_api.py --apply --workers 20 # 探测并回写

# 2) 协议级可用性验证:写回 status / verify_method / last_verified
python scripts/verify_services.py --limit 50             # 不加 --apply 即为只探测
python scripts/verify_services.py --apply --workers 20
python scripts/verify_services.py --apply --only-status 已验证   # 复审已有的"已验证"

verify_services.py 判断的是"服务是否以它声明的协议应答",而不只是"网址能不能打开": WMS 必须返回 WMS_Capabilities,STAC 必须返回 stac_version,ArcGIS REST 必须返回 ?f=json 的服务文档。结果分两档——strong(协议级实证)和 weak(能连通但未证实), 档位写进 verify_method 字段,任何人都能查某条记录的"已验证"是怎么来的。

各平台的识别规则:

平台

探测地址

判定依据

CKAN

GET {root}/api/3/action/status_show

JSON 中含 "ckan_version"

DKAN

GET {root}/api/3/action/package_search?rows=1

含 "result" 且 "success": true

ArcGIS Hub

GET {root}/api/v3/datasets?page[size]=1

JSON 中含 "data" 数组

Socrata

GET {root}/api/catalog/v1

数据集数组或 resultsSetSize 字段

还有第三个脚本负责让离线查询页跟上数据库:

# 3) 重新生成 viewer.html 内嵌的数据 -> 改库后必须执行
python scripts/build_viewer.py

scripts/verify_endpoints.py 是另一个只读的连通性抽查工具(--sample N 或 --id WMS-0001), 它只报 HTTP 状态码,永远不写库。

从门户登记册批量扩库(2026-10-02)

本轮一次性入库 8,845 条,靠的是 dataportals-registry (4.3 万条门户记录):筛出地理空间类平台 → 与库内已有域名去重 → 对每个候选主机发符合其平台的真实请求 (CKAN 打 /api/3/action/status_show,ArcGIS Hub 打 /api/v3/datasets,GeoServer 打 /geoserver/wms 等)。 累计发出约 3.5 万次真实请求,只有返回协议级应答的才按 protocol-probe:strong 收录; 只返回真实页面、探不到接口的按 protocol-probe:weak 收录并在 notes 写明原因。

重跑这套流程时有两个坑:

  • 用 Python 文本模式写 URL 清单会带上 \r 行尾,curl 全部报 HTTP 000、耗时 0.03ms, 看起来像"全站都死了"。要么 tr -d '\r' 清洗,要么写文件时加 newline='\n'。

  • CKAN 返回的是 "success":true(无空格)。按 "success": true(带空格)匹配会静默漏掉 几百个活着的 CKAN 门户。

各批次入库脚本留档在 scripts/add_new_sources_*.py。

数据维护批次(2026-10-02)

批量扩库之后做了一轮数据质量整修:

  • verify_method 从 40 种随手写法归一成 8 个规范枚举(protocol-probe:strong|weak|unreachable、 metadata-only、cn-probe:*),原始证据文本移入 notes 保留。

  • protocol 从 132 种拼法归一成 40 个协议族(如 OGC WMS 1.3.0、ArcGIS WMS 都并入 OGC WMS), 原值以 [protocol归一] 标记写进 notes。

  • 对 5,097 个只指向首页的门户条目补测六条常见服务路径(约 3 万次请求):239 条找到了真实接口、 升级为 protocol-probe:strong 并把接口写进 service_url;4,668 条只有首页可达,如实降为 未验证,探测结果记录在 notes。

  • crs 不再拿 EPSG:4326 当占位符:平台型 API 门户标为 随数据集;WMS/WFS 按在线 Capabilities 解析真实 CRS(254 条),解析不出的标 待复测。

  • 图层:解析 WMS/WFS GetCapabilities 并回填 layers 表,从 1,561 行增至 18,292 行, 覆盖 1,201 个服务。

viewer.html 是生成物(2026-10-03)

viewer.html 是一个单文件、离线可用的浏览器查询界面,但里面的数据是内嵌的 JSON 字面量, 不会运行时去读数据库——整个批量扩库期间它一直显示 9/29 的快照(2,198 条 / 已验证 1,495), 而库里早已是 11,054 / 5,755。改库之后必须重新生成:

python scripts/build_viewer.py

脚本按标记定位 DATA = [...] 与 ST 统计块,只替换这两段,页面的 CSS、结构和静态说明文字不动。 可重复执行,跑两次结果一致。它同时修掉两个问题:详情面板原先把 data_description、 layer_or_endpoint、notes 直接拼进 innerHTML,而批量入库的备注里确实有 $、> 这类字符, 会破坏页面,现已统一转义;统计栏新增协议级强证据一栏(4,749)。

若要改这个生成器,有两个坑:DATA 数组的结尾要用 rindex("];", 0, <"const ST" 的位置>) 往前找, 用 index 往后找会撞上后面 chips 数组的 ];,把中间整段脚本悄悄删掉;替换区间要停在 ] 而不是 ];,否则数组自己的收尾分号会被一并删掉。

联通测试基线(2026-10-03)

随机抽 500 条已验证服务、40 并发发真实请求,可达率 97.2%(p50 2.0 秒、p90 2.9 秒)。这个数字要 这么读:14 条非 200 里有 12 条是 400(端点缺必填参数)、401/403(要 API Key 或反爬)、 412/418(WAF 防护)——它们恰恰证明服务器活着。真正超时的只有 2 条(0.4%)。按项目铁律, 单次探测失败不改判,因此未改动任何条目的状态。

目录里有 70 条(TILE-*、HIST-*)的 service_url 含 {z}/{x}/{y} 占位符。这是瓦片服务的标准 发布形式、不是错误,但探测时必须替换成真实瓦片号才有意义:代入 z=11 后,44 条已验证瓦片服务里 24 条返回了真实的 200 图片,其余 401/403 是缺 Key——而这一点目录里本来就有标注。

复测与专题纵深轮(2026-10-07)

第十轮用十二条路径的探测电池复测了全部 5,245 条未验证条目(约 6.7 万次真实请求), 并从三个策划登记册新增 93 个源:

  • 电池升级 + 如实复审。216 台主机在上一轮没试过的路径上给出协议级应答 (/wms、/ows、/geoserver/ows、THREDDS、GeoNetwork、Opendatasoft、pycsw、data.json、DKAN)。 对每条命中做严格复审后撤回 94 条——那些 "data.json"/"THREDDS" 匹配只是 HTML 页面里引用了 这些字符串;5 条硬签名命中(真 WMS_Capabilities/WFS XML)复审时因瞬时 SSL/超时失败,按 "单次失败不改判"铁律恢复。净增已验证 +215(5,755 → 5,970)。

  • awesome-erddap 登记册:45 台中 32 台未收录,收 22 台(21 台 search API 返回规范 CSV 头、 1 台弱证据),10 台死或受限。

  • STAC Index 登记册:148 个目录中 73 个 public 未收录,52 个在响应中确认 stac_version 后收 录(含 Google Earth Engine 目录,全量读取确认);2 个因 URL 内嵌 API key 不收;14 个死。

  • GeoNode 画廊存量:还剩 24 个实例没测,9 个以真实 WMS_Capabilities 入库——其中 6 个是 前几轮记录"本机不可达"的(Thünen Atlas、Sardegna CEDOC 等),复测存量直接兑现。

  • 专题纵深:GLIMS 冰川 WMS(54 图层含 RGI 7.0)、NOAA NCEP OpenGeo(940 图层)、 澳大利亚气象局 THREDDS、北领地地质调查局、BGS 1:50k 地质、FEMA GeoServer。

  • 图层:对所有缺图层的已验证 WMS/WFS 解析 Capabilities,layers 从 18,292 行增至 56,969 行(1,394 个服务)。解析失败只记 notes,不改状态。

  • 两个 Excel 交付物从数据库重建(新增 scripts/build_xlsx.py),修复数月的数字漂移; xlsx 现在也和 viewer.html 一样有了可重跑的生成脚本。

保鲜复测与电池二轮(2026-10-07)

  • 滚动保鲜复测:对 2026-10-02 之前验证的 2,411 条按声明协议重探,1,461 条协议级确认存活并 刷新 last_verified;失败只记 notes,状态零变动(铁律)。此后每轮固定做,最老的优先。

  • 电池二轮对全部 4,956 条仍未验证的主机试了 9 条全新挂载路径(约 4.5 万次请求): /arcgis/rest/services、/server/rest/services、/rest/services、WMTS、OGC API Features /collections、pycsw、Lizmap。167 条升级,其中 162 个是把 ArcGIS Server 藏在非 /arcgis 路径下的站点——此前电池只盯着 /arcgis 看。已验证 5,970 → 6,137。

  • 语义归类二期:描述关键词规则把 137 条挪出泛化类(地籍→测绘、地下水→水文、正射影像→遥感、 国家统计局→人口/社会经济),并加"多域守门"——国家/大都市综合门户命中 3 类以上就留在综合类。 另试验了"拉真实数据集标题归类",试验后否决:门户级标题噪声太大,不足以支撑自动挪类。

  • viewer.html 的地图 payload 改为自包含:边界数据入库 assets/,计数与服务列表构建时从 数据库现算,不再依赖另一台机器的 scratch 文件。地图已在浏览器验收(全球填色、中国省级下钻、 各国服务卡片)。

快速开始

1. 安装依赖

git clone https://github.com/Wukeeeeee/GeoSource-MCP.git
cd GeoSource-MCP
pip install -r requirements.txt

2. 本地快速自测

python server.py --test

3. 配置客户端连接

Claude Desktop

编辑配置文件(Windows: %APPDATA%\Claude\claude_desktop_config.json,macOS: ~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "geosource": {
      "command": "python",
      "args": ["E:/my_repo/GeoSource/server.py"]
    }
  }
}
Cursor / 其他 IDE

在 MCP 配置页面添加 stdio 服务:

  • Command: python

  • Args: E:/my_repo/GeoSource/server.py


📁 数据库表结构 (Database Schema)

  • master:主服务表(主键 service_id,包含服务名、提供方、国家、协议、服务地址、格式、认证方式、验证状态等 54 个字段,建有 9 个核心索引)。

  • layers:子图层表(联合主键 (service_id, layer_idx),记录服务所属图层名称)。

  • ecosystem:开源 GIS 软件库、SDK 与数据库工具链表。


📄 License

MIT License © 2026 GeoSource Authors

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    A Model Context Protocol server that enables efficient discovery and retrieval of NASA Earth Data for geospatial analysis.
    26
    BSD 3-Clause
  • A
    license
    A
    quality
    D
    maintenance
    A Model Context Protocol (MCP) based geographic processing server that provides spatial analysis functions including coordinate system conversions, distance calculations, and area calculations.
    3
    12 npm
    3
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    A Model Context Protocol server that connects Large Language Models to the GeoServer REST API, enabling AI assistants to query and manipulate geospatial data through natural language.
    9
    95
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A Model Context Protocol server for retrieving land cover, soil type, and temporal land use data for any geographical coordinates using the National Land Cover Database and FAO soil classifications.
    MIT