feat(registry): serve the MCP store from a static JSON catalog over REST#4169
Open
viktormarinho wants to merge 3 commits into
Open
feat(registry): serve the MCP store from a static JSON catalog over REST#4169viktormarinho wants to merge 3 commits into
viktormarinho wants to merge 3 commits into
Conversation
Move the store/registry off the per-org Postgres rows + MCP-binding fan-out and onto a single static JSON catalog (decocms/mcps `registry.json`), fetched and cached server-side and served via a plain REST route. - New `apps/mesh/src/registry-catalog/` module: fetches the first-party `registry.json` with single-flight + stale-while-revalidate + timeout + fail-soft caching (reuses `@decocms/std`), normalizes each entry into a canonical `CatalogItem`, merges N sources (first-party first, deduped) and filters/paginates in-memory. 33 unit tests. - New `GET /api/registry/items[/:id]` REST route (global, top-level mount). - `REGISTRY_CATALOG_URL` setting (HTTPS-only; defaults to the decocms raw catalog, overridable). - Frontend: `use-merged-store-discovery` and `use-install-from-registry` rewired from the multi-registry MCP fan-out to the REST catalog (hook signatures unchanged → call sites untouched). Additive and merge-dark by design: the legacy Postgres registry, its tools, the public MCP shim, and the seeded registry connections remain in place (no longer used by the store frontend); their removal lands in a follow-up PR. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- #1: stamp catalog items with the Deco Store well-known source id so connections.tsx's `_registryId` registry filter and source badges keep working under the single catalog (proper filter removal lands in a later phase, with the rest of the per-registry machinery). - #2: the catalog is live by default (REGISTRY_CATALOG_URL has a default), so fix the app.ts / settings comments that claimed it "ships dark when unset". - #3: drop the now-unused registry-utils helpers (inferRegistryListToolName, isWellKnownRegistry, flattenPaginatedItems, extractItemsFromResponse, callRegistryTool) left dangling by the REST migration — keeps knip green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CI build job's knip gate flagged 6 unused exports: the index.ts barrel re-exported createCatalog/firstPartyJsonSource/normalizeCatalog/toCatalogItem (consumers + tests import them from their own modules) and a __resetCatalogForTests seam no test used. Trim the barrel to what app.ts consumes and remove the dead function. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What is this contribution about?
Moves the MCP store/registry off per-org Postgres rows + the MCP-binding fan-out and onto a single static JSON catalog (
decocms/mcpsregistry.json), fetched and cached server-side and served via a plain REST route. Adds a newapps/mesh/src/registry-catalog/module (single-flight + stale-while-revalidate + fail-soft caching, normalize →CatalogItem, in-memory merge/filter/paginate, 33 unit tests), aGET /api/registry/items[/:id]route, and aREGISTRY_CATALOG_URLsetting (defaults to the decocms catalog). The frontend store hooks (use-merged-store-discovery,use-install-from-registry) are rewired to the REST catalog with their signatures unchanged, so call sites are untouched. This is additive and merge-dark: the legacy Postgres registry, its tools, the public MCP shim, and the seeded registry connections remain in place (just unused by the store), with their removal to follow in a separate PR. Cross-repo: the catalog lives indecocms/mcps(PR #476 merged, #477 adds GitHub's official MCP, issue #478 tracks retiring the old Supabase server).Screenshots/Demonstration
No visual change — the store renders the same items, now sourced from the catalog instead of the per-registry MCP fan-out.
How to Test
REGISTRY_CATALOG_URLunset (uses the default decocms raw catalog) or set to aregistry.jsonURL, run the app.curl 'localhost:3000/api/registry/items?search=stripe'→ returns catalog items; open the "Add connection"/store dialog → items load + search works.server.remotes[].url.Migration Notes
Config only:
REGISTRY_CATALOG_URL(HTTPS, optional — defaults tohttps://raw.githubusercontent.com/decocms/mcps/main/registry.json). No database migration in this PR; the table/connection drops come in the follow-up deletion PR.Review Checklist
Summary by cubic
Serve the MCP store from a static JSON catalog over REST to simplify and speed up discovery and installs. The frontend now reads the catalog via REST (no hook API changes) and stamps items with the Deco Store source id to keep existing filters/badges working.
New Features
REGISTRY_CATALOG_URL(defaults to https://raw.githubusercontent.com/decocms/mcps/main/registry.json), with single-flight + stale-while-revalidate caching (1h TTL), normalization, merge/dedupe, and 33 tests.GET /api/registry/itemsandGET /api/registry/items/:id(global, read-only) and warm the cache on boot.use-merged-store-discoveryanduse-install-from-registryto call the REST catalog and stamp items with the Deco Store_registryId; signatures unchanged and no UI changes.Migration
REGISTRY_CATALOG_URL(HTTPS; localhost may use http). Defaults to the first-party decocms catalog. No database changes or call-site updates required.Written for commit 8550a8d. Summary will update on new commits.