Gdex Mcp

io.github.rpconroy由 GitHub 账号 rpconroy 发布v0.1.0更新于 Oct 25, 2026

MCP server for the GDEX (Geoscience Data Exchange) data portal: datasets, files, metrics, subsetting

已验证Streamable HTTP可网页运行文件与存储知识与记忆数据与分析

概览

AI 生成的概览

面向 GDEX 地球科学数据门户的 MCP 服务器,让助手发现数据集、浏览文件、查找 ARCO 变量并管理子集提取请求。

可以做什么
检索与描述数据集:按关键词列出、读取元数据、单个字段、综合概览、工作人员联系方式以及门户级和单数据集指标。浏览文件:遍历文件分组、列出文件、按名称模式搜索文件并翻页查看结果。按数据类型(grid、cyclone_fix、sensor)搜索数据文件,使用先查到的筛选代码和日期范围。检查 ARCO 可用性,列出或搜索 ARCO 变量,包括 kerchunk 引用。获取数据访问方式,如下载链接和 Globus 地址。管理子集提取请求:读取控制文件模板、校验请求体、提交、轮询状态、获取输出文件以及清除请求。
适用场景
适用于处理 NCAR/GDEX 地球科学数据的场景:查找某个变量所在的数据集、定位某日期或参数对应的文件、确认是否存在可直接分析的 ARCO 数据,或准备并提交子集提取请求而无需下载整个文件。
运行要求
可通过 streamable HTTP 连接远程端点 pip 本地安装并以 gdex-mcp 命令运行。多数工具无需配置。子集提取相关工具需要 GDEX 令牌:本地使用 GDEX_TOKEN,使用共享服务时通过 Authorization: Token 请求头传入。需要能访问 GDEX 的网络。
安装前请注意
子集提取工具会操作你的 GDEX 账户:submit_subset_request 和 submit_and_wait_for_request 会创建真实请求,purge_request 会删除请求及其输出文件。GDEX 令牌属于凭据;使用共享服务时应每次请求传入自己的令牌,而不要依赖共享令牌。数据集列表规模很大,不加筛选地浏览可能占满上下文。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Gdex Mcp,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Web executable,通过 Streamable HTTP。 远程服务在工作区中配置后即可从网页运行时运行。

交给智能体安装

把这段提示词粘贴到 Claude Code、Codex、Cursor 等智能体,或 SourceWeft 对话中。智能体会读取该服务器的安装指南,先向你展示发布者、端点和登录方式,经你同意后再把它添加到你的客户端。密钥不会写进任何命令。

阅读 https://sourceweft.com/mcp/io.github.rpconroy%2Fgdex-mcp/install.md,并按其中说明把这个 MCP 服务器接入我的客户端。修改任何配置之前,先告诉我它的发布者、端点和登录方式,等我确认。不要把 API 密钥写进命令或我会提交的文件;问我密钥应从哪里获取。

查看智能体所依据的安装指南

其他 MCP 客户端

把它添加到你客户端的 mcpServers 配置中。

{
  "mcpServers": {
    "gdex": {
      "type": "http",
      "url": "https://gdex-mcp.k8s.ucar.edu/mcp"
    }
  }
}

README

GDEX MCP Server

An MCP (Model Context Protocol) server exposing the GDEX (Geoscience Data Exchange) REST API as tools for LLM clients — dataset discovery/metadata, file listings, data access links, ARCO variables, portal/dataset metrics, staff contacts, and authenticated subsetting-request workflows.

Running locally

pip install -e .gdex-mcp

Then point your MCP client (Claude Desktop, Claude Code, etc.) at the gdex-mcp command. Configuration is via environment variables or a .env file — see CLAUDE.md's Configuration section. Most tools need no configuration at all; set GDEX_TOKEN only if you'll use the subsetting-request tools (list_request_statuses, check_request_status, get_request_files, submit_subset_request, submit_and_wait_for_request, purge_request).

Running as a shared service

Set GDEX_MCP_TRANSPORT=streamable-http (see Dockerfile) to run this as a network-reachable service instead of a local stdio subprocess. In that mode, callers using the subsetting-request tools pass their own GDEX token as an Authorization: Token <token> header on each request rather than relying on a shared GDEX_TOKEN — see CLAUDE.md's "Two transports" section for how that's wired.

