Skip to main content
Glama
oceanum-io

Oceanum MCP

Official
by oceanum-io

Oceanum MCP

An MCP server package that provides AI assistants with access to the Oceanum platform for ocean/environmental data and cloud storage.

Servers

This package contains multiple MCP servers, selectable at runtime:

Server

Description

datamesh

Search, query, and manage ocean/environmental datasets

storage

List, read, write, and delete files in Oceanum cloud storage

combined

All tools from both servers under a single endpoint (default)

Related MCP server: Code Ocean MCP Server

Prerequisites

Get an API token from oceanum.io. Set it as the DATAMESH_TOKEN environment variable (or keep it out of the client config: see Supplying the token without putting it in the client config).

Installation

Requires Python 3.10–3.13. Python 3.14 is not supported yet: the zarr 2.x stack that oceanum depends on needs numcodecs<0.16, which has no Python 3.14 wheels.

pip install oceanum-mcp

Or run directly with uvx. Pass --python 3.13 so uv doesn't pick Python 3.14 (uv downloads 3.13 if it isn't installed):

uvx --python 3.13 oceanum-mcp              # combined server (default)
uvx --python 3.13 oceanum-mcp datamesh     # datamesh only
uvx --python 3.13 oceanum-mcp storage      # storage only
uvx --python 3.13 oceanum-mcp --list       # show available servers

Configuration

Claude Desktop

Add to your claude_desktop_config.json:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%\Claude\claude_desktop_config.json

Combined server (all tools):

{
  "mcpServers": {
    "oceanum": {
      "command": "uvx",
      "args": ["--python", "3.13", "oceanum-mcp"],
      "env": {
        "DATAMESH_TOKEN": "your-token-here"
      }
    }
  }
}

Individual server (datamesh only):

{
  "mcpServers": {
    "oceanum-datamesh": {
      "command": "uvx",
      "args": ["--python", "3.13", "oceanum-mcp", "datamesh"],
      "env": {
        "DATAMESH_TOKEN": "your-token-here"
      }
    }
  }
}

Claude Code

# Combined server
claude mcp add --transport stdio oceanum -- uvx --python 3.13 oceanum-mcp

# Individual server
claude mcp add --transport stdio oceanum-datamesh -- uvx --python 3.13 oceanum-mcp datamesh

Set the token in your environment:

export DATAMESH_TOKEN=your-token-here

VS Code / Cline / Continue

Use stdio transport with the same command:

{
  "command": "uvx",
  "args": ["--python", "3.13", "oceanum-mcp"],
  "env": {
    "DATAMESH_TOKEN": "your-token-here"
  }
}

If the server reports that the token "looks like an unresolved client variable", your client passed a config variable such as ${input:datamesh-token} through literally instead of substituting it. Restart the server from the client so it prompts for the input again, or use one of the options below.

Supplying the token without putting it in the client config

For the stdio transport the server takes its token from the first of these that is set:

  1. DATAMESH_TOKEN — the token itself.

  2. DATAMESH_TOKEN_FILE — path to a file containing the token (~ is expanded). On macOS/Linux the file must be accessible only by you; the server refuses it otherwise:

    install -m 600 /dev/null ~/.config/oceanum/token
    echo "your-token-here" > ~/.config/oceanum/token
    "env": { "DATAMESH_TOKEN_FILE": "~/.config/oceanum/token" }

    The file is read on every call, so a replaced token takes effect without restarting the server.

  3. DATAMESH_TOKEN_KEYRING=1 — read the token from the OS credential store (macOS Keychain, Secret Service/libsecret on Linux, Windows Credential Manager) via the keyring package, under service oceanum-mcp, user datamesh-token. Store it once with:

    uvx keyring set oceanum-mcp datamesh-token

    The token is looked up once per server process, so restart the server after changing it. keyring currently arrives as an indirect dependency of fastmcp, which is not guaranteed to last: to be sure, install the oceanum-mcp[keyring] extra (with uvx: uvx --python 3.13 --from "oceanum-mcp[keyring]" oceanum-mcp).

Troubleshooting: -32022 on the first initialize

A client may log "connection is serving the 2026-07-28 protocol; the initialize handshake is not accepted" (error -32022) once on connect. This comes from the MCP Python SDK, not from this server's code: in SDK 2.3.0 (mcp/server/runner.py, serve_dual_era_loop) a connection's first request fixes its protocol era. A client that opens with a 2026-07-28 request and then sends the older initialize handshake on the same connection is refused, with the supported versions in the error. Clients are expected to retry with a supported version; GitHub Copilot did so and connected.

Environment Variables

Variable

Required

Description

DATAMESH_TOKEN

Yes*

Oceanum API token (shared by all servers)

DATAMESH_TOKEN_FILE

Yes*

Path to a file holding the token, readable only by its owner; used when DATAMESH_TOKEN is unset

DATAMESH_TOKEN_KEYRING

Yes*

1/true/yes/on to read the token from the OS credential store (once per process); used when neither of the above is set

DATAMESH_SERVICE

No

