You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Refactor DatasetCatalog.load() to source from MCP instead of walking STAC locally
Status — parked / backlog
Design captured below. Will be picked up when one of the forcing functions triggers, not before. The "MCP vs. direct STAC" question for DatasetCatalog.load() has been resolved twice already (#167, #171); the current production answer (direct-fetch + #192 inline-forwarding + #178's collection_url escape hatch) is adequate. Do not re-debate without a forcing function.
Decision history (so we don't go round in circles again)
Make mcp-data-server the single owner of STAC topology. DatasetCatalog.load() stops walking the catalog and instead asks MCP for the structured collection content of each entry in layers-input.json. Unifies Wyoming-style private-data deployments with the public-data path; removes the 1-level walk and the collection_url per-entry escape hatch.
Why it's parked (current state is adequate)
Public catalogs boot via direct fetch + 1-level child walk. Fast, parallel, no MCP dependency at boot.
"Cleaner ownership" and "non-browser MCP-client reach" are real benefits, but speculative — no measured pain point.
Forcing functions to unpark
Reopen active work when one of these triggers:
A new deployment shape can't be expressed via collection_url — topology needs >1-level traversal and can't be flattened.
A non-browser MCP client (CLI, notebook, second app) needs authenticated reach to in-app private metadata.
mcp-data-server#117 ships for unrelated reasons (removes the biggest single prerequisite for free).
An independent DatasetCatalog refactor opens this up at no extra cost.
Hard prerequisites
mcp-data-server#117 — s3_key/s3_secret/s3_endpoint/s3_scope on the STAC tools. Without it, Wyoming-style apps still need inline forwarding for private leaves. Currently scoped at 2–3 days.
Batch endpoint on mcp-data-server — get_collections(catalog_url, collection_ids: [...]) returning {id: collection_dict, ...}. Non-negotiable for perf at 30+ datasets (see Performance). File separately.
mcp-credential-proxy extended to forward S3 creds on the new batch tool and the singular STAC tools.
Soft-fail fallback in geo-agent — keep the existing direct-fetch path as a fallback when the batched MCP call errors. Lets this land before all upstream prerequisites are buffed.
Design
Proposed change
Replace the walk with a single batched MCP call:
asyncload(appConfig){this.catalogUrl=appConfig.catalog;constids=appConfig.collections.map(c=>typeofc==='string' ? c : c.collection_id);constoptionsMap=buildOptionsMap(appConfig.collections);constdicts=awaitmcpClient.callTool('get_collections',{catalog_url: appConfig.catalog,catalog_token: appConfig.catalog_token,collection_ids: ids,});for(const[id,collection]ofObject.entries(dicts)){constoptions=optionsMap.get(id)||{};awaitthis.processCollection(collection,options);}}
_rawStac cache populated from these responses, so #192's inline-forwarding path for get_schema keeps working unchanged.
Per-id MCP calls (naive): N round-trips with full session/JSON-RPC/allowlist overhead. Scales poorly under concurrent app boots.
One batched MCP call: 1 RTT total. MCP serves cached entries from memory and parallelizes uncached S3 reads server-side.
Without batching, this is a perf downgrade.
Migration of layers-input.json
Most apps don't change. Top-level catalog + collections is exactly what the new path needs. Per-entry collection_url is deprecated but stays functional with a console warning. Per-entry catalog_token similarly stays.
Rollout
Refactor lands with fallback active. All deployed apps continue working unchanged.
mcp-data-server#117 + batch endpoint ship on their own timeline.
Downstream apps opt in (Wyoming first) by removing collection_url overrides.
After 1–2 release cycles, remove the fallback walk in a separate PR.
Test surface
Demo / @main-pinned apps boot with new path against public catalog (MCP cache hit for everything). No collection_url needed.
Wyoming (after migration) boots with s3://private-wyoming/... reached through mcp-data-server's authenticated S3 path.
Fallback: simulate MCP outage → verify layers still load via direct-fetch on apps with collection_url; verify clean failure for apps without.
Boot timing on a 30+ dataset app within 100ms of current.
Cross-repo sequence
mcp-data-server#117 → batch-endpoint issue (TBD) → mcp-credential-proxy extension → this issue → Wyoming layers-input.json simplification (separate PR in boettiger-lab/wyoming). Roll out via geo-agent-ops's normal pinned/unpinned validation order.
Refactor DatasetCatalog.load() to source from MCP instead of walking STAC locally
Status — parked / backlog
Design captured below. Will be picked up when one of the forcing functions triggers, not before. The "MCP vs. direct STAC" question for
DatasetCatalog.load()has been resolved twice already (#167, #171); the current production answer (direct-fetch + #192 inline-forwarding + #178'scollection_urlescape hatch) is adequate. Do not re-debate without a forcing function.Decision history (so we don't go round in circles again)
DatasetCatalog.load()walks the catalog directly, 1 level.get_collection. Rejected: MCP on critical boot path, OAuth-walled-app privacy issues, dual-href API change required.get_collectionpreload that fed the system prompt. Direct-read became the single STAC consumer at boot.DatasetCatalogretains_rawStac;get_schemaforwards cached JSON to MCP inline. Avoids the refetch without inverting the ownership.collection_urlis the supported pattern for multi-level / mixed-private catalogs (Wyoming). Not a bug.get_stac_details/browse_stac_catalog. Privacy motivation dissolved with get_schema: forward cached STAC content inline to MCP #192; latency motivation unmeasured.Goal
Make mcp-data-server the single owner of STAC topology.
DatasetCatalog.load()stops walking the catalog and instead asks MCP for the structured collection content of each entry inlayers-input.json. Unifies Wyoming-style private-data deployments with the public-data path; removes the 1-level walk and thecollection_urlper-entry escape hatch.Why it's parked (current state is adequate)
collection_url(Wyoming pattern). Deterministic, deployment-portable.get_schemaalready gets cached STAC inline (get_schema: forward cached STAC content inline to MCP #192). No refetch.Forcing functions to unpark
Reopen active work when one of these triggers:
collection_url— topology needs >1-level traversal and can't be flattened.DatasetCatalogrefactor opens this up at no extra cost.Hard prerequisites
s3_key/s3_secret/s3_endpoint/s3_scopeon the STAC tools. Without it, Wyoming-style apps still need inline forwarding for private leaves. Currently scoped at 2–3 days.get_collections(catalog_url, collection_ids: [...])returning{id: collection_dict, ...}. Non-negotiable for perf at 30+ datasets (see Performance). File separately.Design
Proposed change
Replace the walk with a single batched MCP call:
_rawStaccache populated from these responses, so #192's inline-forwarding path forget_schemakeeps working unchanged.Performance
Batching is non-negotiable. For ~30+ datasets:
Without batching, this is a perf downgrade.
Migration of
layers-input.jsonMost apps don't change. Top-level
catalog+collectionsis exactly what the new path needs. Per-entrycollection_urlis deprecated but stays functional with a console warning. Per-entrycatalog_tokensimilarly stays.Rollout
collection_urloverrides.Test surface
@main-pinned apps boot with new path against public catalog (MCP cache hit for everything). Nocollection_urlneeded.s3://private-wyoming/...reached through mcp-data-server's authenticated S3 path.collection_url; verify clean failure for apps without.Cross-repo sequence
mcp-data-server#117 → batch-endpoint issue (TBD) → mcp-credential-proxy extension → this issue → Wyoming
layers-input.jsonsimplification (separate PR inboettiger-lab/wyoming). Roll out via geo-agent-ops's normal pinned/unpinned validation order.Collapses
collection_urlworkaround in downstreamlayers-input.jsonfiles.