Docker

bash
# Build the imagedocker build -t gdex-mcp .
# Run the containerdocker run -d --name gdex-mcp -p 8080:8080 gdex-mcp

MCP requests go to http://localhost:8080/mcp.

bash
# Stop and remove the containerdocker stop gdex-mcp && docker rm gdex-mcp

Deployment

A merged PR to main triggers the GitHub Actions workflow, which runs the test suite (pip install -e ".[test]" && pytest) and then builds a new Docker image and pushes it to Harbor (hub.k8s.ucar.edu/gdex_mcp/gdex-mcp). The app is deployed to Kubernetes via the Helm chart in app-chart/ — see CLAUDE.md's Deployment section for how this follows gdex-web-services' conventions.

bash
# Deploy with Helmhelm upgrade --install gdex-mcp ./app-chart -n <namespace>
# Deploy a test instancehelm upgrade --install gdex-mcp ./app-chart -n <namespace> --set testName=<your-name>

MCP Registry

gdex-mcp is published to the official MCP Registry as io.github.rpconroy/gdex-mcp (see server.json), not io.github.NCAR/gdex-mcp. Publishing under the NCAR org namespace kept failing with a 403 even after making org membership public — a known, unresolved issue with the registry's org-membership check (see modelcontextprotocol/registry#1537 and #1649), suspected to be an org-admin-side GitHub OAuth App access restriction rather than anything on our end. .github/workflows/publish-mcp-registry.yaml publishes new versions on v* tags; it uses PAT auth (MCP_GITHUB_TOKEN secret) instead of GitHub OIDC because this repo is NCAR-owned, so Actions OIDC always asserts repository_owner: NCAR and can't authenticate as the personal rpconroy namespace. Once NCAR org access is sorted out, moving to io.github.NCAR/gdex-mcp means publishing a new registry entry (the registry has no rename support) and switching the workflow back to login github-oidc.

Documentation

CLAUDE.md has the full picture: architecture, conventions to follow when adding tools, the two transport modes, and deployment. Read it before making changes here.

来源:README.md,提交 3333119

工具

30

list_datasets

List datasets available on GDEX, with their IDs and titles. The full catalog has ~1700 datasets — far too many to return at once. Always pass `query` to filter by keyword unless the user specifically wants to browse the whole catalog page by page. Args: query: Keyword(s) to filter by, matched case-insensitively as a substring against dataset id and title. Leave empty to browse unfiltered. limit: Max number of datasets to return (default 50, capped at 500) offset: Number of matching datasets to skip, for paging through results

输入参数limitqueryoffset

get_dataset_metadata

Return full metadata for a GDEX dataset (parameters, temporal range, spatial coverage, etc.). Args: dsid: Dataset ID (dNNNNNN), e.g. d083002

输入参数dsid必填

get_dataset_field

Return one metadata field for a dataset. Prefer describe_dataset when the user wants a general summary covering several of these at once (abstract, temporal, spatial_coverage, variables, data_formats, volume) — this tool is for pulling a single field, including the fields describe_dataset doesn't cover (publications, contributors, related_datasets, documentation). Args: dsid: Dataset ID (dNNNNNN), e.g. d083002 field: One of: abstract, variables, temporal, spatial_coverage, publications, contributors, data_formats, volume, related_datasets, documentation

输入参数dsid必填field必填

describe_dataset

Return a combined overview of a dataset — abstract, temporal coverage, spatial coverage, variables, data formats, and volume — in a single call. Prefer this over calling get_dataset_field repeatedly when the user wants a general summary of a dataset. If one of the underlying fields fails to load, it's returned as {"error": ...} rather than failing the whole call. Args: dsid: Dataset ID (dNNNNNN), e.g. d083002

输入参数dsid必填

get_file_groups

Return file groups for a dataset. Pass gindex to get child groups under a parent. Groups nest (dataset -> format -> year -> month, or similar, varying by dataset) and there's no way to predict a child's gindex in advance — each group's gindex/url is dataset-specific and only knowable from the parent response. To drill down, read the gindex (or url) off a row in this response and pass that as the next call's gindex. This never returns file rows, only groups — every response stays small regardless of how many files the dataset holds, unlike get_dataset_files. Descend until a call returns empty ({} or []): that means the gindex you just called with is a leaf with no further subgroups, so it's safe to call get_dataset_files there for the actual files. find_dataset_files automates exactly this walk if you'd rather not do it by hand. At the top level, watch for a "Kerchunk Reference Files" (or similar ARCO-related) group alongside the raw-format groups. For an analysis task, prefer pulling from there (see also has_arco/get_arco_variables) over a raw data file when one's available — it avoids downloading a whole file just to read a subset of it. Args: dsid: Dataset ID (dNNNNNN), e.g. d083002 gindex: Optional group index to fetch child groups