Custom datamesh service URL (default: https://datamesh.oceanum.io)

STORAGE_SERVICE

No

Custom storage service URL (default: https://storage.oceanum.io)

OCEANUM_DOMAIN

No

Override the base domain for all services (default: oceanum.io)

OCEANUM_MCP_READ_ONLY

No

1/true/yes/on to disable write tools (update_metadata, storage write_file/delete_file); any value other than these or 0/false/no/off stops the server at startup

OCEANUM_MCP_MAX_INLINE_BYTES

No

Max staged result size returned inline by query_data (default 50,000,000)

OCEANUM_MCP_MAX_INLINE_ROWS

No

Max rows/records previewed inline before truncation (default 100)

OCEANUM_MCP_EXPORT_DIR

No

If set, export_query may only write inside this directory

OCEANUM_MCP_STAGE_TIMEOUT

No

Seconds a Datamesh staging/query request may wait on the gateway before the tool returns a timeout error (default 120)

OCEANUM_MCP_AUTH

No

Auth scheme for --transport http: auto (default), datamesh, auth0, or none

OCEANUM_MCP_AUTH0_DOMAIN

No

Auth0 tenant domain for auth0 mode (default: auth.oceanum.io)

OCEANUM_MCP_AUTH0_AUDIENCE

No

Auth0 API audience for auth0 mode (default: https://api.oceanum.io)

OCEANUM_MCP_PUBLIC_URL

No

Externally visible base URL (e.g. https://mcp.oceanum.io); enables OAuth discovery metadata for claude.ai connectors

OCEANUM_MCP_CORS_ORIGINS

No

Comma-separated browser origins allowed by CORS on http (default: https://*.oceanum.io,https://*.oceanum.tech,https://vscode.dev; empty string disables)

* One token source (DATAMESH_TOKEN, DATAMESH_TOKEN_FILE or DATAMESH_TOKEN_KEYRING) is required for the stdio transport (and for --transport http with OCEANUM_MCP_AUTH=none); in authenticated http mode each request carries its own credential and no server-side token is needed.

Hosted mode (HTTP transport)

Run any server as a shared, multi-tenant HTTP service:

oceanum-mcp datamesh --transport http --host 0.0.0.0 --port 8000

This serves the MCP streamable-HTTP endpoint at http://<host>:<port>/<server> (/datamesh here; override with --path). Each server owning its own path lets several MCP servers share one domain behind an ingress — e.g. https://mcp.oceanum.io/datamesh and https://mcp.oceanum.io/storage. Every request must present a bearer credential, and all Datamesh/Storage calls are made as that request's user — connections are cached per credential and never shared between tokens.

Auth schemes (OCEANUM_MCP_AUTH):

  • auto (default) — accepts either credential, detected per request: Datamesh tokens arrive in the X-DATAMESH-TOKEN header (the same header the gateway itself uses), Auth0 JWTs in Authorization: Bearer. A Datamesh token sent as the bearer also works (JWT-shape detection routes it), but the dedicated header is the canonical form. Each request runs as the identity its own credential resolves to.

  • datamesh — only Datamesh tokens are accepted. The server validates them against the gateway. Add to Claude Code with:

    claude mcp add --transport http oceanum-datamesh https://mcp.oceanum.io/datamesh \
      --header "X-DATAMESH-TOKEN: <datamesh-token>"
  • auth0 — clients send an Auth0-issued JWT, validated against the tenant JWKS and forwarded to the Datamesh gateway as-is.

  • none — no authentication; every request uses the server's own DATAMESH_TOKEN. Only for trusted-network deployments.

Notes:

  • export_query works over HTTP but changes shape: instead of writing to the server's local filesystem (meaningless for remote clients), it returns a time-limited, self-authenticating gateway download_url that the caller fetches out-of-band. The path argument is ignored on hosted servers. The URL needs no credential, so it is a capability — treat it as a secret. Gateways with scoped download links (OCE-317) also limit its lifetime and number of fetches; the response then reports them as expires_at and max_uses. Hosted exports are capped at 10 GB to bound what one link can pull, and exports above 1 GB need confirm_size_bytes (see export_query).

  • A rejected Datamesh token (in X-DATAMESH-TOKEN, or a non-JWT Authorization: Bearer) gets a 401 saying the token was not accepted, without the OAuth resource_metadata challenge (which would send clients such as VS Code into a sign-in flow that cannot fix a Datamesh token). Requests with no credential, and failed JWT (OAuth) bearers, still get the challenge, so OAuth discovery and re-authorization are unaffected. If the token could not be verified because the Datamesh service was unreachable, the response is a 503 asking to retry instead. A credential that is an unsubstituted client variable (${input:...}) gets a 401 saying so (except with OCEANUM_MCP_AUTH=none, where client credentials are ignored).

  • Combine with OCEANUM_MCP_READ_ONLY=1 to run a read-only public service.

  • Pass --stateless when running behind a load balancer or on autoscaled platforms (Cloud Run, etc.): sessions are otherwise held in instance memory, and consecutive requests routed to different instances would fail.

  • Breaking change for --transport sse (deprecated): sse is a network transport and now behaves like http — authenticated by default and no export_query. Set OCEANUM_MCP_AUTH=none to restore the old unauthenticated behavior.

Serving under an external ASGI server

To run under uvicorn/gunicorn (multiple workers, serverless platforms), use the packaged app factory — it applies the same auth and tool policy as the CLI; serving mcp.http_app() directly would bypass both:

uvicorn --factory oceanum_mcp.app:create_http_app --host 0.0.0.0 --port 8000

Requests on a network transport never fall back to the server's DATAMESH_TOKEN: an unauthenticated request fails unless OCEANUM_MCP_AUTH=none was set explicitly.

Browser clients (CORS)

Browser-based MCP clients send a CORS preflight (OPTIONS) before every cross-origin request. The http app answers preflights for an allowlist of origins, ahead of authentication (a preflight never carries a credential); all other requests still require one. Configure the allowlist with OCEANUM_MCP_CORS_ORIGINS, comma-separated:

OCEANUM_MCP_CORS_ORIGINS="https://*.oceanum.io,https://vscode.dev,http://localhost:6274"
  • Unset: https://*.oceanum.io, https://*.oceanum.tech and https://vscode.dev.

  • Empty string: CORS disabled — no CORS headers, preflights are not answered.

  • Each entry is an exact origin (scheme://host[:port], no path). A leading *. matches exactly one subdomain label: https://*.oceanum.io allows https://app.oceanum.io but not https://oceanum.io, https://a.b.oceanum.io or https://oceanum.io.evil.com. Bare *, single-label wildcards (https://*.io) and malformed entries are rejected at startup; a scheme-default port (:443 on https) is dropped, as browsers omit it. Multi-label public suffixes (https://*.co.uk, https://*.github.io) cannot be detected — never configure them: they would admit every site under that suffix.

  • Credentials travel in Authorization / X-DATAMESH-TOKEN headers, never cookies, so Access-Control-Allow-Credentials is never sent. Mcp-Session-Id and WWW-Authenticate are exposed to browser scripts.

claude.ai custom connectors

Set OCEANUM_MCP_PUBLIC_URL to the server's public base URL and the auto and auth0 modes additionally serve OAuth 2.0 Protected Resource Metadata (RFC 9728) naming the Auth0 tenant, plus a WWW-Authenticate challenge on 401s — which is how claude.ai discovers where to send users to authorize. The Auth0 tenant must allow client registration for Claude (Dynamic Client Registration, or a pre-registered application) and issue JWT access tokens for the configured audience. Header/bearer clients are unaffected either way.

Post-deploy smoke test

scripts/smoke_hosted.py opens real gridded datasources over zarr through a deployed server (load_datasource, and a whole-grid query_data), which catches a broken data stack in the image that tools/list does not. There is no deploy pipeline (the hosted service is deployed by hand with the local deploy_cloudrun*.sh scripts), so run it manually after each deploy:

DATAMESH_TOKEN=<token> uv run python scripts/smoke_hosted.py https://mcp.oceanum.io/datamesh

The token must be valid for the gateway the server uses. --load-datasource, --query-datasource and --query-variable override the default datasets. The URL must be https unless the host is local, since the token is sent with every request. Exit status: 0 all checks passed; 1 a check failed, or the server was unreachable or rejected the token; 2 usage error (DATAMESH_TOKEN unset, or a non-https remote URL); 3 inconclusive (a datasource was not found, not shared or empty, the query was refused, or it was small enough to be downloaded instead of opened over zarr).

The hosted image installs this package from the source checkout (pip install .), not from PyPI, so dependency fixes take effect on the next deploy from main without a release.

Datamesh Tools

The intended workflow is: search_catalog → get_datasource_info → stage_query (dry run: learn the result size without downloading) → query_data for small results inline, or export_query to write large results to a file that analysis code reads directly.

search_catalog

Search the Datamesh catalog with optional text search, time range, and bounding box filters. Returns a JSON object with count and results; if count equals limit, more matches may exist. Only datasources accessible to the request's credentials are searched. An empty or short (below limit, with nothing omitted) result carries a fixed scope note saying a missing datasource either does not exist or is not accessible with these credentials; it never reveals whether, how many, or which inaccessible datasources exist.

By default each result is a compact summary: id, name, a description cut to 200 characters, tstart/tend, bounds (rounded outward to 4 decimals), variable names when the catalog provides them (first 20, with variables_total), and the first 5 tags (each clipped to 60 characters, with tags_total). Unusable bounds (empty or non-finite) are null. detail="full" returns each datasource's complete catalog record instead. The response is compact JSON, and its total size is bounded (~20k characters for summaries, ~100k for full records): matches beyond the bound are dropped, counted in omitted, and a note asks to refine the search.

The catalog ranks datasources by fuzzy similarity to the search text and returns the closest ones even when none contains it. With search text, the response therefore carries text_matches: how many results have every search word (as a whole word, singular or plural) in their id, name, description, tags, labels or variable names. or separates alternatives and negated words or phrases (-era5, -"era5 grid", not era5) are ignored. This count is only a signal: no result is dropped for failing it, but results that fail are marked "text_match": false, and a text_note ahead of the results explains. If no result contains the text as whole words (text_matches: 0), every result is still returned, but in summary mode as id and name only, with a text_note first and no scope note.

Parameter

Type

Description

search

string

Text search for name, description, or tags

time_start

string

ISO 8601 start time

time_end

string

ISO 8601 end time

bbox

list[float]

Bounding box [xmin, ymin, xmax, ymax] in WGS84

limit

int

Max results to return (default 20)

detail

string

summary (default) or full

get_datasource_info

Get the metadata for a datasource: coverage, schema dims and coordinates, variables, and attributes.

The default (detail="summary") is a compact view with the same fields as the full record. Each variable and coordinate keeps its dims, shape, dtype and units/long_name/standard_name attributes only (other attributes are counted in attrs_omitted); the description is clipped to 1,000 characters, global attributes and info are capped at 25 entries (with *_omitted counts), and long values are clipped to 200 characters. schema.data_vars/schema.attrs are omitted as duplicates of variables/attributes. Past ~30k characters the summary sheds, in order and only as far as needed: global attributes, coordinate attributes, variable attributes other than units, variable shape/dtype, and finally per-variable details; the note names what was shed. Every variable name is always listed. detail="full" returns the complete record. Both are compact JSON.

An unknown id adds suggestions: visible datasources whose id or name differs from the requested one by a typo (at most one character edit per 7 characters, up to 3, with the differing words still similar), or extends a request of two or more words. An id that merely shares generic words such as oceanum_wave_..._era5, or a single word such as wave, is never suggested.

Parameter

Type

Description

datasource_id

string

Datasource ID

detail

string

summary (default) or full

stage_query

Dry-run a query on the Datamesh gateway: reports the result size, container type, and domain length without downloading any data, echoes the canonical query, and recommends the next step (inline query vs export vs narrowing). The inline recommendation counts records as well as bytes: a result with more records than OCEANUM_MCP_MAX_INLINE_ROWS would come back from query_data as a preview, so it is steered to resampling, aggregation or export_query instead. Accepts the same query parameters as query_data.

query_data

Query a datasource with filters and return small results inline as coordinate-attributed JSON records with explicit truncated/lazy flags. The query is staged first: gridded results above the inline limit are summarized lazily (structure only); tabular results above the limit, and any result above 1 GB, are refused with the staged size and alternatives (the 1 GB refusal also lists each variable's dims). The exception is limit combined with time_resolution or aggregate_operations: the limited slice may be small, so it is still opened lazily. Library warnings (e.g. the 2,000,000-row cap on tabular queries) are included in the response.

Parameter

Type

Description

datasource_id

string

Datasource to query

variables

list[string]

Variables to select

time_start

string

ISO 8601 start of a time range (open-ended if omitted)

time_end

string

ISO 8601 end of a time range (open-ended if omitted)

times

list[string]

Discrete times (series selection); excludes time_start/time_end

time_resolution

string

Server-side temporal downsampling (pandas frequency, e.g. 1h, 1D, 30D; not MS/ME/QS/YS or finer than 1 minute)

time_resample

string

Resampling method for time_resolution: mean, nearest, linear

bbox

list[float]

Bounding box [xmin, ymin, xmax, ymax]

geofilter_feature

object

GeoJSON Feature (Point, MultiPoint, or Polygon) for selection

geofilter_interp

string

Interpolation for feature selection: nearest or linear

geofilter_resolution

float

Max spatial resolution for downsampling, in CRS units

level_min

float

Minimum vertical level

level_max

float

Maximum vertical level

levels

list[float]

Discrete vertical levels (series selection)

level_interp

string

Interpolation for level series: nearest or linear

coord_filters

list[object]

Coordinate selections: [{"coord": "name", "values": [...]}]

crs

string/int

CRS for filter coordinates and returned data

aggregate_operations

list[string]

Aggregation ops: mean, min, max, std, sum

aggregate_spatial

bool

Aggregate over spatial dims (default true)

aggregate_temporal

bool

Aggregate over temporal dims (default true)

limit

int

Keep the last N records (see below)

limit keeps the last N records (Datamesh semantics: the last N steps along time/ensemble), with the same meaning in stage_query, query_data, and export_query. Combined with time_resolution or aggregate_operations it is applied by this server after resampling/aggregation instead of being sent to Datamesh (which would apply it to the native records first), so stage_query reports the unlimited size as an upper bound. Hosted export_query cannot apply it to a gateway download and refuses that combination: drop limit or narrow the time range.

export_query

Export the full result of a query — the data-handle path for results too large to return inline. Behaviour depends on transport:

  • Local (stdio): writes the result to the local file path (required) and returns that path. Gridded datasets stream lazily to NetCDF; tabular results write Parquet or CSV.

  • Hosted (http/sse): returns a time-limited, self-authenticating gateway download_url (choose format; path is ignored). Fetch it out-of-band. When the response includes expires_at or max_uses (gateways with scoped links), fetch it before expires_at and at most max_uses times. Results above 10 GB (for CSV, the estimated text size, about 3x the staged size) are refused (narrow the query); above 2 GB the link is returned with a large-download warning.

export_query sizes the result itself, whether or not stage_query was called, and refuses before anything is exported. Results above the export cap are refused outright: the cap limits the transfer, so splitting the request into parts is not a way round it. An export that writes more than 1 GB in the chosen format (CSV text is estimated at about 3x the staged size; locally, a dataset written as CSV/Parquet is sized as the flattened table, and a limited one on its limited slice) is refused unless confirm_size_bytes equals that size. On hosted servers a value within 5% is accepted, because the download stage is sized separately from stage_query's stage. The refusal reports the exact value as export_size_bytes. The agent should pass it only after the user has agreed. The server cannot see whether the user was asked, so the check is advisory: it forces an explicit, size-aware step for each large export.

Accepts the same query parameters as query_data plus:

Parameter

Type

Description

path

string

Destination file path (parent directories are created)

format

string

netcdf (datasets), parquet or csv (tabular); sensible default

overwrite

bool

Overwrite an existing file (default false)

confirm_size_bytes

int

Bytes (in the chosen format) the user agreed to export; required above 1 GB; exact match (within 5% on hosted)

load_datasource

Summarize an entire datasource. Gridded datasources are opened lazily (no data download); tabular datasources are downloaded only if under the inline size limit.

Parameter

Type

Description

datasource_id

string

Datasource to load

update_metadata

Update metadata on an existing datasource. Only provided fields are changed. Disabled when the server runs with OCEANUM_MCP_READ_ONLY set.

Parameter

Type

Description

datasource_id

string

Datasource to update

name

string

New name

description

string

New description

tags

list[string]

New tags

labels

list[string]

New labels

info

object

Additional metadata object

details

string

URL for datasource details

Storage Tools

list_files

List files and directories in Oceanum cloud storage.

Parameter

Type

Description

path

string

Directory path to list (default: "/")

recursive

bool

List subdirectories recursively

file_exists

Check if a file or directory exists in storage.

Parameter

Type

Description

path

string

Path to check

read_file

Read the contents of a text file from storage.

Parameter

Type

Description

path

string

Path to the file

write_file

Write text content to a file in storage.

Parameter

Type

Description

path

string

Destination path

content

string

Text content to write

delete_file

Delete a file or directory from storage.

Parameter

Type

Description

path

string

Path to delete

recursive

bool

Delete directory contents recursively

file_info

Get metadata about a file or directory.

Parameter

Type

Description

path

string

Path to inspect

Example Workflows

Discover wave data in the Pacific:

  1. search_catalog(search="wave", bbox=[120, -50, 180, 10])

  2. get_datasource_info(datasource_id="some-wave-dataset")

  3. stage_query(datasource_id="some-wave-dataset", variables=["Hs", "Tp"], time_start="2024-01-01", time_end="2024-01-31") to check the result size

  4. query_data(...) with the same parameters if small, or export_query(..., path="waves.nc") if large

Shrink a 40-year hourly time series to something inline-sized:

  1. stage_query(datasource_id="hindcast", variables=["Hs"], time_start="1984-01-01", time_end="2024-01-01") — too large

  2. query_data(..., time_resolution="30D", time_resample="mean") — roughly monthly means, small enough to return inline (calendar aliases such as "1MS" are refused until a Datamesh engine fix ships: the engine currently reads "1MS" as 1 millisecond)

Browse and read files in cloud storage:

  1. list_files(path="/") to see top-level contents

  2. list_files(path="/my-project", recursive=True) to drill down

  3. read_file(path="/my-project/config.json") to read a file

Get a quick summary of a dataset:

  1. get_datasource_info(datasource_id="my-dataset") to see variables and time range

  2. query_data(datasource_id="my-dataset", limit=10) to preview the data

Available Tools

13 tools
datamesh_export_queryDatamesh Export QueryA
Idempotent

Export the FULL result of a query — the data never enters the conversation.

Behavior depends on how the server is running:

  • Hosted (http/sse): returns a time-limited, self-authenticating gateway download_url (choose format via format); path is ignored. Fetch the URL out-of-band — it needs no credential, so treat it as a secret. When the response includes expires_at or max_uses, fetch it before expires_at and at most max_uses times. Refused above the hosted export cap, and for limit combined with time_resolution/aggregate_operations.

  • Local (stdio): writes the result to the local file path (required) and returns that path. Gridded datasets stream to NetCDF; tabular results write Parquet or CSV, as do datasets small enough to flatten into a table (e.g. point time series). Refused up front if the result exceeds the local export cap or the destination's free disk space. With limit plus time_resolution/aggregate_operations, the last N resampled steps are written.

The size is checked before anything is exported, whether or not stage_query was called. An export writing more than 1 GB in the chosen format (CSV text is about 3x; locally, a dataset written as CSV/Parquet is sized as the flattened table, and a limited one on its limited slice) is refused unless confirm_size_bytes equals that size (on hosted, within 5%, since the download stage is sized separately): ask the user first. The refusal states the exact value. The server cannot see whether the user was asked, so this is advisory: it forces an explicit, size-aware step. The export caps limit the transfer, not the size of each file: never split a refused request into parts to get under them.

A variable given as the exact CF standard_name of exactly one of the datasource's variables (e.g. "sea_surface_wave_significant_height" for "hs") is resolved to that variable; the response then includes resolved_variables ({requested: used}) and echoes the resolved names.

NameRequiredDescriptionDefault
crsNoCRS for filter coordinates and returned data (EPSG code or CRS string).
bboxNoBounding box [xmin, ymin, xmax, ymax] in WGS84 (or crs units if crs is set).
pathNoLocal (stdio) destination file path (required on stdio; parent directories are created; confined to OCEANUM_MCP_EXPORT_DIR when set). Ignored on hosted servers, which return a download URL.
limitNoKeep only the last N records (Datamesh semantics: the last N steps along time/ensemble). Combined with time_resolution or aggregate_operations it is applied AFTER resampling/aggregation (by this server, not sent to Datamesh), so stage_query sizes the unlimited result as an upper bound; hosted export_query refuses that combination.
timesNoDiscrete times to select (series selection). Mutually exclusive with time_start/time_end.
formatNoOutput format: netcdf (datasets), parquet or csv (tabular, or datasets small enough to flatten into a table such as point time series). Defaults by container: dataset -> netcdf, tabular -> parquet.
levelsNoDiscrete vertical levels to select (series selection). Mutually exclusive with level_min/level_max.
time_endNoISO 8601 end of a time range. Open-ended if omitted.
level_maxNoMaximum vertical level of a range.
level_minNoMinimum vertical level of a range.
overwriteNoOverwrite an existing local file (default false). Local export only.
variablesNoList of variable names to select (e.g. ["temperature", "salinity"]).
time_startNoISO 8601 start of a time range (e.g. "2023-01-01T00:00:00Z"). Open-ended if omitted.
level_interpNoInterpolation for level series selection: nearest or linear.
coord_filtersNoAdditional coordinate selections, e.g. [{"coord": "station", "values": ["A1", "B2"]}].
datasource_idYesThe datasource to query.
time_resampleNoResampling method when time_resolution is set: mean, nearest, or linear.
time_resolutionNoDownsample a time range server-side to this resolution (pandas frequency string, e.g. "1h", "6h", "1D", "7D", or "30D" for roughly monthly). Drastically shrinks long time series. Monthly/quarterly/yearly calendar aliases (MS, ME, QS, YS) are not supported until a Datamesh engine fix ships: use "30D", "90D" or "365D". Finer than 1 minute is refused.
geofilter_interpNoInterpolation for feature selection: nearest or linear (default linear).
aggregate_spatialNoAggregate over spatial dimensions (default true).
geofilter_featureNoGeoJSON Feature object (Point, MultiPoint, or Polygon geometry) for spatial selection/interpolation. Mutually exclusive with bbox.
aggregate_temporalNoAggregate over the temporal dimension (default true).
confirm_size_bytesNoRequired for results above 1 GB: the size in bytes, in the chosen format, the user has agreed to export (stage_query's size_bytes for the default format, or export_size_bytes from a refusal). Must match exactly (within 5% on hosted servers). Ignored for exports of 1 GB or less.
aggregate_operationsNoAggregations to apply after filtering: mean, min, max, std, sum.
geofilter_resolutionNoMaximum spatial resolution for downsampling, in CRS units.

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Given annotations only declare readOnlyHint=false, openWorldHint=true, idempotentHint=true, and destructiveHint=false, the description adds substantial behavioral context: hosted download URL secrecy, expiry/max_uses semantics, local file writing with overwrite behavior, size-check-before-export, and the advisory nature of confirm_size_bytes. It also warns against splitting refused requests. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and mode-dependent behavior, and every paragraph carries operational weight (size caps, secret handling, refusal conditions). It is however quite long and dense for a tool description; a bullet or table structure for hosted vs local differences could improve scanability without losing content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 25 parameters, an output schema (so return values need not be described), and the complexity of dual hosted/local behavior, the description covers all critical decision points: environment-dependent behavior, size confirmation, variable resolution, and refusal conditions. Nothing an agent needs in order to call it correctly or handle its response appears missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With schema description coverage at 100%, the baseline would be 3, but the description adds cross-parameter semantics not captured per-parameter in the schema: hosted vs local effects on `path` and `format`, the interaction of `limit` with `time_resolution`/`aggregate_operations`, and CF standard_name resolution for `variables`. These are meaningful additions beyond the schema, though many individual parameters (bbox, times, levels) are still only explained in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource: 'Export the FULL result of a query' and immediately differentiates itself by stating 'the data never enters the conversation'. This clearly distinguishes it from sibling tools like datamesh_query_data that presumably return data in-conversation. An agent can tell what this tool does without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives rich context on when behavior changes (hosted vs local), when `path` is required or ignored, and when `confirm_size_bytes` is needed, including 'ask the user first'. It provides explicit refusal conditions (hosted cap, limit combined with resampling) but does not explicitly name an alternative sibling (e.g., datamesh_query_data or stage_query) for routine retrieval, leaving the when-to-use-this-vs-that inference to the reader.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

datamesh_get_datasource_infoDatamesh Get Datasource InfoA
Read-only

Get the metadata for one datasource: coverage, coordinates and variables.

The default view keeps every field of the full record but reduces each variable and coordinate to its dims, shape, dtype, units, long_name and standard_name, clips the description and long attribute values, caps global attributes. On very large records it sheds attributes and then per-variable details (the note says which), but every variable name is always listed.

NameRequiredDescriptionDefault
detailNo"summary" (default) returns the compact view described above. "full" returns the complete record, including every attribute and variable; it can be very large.summary
datasource_idYesThe unique ID of the datasource.

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With readOnlyHint and openWorldHint already provided, the description adds significant behavioral context beyond annotations. It explains that the default view reduces fields, clips long values, caps global attributes, and may shed attributes on very large records while always listing every variable name.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded in the first sentence, and the second paragraph is dense but every clause explains useful truncation behavior. There is no redundant or filler text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has an output schema and annotations covering safety and openness, and the description supplies the missing behavioral details about truncation and large-record handling. An agent has enough information to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description nonetheless adds meaning about what the default/summary view actually returns, especially truncation and field reduction, beyond the enum descriptions in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: getting metadata for one datasource, including coverage, coordinates and variables. It is clear enough to distinguish this from sibling query/load/search tools, but it does not explicitly name or contrast those alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the purpose: use this to retrieve metadata for a known datasource. The description does not explicitly say when to choose this over siblings such as datamesh_search_catalog or datamesh_query_data, nor does it state prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

datamesh_load_datasourceDatamesh Load DatasourceA
Read-only

Summarize an entire datasource.

Gridded datasources are opened lazily (no data download). Tabular datasources are downloaded only if under the inline size limit; use query_data with filters to retrieve larger ones.

NameRequiredDescriptionDefault
datasource_idYesThe datasource to load.

Output Schema

NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds real behavioral context beyond the readOnlyHint/openWorldHint annotations: gridded sources open lazily with no data download, tabular sources download only under an inline size limit, and oversize tabular data must go through query_data. It does not quantify the limit or describe failure behavior when a tabular source is too large and no query is issued.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with the core action, then the type-specific behavior and the fallback path. No filler or restatement of the name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need not be explained, and the description covers both datasource classes and the oversize fallback. The only remaining gap is the unquantified size limit and what a caller observes when a tabular source is skipped.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% for the single datasource_id parameter, so the baseline is 3. The description adds no syntax, format, or ID-provenance detail beyond what the schema already documents.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ("Summarize an entire datasource") and further splits behavior by datasource type (gridded vs tabular), which lets an agent scope it precisely. It names the sibling query_data as the alternative for large tabular data, though it does not contrast with other nearby siblings like datamesh_get_datasource_info.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit context: use this for whole-datasource summarization, and switch to query_data with filters when a tabular datasource exceeds the inline size limit. No explicit "do not use when" clause for gridded/tabular edge cases, but the routing condition is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

datamesh_query_dataDatamesh Query DataA
Read-only

Query a datasource and return small results inline.

The query is staged first; results larger than the inline limit are not downloaded (datasets are summarized lazily, tabular queries are refused with alternatives), and results above 1 GB are refused with narrowing advice and each variable's dims, unless limit is combined with time_resolution/aggregate_operations (the limited slice may be small, so a dataset is then opened lazily). Use stage_query to size a query before calling this.

Inline values are a preview when preview is true (returned of total records): never compute statistics from a preview; use aggregate_operations or time_resolution instead.

limit keeps the last N records (Datamesh semantics: the last N steps along time/ensemble). Combined with time_resolution or aggregate_operations, limit is applied by this server AFTER resampling/aggregation (to the last N resampled steps, or the last N rows of a table) rather than sent to Datamesh. A limited result is a subset of the requested range, so it is flagged as a preview, with a limit_note.

A variable given as the exact CF standard_name of exactly one of the datasource's variables (e.g. "sea_surface_wave_significant_height" for "hs") is resolved to that variable; the response then includes resolved_variables ({requested: used}) and echoes the resolved names.

NameRequiredDescriptionDefault
crsNoCRS for filter coordinates and returned data (EPSG code or CRS string).
bboxNoBounding box [xmin, ymin, xmax, ymax] in WGS84 (or crs units if crs is set).
limitNoKeep only the last N records (Datamesh semantics: the last N steps along time/ensemble). Combined with time_resolution or aggregate_operations it is applied AFTER resampling/aggregation (by this server, not sent to Datamesh), so stage_query sizes the unlimited result as an upper bound; hosted export_query refuses that combination.
timesNoDiscrete times to select (series selection). Mutually exclusive with time_start/time_end.
levelsNoDiscrete vertical levels to select (series selection). Mutually exclusive with level_min/level_max.
time_endNoISO 8601 end of a time range. Open-ended if omitted.
level_maxNoMaximum vertical level of a range.
level_minNoMinimum vertical level of a range.
variablesNoList of variable names to select (e.g. ["temperature", "salinity"]).
time_startNoISO 8601 start of a time range (e.g. "2023-01-01T00:00:00Z"). Open-ended if omitted.
level_interpNoInterpolation for level series selection: nearest or linear.
coord_filtersNoAdditional coordinate selections, e.g. [{"coord": "station", "values": ["A1", "B2"]}].
datasource_idYesThe datasource to query.
time_resampleNoResampling method when time_resolution is set: mean, nearest, or linear.
time_resolutionNoDownsample a time range server-side to this resolution (pandas frequency string, e.g. "1h", "6h", "1D", "7D", or "30D" for roughly monthly). Drastically shrinks long time series. Monthly/quarterly/yearly calendar aliases (MS, ME, QS, YS) are not supported until a Datamesh engine fix ships: use "30D", "90D" or "365D". Finer than 1 minute is refused.
geofilter_interpNoInterpolation for feature selection: nearest or linear (default linear).
aggregate_spatialNoAggregate over spatial dimensions (default true).
geofilter_featureNoGeoJSON Feature object (Point, MultiPoint, or Polygon geometry) for spatial selection/interpolation. Mutually exclusive with bbox.
aggregate_temporalNoAggregate over the temporal dimension (default true).
aggregate_operationsNoAggregations to apply after filtering: mean, min, max, std, sum.
geofilter_resolutionNoMaximum spatial resolution for downsampling, in CRS units.

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite annotations already signaling a read-only, open-world operation, the description adds extensive behavioral detail: staging happens first, oversized results are refused with narrowing advice, tabular queries may be refused, limited results are flagged as previews, and variable resolution is reported via resolved_variables. None of this contradicts the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The most important constraints — small inline results, staging, size refusals, and preview warnings — are front-loaded. The description is long but largely earns its length for a 21-parameter tool, though some limit and resampling details duplicate the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complex schema, annotations, and available output schema, the description covers the critical operational behavior: sizing, refusal conditions, preview limitations, and variable resolution. It could be more complete by explicitly directing large-result use cases to export_query, but nothing essential for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 21 parameters thoroughly, including limit and time_resolution interactions. The description adds meaningful semantics for CF standard_name variable resolution and preview behavior, but much of its parameter discussion repeats what is already in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource — query a datasource and return small results inline — and clarifies the inline-size scope. It also mentions stage_query for sizing, but does not explicitly distinguish this tool's purpose from the sibling export_query, leaving some sibling selection ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear operational context: use stage_query before calling, previews should not be used for statistics, and aggregate_operations or time_resolution should be used instead. It also explains when large results are refused, but it does not explicitly name export_query as the alternative for larger exports, leaving one key routing decision implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

datamesh_search_catalogDatamesh Search CatalogA
Read-only

Search the Oceanum Datamesh catalog for datasets.

Catalog search only covers datasources accessible to the credentials used for this request; a datasource missing from the results either does not exist or is not accessible with these credentials, so do not report it as nonexistent.

NameRequiredDescriptionDefault
bboxNoBounding box as [xmin, ymin, xmax, ymax] in WGS84 coordinates.
limitNoMaximum number of datasources to return (default 20, minimum 1).
detailNo"summary" (default) returns id, name, a short description, time range, bounds, and variable names when known. "full" returns each datasource's complete catalog record; prefer get_datasource_info for one datasource's details.summary
searchNoText search string to filter datasources by name, description, or tags.
time_endNoISO 8601 datetime for end of time range filter (e.g. "2023-12-31").
time_startNoISO 8601 datetime for start of time range filter (e.g. "2023-01-01").

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds real behavioral context beyond that: results are credential-scoped, and a datasource absent from results may simply be inaccessible rather than nonexistent—an important constraint for interpreting output.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, purpose front-loaded, no wasted preamble. The second sentence is slightly redundant—'either does not exist or is not accessible with these credentials' largely restates 'do not report it as nonexistent'—but the constraint is worth stating once.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return-value detail is unnecessary, and the description covers the key interpretive caveat for a search tool. It could go further by noting pagination/limit interaction or pointing to get_datasource_info for single-record lookups, but nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every parameter (bbox, limit, detail, search, time_start, time_end) is already documented in the schema. The description contributes no additional parameter meaning, which is the expected baseline when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Search the Oceanum Datamesh catalog for datasets'), making the operation unambiguous. It does not, however, differentiate itself from siblings like datamesh_get_datasource_info; that routing distinction only appears in the schema's 'detail' parameter, not in the description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The accessibility caveat ('catalog search only covers datasources accessible to the credentials used for this request') is genuinely useful usage guidance. But the description never says when to prefer this tool over siblings such as get_datasource_info for a single dataset, or when a text/bbox/time filter is the right approach—usage is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

datamesh_stage_queryDatamesh Stage QueryA
Read-only

Dry-run a query: report the result size WITHOUT downloading any data.

Always stage before retrieving data you have not sized. The response says whether the result is small enough for query_data to return inline, and echoes the canonical query. With limit plus time_resolution or aggregate_operations the reported size is that of the unlimited result (limit is applied after resampling), so it is an upper bound.

A variable given as the exact CF standard_name of exactly one of the datasource's variables (e.g. "sea_surface_wave_significant_height" for "hs") is resolved to that variable; the response then includes resolved_variables ({requested: used}) and echoes the resolved names.

NameRequiredDescriptionDefault
crsNoCRS for filter coordinates and returned data (EPSG code or CRS string).
bboxNoBounding box [xmin, ymin, xmax, ymax] in WGS84 (or crs units if crs is set).
limitNoKeep only the last N records (Datamesh semantics: the last N steps along time/ensemble). Combined with time_resolution or aggregate_operations it is applied AFTER resampling/aggregation (by this server, not sent to Datamesh), so stage_query sizes the unlimited result as an upper bound; hosted export_query refuses that combination.
timesNoDiscrete times to select (series selection). Mutually exclusive with time_start/time_end.
levelsNoDiscrete vertical levels to select (series selection). Mutually exclusive with level_min/level_max.
time_endNoISO 8601 end of a time range. Open-ended if omitted.
level_maxNoMaximum vertical level of a range.
level_minNoMinimum vertical level of a range.
variablesNoList of variable names to select (e.g. ["temperature", "salinity"]).
time_startNoISO 8601 start of a time range (e.g. "2023-01-01T00:00:00Z"). Open-ended if omitted.
level_interpNoInterpolation for level series selection: nearest or linear.
coord_filtersNoAdditional coordinate selections, e.g. [{"coord": "station", "values": ["A1", "B2"]}].
datasource_idYesThe datasource to query.
time_resampleNoResampling method when time_resolution is set: mean, nearest, or linear.
time_resolutionNoDownsample a time range server-side to this resolution (pandas frequency string, e.g. "1h", "6h", "1D", "7D", or "30D" for roughly monthly). Drastically shrinks long time series. Monthly/quarterly/yearly calendar aliases (MS, ME, QS, YS) are not supported until a Datamesh engine fix ships: use "30D", "90D" or "365D". Finer than 1 minute is refused.
geofilter_interpNoInterpolation for feature selection: nearest or linear (default linear).
aggregate_spatialNoAggregate over spatial dimensions (default true).
geofilter_featureNoGeoJSON Feature object (Point, MultiPoint, or Polygon geometry) for spatial selection/interpolation. Mutually exclusive with bbox.
aggregate_temporalNoAggregate over the temporal dimension (default true).
aggregate_operationsNoAggregations to apply after filtering: mean, min, max, std, sum.
geofilter_resolutionNoMaximum spatial resolution for downsampling, in CRS units.

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint/openWorldHint, so the safety bar is already met; the description still earns credit by disclosing non-obvious behavior: no data is downloaded, limit+resampling makes the size an upper bound, and CF standard_name variables get resolved with resolved_variables echoed back. It omits cost/latency or rate-limit context for what is effectively a repeated exploratory call.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core dry-run semantics, then caveats in descending priority; every sentence carries information. It is a bit long and partially restates the limit/time_resolution interaction already present in the limit parameter description, which is mild redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 21 parameters, an output schema, and annotations, the description covers what structured fields cannot: that nothing is downloaded, how the size verdict relates to query_data, and the upper-bound caveat. Nothing essential for correct invocation is missing, though staging cost and whether the echoed canonical query is reusable could be stated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3 and the schema already documents all 21 parameters. The description adds genuine meaning beyond it by specifying the CF standard_name resolution rule for variables and how the response echoes resolved names, a behavior not stated in the variables schema field.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource pairing ("Dry-run a query: report the result size WITHOUT downloading any data") that immediately distinguishes it from siblings like datamesh_query_data and datamesh_export_query. An agent can tell exactly what this tool does without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit usage rule ("Always stage before retrieving data you have not sized") and routes the agent by naming query_data as the consumer of the size verdict. It does not explicitly cover the export path or state the inverse exclusion ("do not use this to fetch data"), so routing is clear but not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

datamesh_update_metadataDatamesh Update MetadataA
DestructiveIdempotent

Update metadata properties on an existing datasource.

Only the provided fields will be updated; others remain unchanged. Not available when the server runs with OCEANUM_MCP_READ_ONLY set.

NameRequiredDescriptionDefault
infoNoAdditional metadata as a JSON object.
nameNoNew human-readable name (max 128 chars).
tagsNoNew list of keyword tags.
labelsNoNew list of metadata labels.
detailsNoURL with further details about the datasource.
descriptionNoNew description (max 1500 chars).
datasource_idYesThe datasource to update.

Output Schema

NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=true, and openWorldHint=true. The description adds genuinely new behavioral context: only supplied fields are modified and the rest remain untouched, plus the read-only-mode availability gate. It does not explain what makes the operation destructive (e.g. overwriting existing field values), which is the one remaining gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core action, then the partial-update rule, then the availability gate. No filler and every sentence carries distinct information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described. For a mutation tool with full schema coverage and rich annotations, the description covers scope, partial-update semantics, and the read-only limitation. Only the destructive consequence is left implicit for the agent to infer.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all seven parameters including datasource_id, info, name, tags, labels, details, and description are already documented with formats and length limits in the schema. The description adds nothing parameter-specific here, which is the expected baseline when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource ("Update metadata properties on an existing datasource"), which is unambiguous and clearly distinct from the read-oriented siblings (search_catalog, get_datasource_info, query_data). It stops short of naming any sibling, but since no other tool in the set performs updates, differentiation is implicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a clear when-not condition ("Not available when the server runs with OCEANUM_MCP_READ_ONLY set") and clarifies the partial-update contract, so an agent knows changes are additive per-field. No alternative tool is named, but none exists in this family for metadata mutation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

storage_delete_fileStorage Delete FileC

Delete a file or directory from Oceanum storage.

NameRequiredDescriptionDefault
pathYesPath to delete.
recursiveNoFor directories, delete contents recursively.

Output Schema

NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden, yet it says nothing about permanence, whether directories must be empty, permission requirements, or whether the operation can be undone. For a destructive delete tool with zero annotation coverage, this is a substantial gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single efficient sentence with the resource front-loaded and no padding. It is well-sized, though its brevity is partly under-specification rather than tight information density.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, but a destructive tool with no annotations and no description of irreversibility or failure modes leaves the agent without critical context for safe invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both 'path' and 'recursive' are already documented in the schema. The description adds no syntax, format, or behavioral nuance beyond what the schema states, which is the baseline expectation when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (delete) and resource (file or directory) scoped to Oceanum storage, which is enough to separate it from storage_write_file, storage_read_file, and storage_list_files. It does not explicitly name a sibling or contrast with one, so it falls short of the top score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description offers no guidance on when to use this tool versus alternatives, no prerequisites, and no mention that deletion is likely irreversible. The only usage-adjacent hint lives in the schema's 'recursive' field, not the description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

storage_file_existsStorage File ExistsB

Check if a file or directory exists in Oceanum storage.

NameRequiredDescriptionDefault
pathYesPath to check.

Output Schema

NameRequiredDescription
resultYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden. 'Check if ... exists' strongly implies a side-effect-free boolean query, and the existence of an output schema means return format need not be explained. However, it says nothing explicit about read-only semantics, permissions, or behavior for non-existent/invalid paths.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight sentence with the verb and scope front-loaded and zero wasted words. Nothing to trim and nothing important buried.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter existence check with a fully documented schema and an output schema covering the return value, the description is nearly sufficient. The only missing piece is any hint about path conventions or behavior for special cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and there is a single required parameter, so baseline is 3. The description adds no extra meaning about path format (absolute vs relative, bucket prefixes, directory conventions) beyond what the schema states.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource ('check if a file or directory exists') scoped to 'Oceanum storage', which is unambiguous and distinct from siblings like storage_read_file or storage_list_files. It doesn't explicitly name those siblings, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this versus alternatives such as storage_file_info or storage_list_files, nor any note about prerequisites or typical contexts. The agent must infer usage entirely from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

storage_file_infoStorage File InfoB

Get metadata about a file or directory in Oceanum storage.

NameRequiredDescriptionDefault
pathYesPath to inspect.

Output Schema

NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It adds only that the target may be a file or a directory; it does not say whether a missing path errors or returns empty, whether it follows symlinks, or what permissions are required for Oceanum storage. For a bare read tool this leaves notable gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with zero filler. The core verb and resource lead the sentence, and nothing is repeated from the title or restated redundantly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple: one required path parameter and an output schema that already documents the returned metadata fields, so the description need not explain return values. It is largely complete for such a low-complexity read operation, though it omits error behavior on nonexistent paths.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There is a single parameter with 100% schema description coverage ('Path to inspect.'), so the schema already documents it. The description adds no format examples, accepted path prefixes, or relative-vs-absolute semantics beyond what the schema provides, matching the baseline of 3 when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: 'Get metadata about a file or directory in Oceanum storage.' An agent can distinguish it from storage_read_file, storage_list_files and storage_write_file because it returns metadata rather than content or listings. It stops short of explicitly naming siblings or the info-only scope, so it is clear but not fully differentiated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no when-to-use guidance: nothing says when to prefer this over storage_file_exists (existence check) or storage_list_files (enumerate a directory). Usage is only implied by the tool's name and purpose. No prerequisites, exclusions, or alternatives are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

storage_list_filesStorage List FilesC

List files and directories in Oceanum cloud storage.

NameRequiredDescriptionDefault
pathNoDirectory path to list (default: root "/")./
recursiveNoWhether to list subdirectories recursively.

Output Schema

NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. 'List' implies a read-only operation, but the description says nothing about permissions, authentication, non-recursive default behavior, or rate/pagination limits, leaving behavioral traits to inference.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler or redundancy. It is efficient, though its brevity edges toward under-specification rather than maximal information density.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple (two optional params) and has an output schema, so return values need not be described. However, with no annotations the agent gets no explicit confirmation of the read-only nature or permission requirements, leaving a small but real gap for an otherwise minimal definition.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both 'path' and 'recursive' are fully documented in the schema, making 3 the baseline. The description adds no syntax or format detail (e.g., what a recursive listing returns) beyond what the schema already conveys.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List') and resource ('files and directories in Oceanum cloud storage'), which an agent can easily distinguish from sibling reads like storage_file_info or storage_read_file. It stops short of explicitly naming sibling alternatives, so it is clear but not differentiated at the highest level.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use or when-not-to-use guidance, and no alternatives are named. The listing verb implies a browse/explore use case, but nothing tells the agent when to prefer this over storage_file_info or datamesh_search_catalog.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

storage_read_fileStorage Read FileB

Read the contents of a text file from Oceanum storage.

NameRequiredDescriptionDefault
pathYesPath to the file.

Output Schema

NameRequiredDescription
resultYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden; 'Read' implies a non-mutating operation, and the 'text file' qualifier usefully signals that binary content may be unsupported. However, it says nothing about missing-file behavior, permissions, encoding, or size limits, which are real risks for a file fetch.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight sentence that front-loads the action and resource with zero filler. Correctly sized for a one-parameter tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple, the sole parameter is documented in the schema, and an output schema exists so return values need not be described. Only error/edge-case behavior (missing file, binary content) is left unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter exists and schema description coverage is 100%, so the schema already documents 'path' fully. The description adds no path syntax, relative-vs-absolute, or format detail beyond what the schema provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (read) and resource (contents of a text file) scoped to Oceanum storage, which cleanly distinguishes it from write/delete/list siblings. It stops short of naming an alternative or explicitly contrasting with storage_list_files or storage_file_info.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use guidance, no prerequisites, and no reference to alternatives such as storage_file_info (metadata) versus this tool (contents). Usage is only inferable from the verb.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

storage_write_fileStorage Write FileA

Write text content to a file in Oceanum storage.

Creates the file if it doesn't exist, overwrites if it does.

NameRequiredDescriptionDefault
pathYesDestination path in Oceanum storage.
contentYesText content to write.

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It does disclose the most consequential behavior — silent overwrite of existing files — which is genuinely useful for data-loss avoidance. However it says nothing about required permissions, content encoding/type handling, size limits, or whether the write is atomic, leaving meaningful gaps for a mutation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with zero filler. The core action is front-loaded and the create-or-overwrite caveat immediately follows, so nothing has to be hunted for.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the schema fully covers both parameters. For a simple two-parameter write, the description covers the essential behavioral surprise (overwrite). Only minor gaps remain — no auth/permission note, which matters for a mutation tool with no annotations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and both parameters are documented there, so the baseline is 3. The description adds no syntax, path-format, or content-format detail beyond what 'path' and 'content' already convey in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Write text content to a file in Oceanum storage.' The verb contrasts naturally with siblings like storage_read_file and storage_delete_file, though it never names a sibling explicitly. An agent can identify the operation without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the operation itself (write/overwrite a file), but there is no statement of when to prefer this over storage_delete_file or storage_file_exists, nor any prerequisite guidance. The 'creates if absent, overwrites if present' line does hint at idempotent upsert semantics, which is the closest thing to usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv0.6.0
    • Changeddatamesh_export_query1 field changed
      • addedInput schema / properties / confirm_size_bytes
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Required for results above 1 GB: the size in bytes, in the chosen format, the user has agreed to export (stage_query's size_bytes for the default format, or export_size_bytes from a refusal). Must match exactly (within 5% on hosted servers). Ignored for exports of 1 GB or less."
        +}
    • Changeddatamesh_get_datasource_info1 field changed
      • changedInput schema / properties / detail / description
        Previous value: -"\"summary\" (default) returns the bounded view described above. \"full\" returns the complete record, including every attribute; it can be very large."New value: +"\"summary\" (default) returns the compact view described above. \"full\" returns the complete record, including every attribute and variable; it can be very large."
  2. 13 tool updatesv0.5.2
    • First observeddatamesh_export_query
    • First observeddatamesh_get_datasource_info
    • First observeddatamesh_load_datasource
    • First observeddatamesh_query_data
    • First observeddatamesh_search_catalog
    • First observeddatamesh_stage_query
    • First observeddatamesh_update_metadata
    • First observedstorage_delete_file
    • First observedstorage_file_exists
    • First observedstorage_file_info
    • First observedstorage_list_files
    • First observedstorage_read_file
    • First observedstorage_write_file

TDQS

A3.7/5.0

Scored across 13 tools

Disambiguation4/5

The data-access tools are clearly tiered by role: search_catalog finds datasources, get_datasource_info/stage_query inspect metadata and size, query_data returns inline previews, and export_query offloads large results. The only real friction is load_datasource ('summarize an entire datasource') versus get_datasource_info ('metadata for one datasource'), which can look interchangeable at a glance, plus the storage_file_exists/storage_file_info pair.

Naming Consistency4/5

Every name is snake_case with a clear domain prefix (datamesh_/storage_) and most follow verb_noun (query_data, export_query, stage_query, list_files, read_file, delete_file). The deviations are minor: load_datasource rather than get_datasource, and the noun-first storage_file_exists/storage_file_info.

Tool Count5/5

Thirteen tools split cleanly into two domains (7 datamesh, 6 storage), each earning its place in the query/export workflow. Nothing feels redundant or padded at this size.

Completeness4/5

The data pipeline is covered end-to-end (discover → inspect → stage → query → export → update metadata) and storage has full create/read/list/delete/stat coverage. Gaps remain: no datasource creation or deletion, no storage copy/move, and metadata updates are the only write path for the catalog.

Maintenance

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Access oceanographic and environmental data from 63+ ERDDAP servers worldwide through natural language queries. Search datasets, retrieve metadata, and download scientific data for climate research, marine biology, and coastal management.
    18
    -
  • A
    license
    B
    quality
    B
    maintenance
    Provides tools to search and execute Code Ocean capsules and pipelines while managing platform data assets. It enables users to interact with Code Ocean's computational resources and scientific workflows directly through natural language interfaces.
    26
    270 PyPI
    5
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to interact with the OSDU® data platform through Model Context Protocol, providing tools for search, storage, schema management, and dataset operations.
    2
    Apache 2.0