输入参数dsid必填gindex

get_dataset_files

Return a paginated file listing for a dataset or a specific group. Depending on how deep gindex is in the group hierarchy, this returns either actual file rows or another layer of subgroup summaries — there's no way to tell in advance which you'll get. If you get subgroups, read the gindex (or url) off a row and call again with that gindex to go one level deeper; gindex values are dataset-specific and can't be guessed. A shallow gindex on a large dataset can return a very large response (thousands of files) — the file-row portion of the response is capped at 500 rows (look for "_truncated": true). Two ways to avoid hitting that cap instead of drilling down group by group: pass filter_wfile with a filename pattern (e.g. a date like "20220808") to filter down to matching files, or page through a known group's results with `page`. filter_wfile only filters actual file rows, so it has no effect at a gindex that's still returning a subgroup summary rather than files — if a first attempt comes back unfiltered, descend one level (see get_file_groups) and retry there. Args: dsid: Dataset ID (dNNNNNN), e.g. d083002 gindex: Optional group index to filter files page: Page number to fetch (for a group with more files than fit on one page) filter_wfile: Filter files by name pattern, e.g. "20220808" to match a date fl: File list source (defaults to "web" server-side)

输入参数fldsid必填pagegindexfilter_wfile

find_dataset_files

Search a dataset's file-group hierarchy for files matching a name pattern (e.g. a date like "20220808"), without ever pulling a large, context-blowing file listing. Automates the pattern described in get_file_groups: recursively calls get_file_groups, descending into every child gindex, until a gindex returns no further children (a leaf group) — then calls get_dataset_files there with filter_wfile=name_pattern and keeps only the matches. Prefer this over manually drilling with get_file_groups/get_dataset_files when you don't already know roughly where in the hierarchy to look. A dataset's hierarchy can be large (hundreds of leaf groups), and this tool has no way to know in advance which branches might contain a match, so it may need to visit many groups to be thorough. Pass start_gindex if you already know a good starting point (e.g. from a prior get_file_groups call, or a related dataset's structure) to narrow and speed up the search. If the number of groups visited hits max_groups_visited, the search stops early and `stopped_early` comes back true — narrow with start_gindex and retry, or raise the cap. Args: dsid: Dataset ID (dNNNNNN), e.g. d083002 name_pattern: Filename substring/pattern to match, e.g. "20220808" for a date start_gindex: Optional group index to start the search from, instead of the dataset root max_groups_visited: Safety cap on groups traversed before giving up (default 300)

输入参数dsid必填name_pattern必填start_gindexmax_groups_visited

get_filesearch_datatypes

Return the file-search datatypes available for a dataset (a subset of "grid", "cyclone_fix", "sensor"). Call this before the other filesearch_* tools to know which one(s) apply — a dataset only supports search for the datatypes it actually contains. Args: dsid: Dataset ID (dNNNNNN), e.g. d083002

输入参数dsid必填

get_filesearch_grid_filters

Return the valid parameter/product/grid/level codes and date range for "grid" datatype file search on a dataset. Use this to discover the codes to pass to get_filesearch_grid_files, optionally narrowed by any filters you already know you want. Args: dsid: Dataset ID (dNNNNNN), e.g. d083002 valid_datetime_min: Restrict to data valid on/after "YYYY-MM-DD HH:MM" valid_datetime_max: Restrict to data valid on/before "YYYY-MM-DD HH:MM" parameters: Restrict to specified parameter code(s) products: Restrict to specified product code(s) grids: Restrict to specified grid code(s) levels: Restrict to specified vertical level code(s)

输入参数dsid必填gridslevelsproductsparametersvalid_datetime_maxvalid_datetime_min

get_filesearch_cyclone_fix_filters

Return the valid date range and other filters for "cyclone_fix" datatype file search on a dataset. Args: dsid: Dataset ID (dNNNNNN), e.g. d083002 valid_datetime_min: Restrict to data valid on/after "YYYY-MM-DD HH:MM" valid_datetime_max: Restrict to data valid on/before "YYYY-MM-DD HH:MM"

输入参数dsid必填valid_datetime_maxvalid_datetime_min

get_filesearch_sensor_filters

Return the valid date range and other filters for "sensor" datatype file search on a dataset. Args: dsid: Dataset ID (dNNNNNN), e.g. d083002 valid_date_min: Restrict to data valid on/after "YYYY-MM-DD" valid_date_max: Restrict to data valid on/before "YYYY-MM-DD"

输入参数dsid必填valid_date_maxvalid_date_min

get_filesearch_grid_files

Search for data files containing "grid" datatype data, filtered by parameter code(s) and optionally by time range, product, grid, or level. Results are paginated; use get_filesearch_result_page with the returned result_id to fetch additional pages. Use get_filesearch_grid_filters first to find valid parameter/product/grid/level codes for this dataset. Args: dsid: Dataset ID (dNNNNNN), e.g. d083002 parameters: Parameter code(s) to search for (required, at least one) valid_datetime_min: Restrict to data valid on/after "YYYY-MM-DD HH:MM" valid_datetime_max: Restrict to data valid on/before "YYYY-MM-DD HH:MM" products: Restrict to specified product code(s) grids: Restrict to specified grid code(s) levels: Restrict to specified vertical level code(s)

输入参数dsid必填gridslevelsproductsparameters必填valid_datetime_maxvalid_datetime_min

get_filesearch_cyclone_fix_files

Search for data files containing "cyclone_fix" datatype data, optionally filtered by time range. Results are paginated; use get_filesearch_result_page with the returned result_id to fetch additional pages. Args: dsid: Dataset ID (dNNNNNN), e.g. d083002 valid_datetime_min: Restrict to data valid on/after "YYYY-MM-DD HH:MM" valid_datetime_max: Restrict to data valid on/before "YYYY-MM-DD HH:MM"

输入参数dsid必填valid_datetime_maxvalid_datetime_min

get_filesearch_sensor_files

Search for data files containing "sensor" datatype data, optionally filtered by date range. Results are paginated; use get_filesearch_result_page with the returned result_id to fetch additional pages. Args: dsid: Dataset ID (dNNNNNN), e.g. d083002 valid_date_min: Restrict to data valid on/after "YYYY-MM-DD" valid_date_max: Restrict to data valid on/before "YYYY-MM-DD"

输入参数dsid必填valid_date_maxvalid_date_min

get_filesearch_result_page

Return a page of results from a previous get_filesearch_*_files call, by its result_id. Use this to page through file-search results beyond the first page (see the "pagination" block of a files/results response for num_pages and next_page). Args: dsid: Dataset ID (dNNNNNN), e.g. d083002 result_id: The result_id from a previous filesearch files/results response page_num: Page number to retrieve

输入参数dsid必填page_num必填result_id必填

get_data_access

Return data access options for a dataset — download links, Globus URLs, access methods. Args: dsid: Dataset ID (dNNNNNN), e.g. d083002

输入参数dsid必填

has_arco

Check whether Analysis-Ready Cloud-Optimized (ARCO) data is available for a dataset. For analysis tasks, call this (and check for a "Kerchunk Reference Files" group via get_file_groups) before reaching for raw data files — reading through ARCO/kerchunk references avoids downloading whole files just to subset them. When picking among kerchunk reference variants, always use the one with "-osdf" in its name (see get_arco_variables) — other variants' chunk targets can be internal paths that only resolve on NCAR's network. Open it with xr.open_dataset(url, engine="kerchunk", storage_options={"remote_protocol": "https", "lazy": True}) rather than hand-building an fsspec reference filesystem. Args: dsid: Dataset ID (dNNNNNN), e.g. d083002

输入参数dsid必填

get_arco_variables

Return the list of ARCO variables available for a dataset. Each row's type (index 2) is either "zarr" or "reference" (kerchunk). A "reference" variable is often listed multiple times, once per kerchunk reference variant (plain, "-remote-https", "-remote-osdf", etc.) — always pick the "-osdf" variant's URL; the others' chunk targets can be internal paths that only resolve on NCAR's network. Open it with xr.open_dataset(url, engine="kerchunk", storage_options={"remote_protocol": "https", "lazy": True}) — that's better behaved than hand-building an fsspec reference filesystem. A "zarr" row needs no variant picking — its URL already routes through the OSDF director (rewritten automatically); open it directly with xr.open_dataset(url, engine="zarr"). Results are capped at 300 rows (look for "truncated": true); narrow with search_arco_variables if you hit the cap. Args: dsid: Dataset ID (dNNNNNN), e.g. d083002

输入参数dsid必填

search_arco_variables

Search ARCO variables by name for a dataset. As with get_arco_variables, a "reference" (kerchunk) match is often listed once per variant — always pick the "-osdf" variant's URL (reachable from anywhere), and open it with xr.open_dataset(url, engine="kerchunk", storage_options={"remote_protocol": "https", "lazy": True}). A "zarr" match needs no variant picking — its URL already routes through the OSDF director (rewritten automatically); open it directly with xr.open_dataset(url, engine="zarr"). Args: dsid: Dataset ID (dNNNNNN), e.g. d083002 query: Search text to match against variable names

输入参数dsid必填query必填

get_portal_metrics

Return a GDEX portal-wide metric. Args: metric: One of: volume_downloaded, unique_users, total_datasets, total_citations, gdex_volume, total_requests, top_datasets, ai_datasets

输入参数metric

get_dataset_metrics

Return a per-dataset metric. Args: dsid: Dataset ID (dNNNNNN), e.g. d083002 metric: One of: users_month, users_year, volume_month, volume_year

输入参数dsid必填metric

get_staff

Return GDEX staff contacts, optionally filtered to a specific dataset. Args: dsid: Optional dataset ID. If omitted, returns all staff.

输入参数dsid

list_request_statuses

List all subsetting request statuses for the authenticated user. Requires GDEX_TOKEN.

无需输入参数。

check_request_status

Check the status of a specific subsetting request. Requires GDEX_TOKEN. Args: rindex: Request index/ID

输入参数rindex必填

get_request_files

Return the output files for a completed subsetting request. Requires GDEX_TOKEN. Args: rindex: Request index/ID

输入参数rindex必填

get_control_file_template

Return the control file template for building a subsetting request for a dataset. Args: dsid: Dataset ID (dNNNNNN), e.g. d083002

输入参数dsid必填

validate_subset_request

Check a subset request body against the dataset's control file template, without submitting anything. Use this before submit_subset_request to catch missing or unrecognized fields fast, instead of finding out from a failed API call. Args: dsid: Dataset ID (dNNNNNN), e.g. d083002 request_json: JSON string of the subsetting request body to validate

输入参数dsid必填request_json必填

submit_subset_request

Submit a data subset request to GDEX. Requires GDEX_TOKEN. Args: request_json: JSON string of the subsetting request body. Use get_control_file_template to get the expected structure for a dataset, or validate_subset_request to check it before submitting.

输入参数request_json必填

submit_and_wait_for_request

Submit a subset request and poll its status until it finishes, fails, or timeout_s elapses — instead of calling submit_subset_request and then manually looping on check_request_status. Requires GDEX_TOKEN. GDEX's API schema doesn't document the exact status vocabulary, so "finished" is a best-effort match on the status text (words like "complete" vs. "error"/"fail"). If the outcome comes back "timeout", that means the request is still pending by our reading, not that it failed — keep polling with check_request_status(rindex), or re-run this tool with a longer timeout_s. If it comes back "unknown", the status payload didn't contain a field we recognize; inspect the raw "status" value yourself. Args: request_json: JSON string of the subsetting request body (see get_control_file_template). poll_interval_s: Seconds between status checks (default 15, minimum 5). timeout_s: Give up and return the last-seen status after this many seconds (default 600).

输入参数timeout_srequest_json必填poll_interval_s

purge_request

Delete a subsetting request and its output files. Requires GDEX_TOKEN. Args: rindex: Request index/ID to purge

输入参数rindex必填

版本历史

1
  1. v0.1.0最新Sep 25, 2026

评分

已满足适用检查项的 90%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通必需25 分
  • 已声明认证方式必需10 分
  • 已列出工具必需15 分
  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分

    请在仓库或注册中心条目中声明许可证。