Repository navigation
MCP catalog audit: publish hosted endpoints hidden behind unusable first entries, fix Deel/AppDeploy URLs, report withheld endpoints (stacked on #97) - #98
Open
vaibhavamalgm wants to merge 2 commits into
Conversation
…entries hiding hosted ones curated/resend.json described only the local stdio server (npx -y resend-mcp) with no endpoint. Curated records claim their (domain, kind) slot before any other source, so the hosted https://mcp.resend.com/mcp already present in domains/resend.com was discarded and the catalog's Resend MCP surface had no connect URL. - curated/resend.json: add the hosted MCP interface (Streamable HTTP, OAuth in supporting clients, API-key bearer header otherwise; auth "mixed" like Stripe and GitHub) and keep the local stdio server as a second interface. - normalize: when a curated file lists several MCP interfaces, a hosted, publishable endpoint beats an endpoint-less one listed before it. - normalize: an endpoint-less curated MCP record no longer holds its slot. A feed or discovered hosted endpoint that passes the usual isPublic and endpoint-verdict rules replaces it, and the build prints a curated-mcp-no-endpoint warning so the curated file gets fixed. - The curated/feed/discovered merge moves out of main() into assembleRecords() so tests exercise the real wiring with local fixtures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…entries; report withheld ones
Audit of every discovered hosted MCP endpoint against the published search
index (1,319 domains) found three causes of a missing or wrong MCP surface:
- buildDiscoveredEntries kept the first MCP surface per domain even when it
had no URL or an unusable {template} URL. That record was then dropped by
the endpoint rules and the domain's real hosted server went with it. A
hosted, publishable endpoint now beats an earlier unusable one (Algolia,
Commerce Layer, LangChain/LangSmith, Snowplow, Vectorize, Halyard,
PromptLayer, Loqate, Cosmic, Coverage Cat, Webiny, Weaviate, evlog). A
promoted surface never becomes a second card for an endpoint another row
already publishes; pre-existing duplicates are untouched.
- A domain covered by another source with no MCP surface (an apis.guru spec,
a GraphQL/CLI feed row, a curated file without an MCP interface) still has
its discovered record skipped wholesale. Those hosted endpoints are now
reported by the build (discovered-mcp-withheld) instead of disappearing
silently; they are not auto-published, since there is no per-surface
rejection if a crawled one is wrong.
- The OpenAI directory feed lists Deel's staging host and AppDeploy's
previous host. overrides/mcp/ points them at the production endpoints the
vendors document.
Co-Authored-By: Claude Opus 5.5 <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.
Audit
I compared every hosted MCP endpoint in
domains/with whatoutput/search-index.jsonactually publishes. That file is what the worker's catalog feed serves.output/mcp-endpoints.json)I also checked the curated entries: all 18 curated hosted endpoints match discovery and the probe cache, and every curated
auth: "none"is backed by alive(HTTP 200) probe. No stale curated endpoints and no contradicted auth claims.All endpoint checks below were read-only: one plain
GET(status andWWW-Authenticateonly) and a fetch of the RFC 9728 protected-resource metadata. There were no MCPinitializecalls, no sessions and no credentials.Fix 1: discovered MCP selection (pipeline,
scripts/normalize.ts)Bug:
buildDiscoveredEntrieskeeps the first MCP surface per domain. When that surface has no URL (a docs server listed without one) or an unusable{template}URL, the record is later dropped byisPublic/applyEndpointVerdicts, and the domain's real hosted server, listed second, is lost with it.Fix: within a domain, a hosted endpoint now beats an earlier unusable one. "Hosted" means
isHttpUrlplus the existingisPublishableMcpUrl, so the same template, loopback and dead-verdict rules apply. First-listed-wins is unchanged whenever the first entry is usable. Other kinds are unchanged.Guard against new duplicates: a promoted surface is dropped if another row already publishes the same endpoint. For example, domotz.app's second entry is domotz.com's endpoint, so domotz.app does not get a duplicate card. The 22 cross-domain duplicate MCP URLs already on
mainare untouched (see draft #51).Endpoints this publishes, each verified:
https://mcp.algolia.com/mcphttps://{APP_ID}.algolia.net/…templateresource= endpoint, auth serverdashboard.algolia.com; probeauthhttps://core-mcp.commercelayer.io/mcpresource= endpoint, auth serverauth.commercelayer.io;401 Bearerhttps://api.smith.langchain.com/mcpresource= endpoint;401withresource_metadatahttps://console.snowplowanalytics.com/api/agent/mcpresource= endpoint, auth serverid.snowplowanalytics.comhttps://api.hindsight.vectorize.io/mcpresource= endpointhttps://mcp.usehalyard.airesource= endpoint, auth serverapi.usehalyard.aihttps://mcp.promptlayer.com/mcpAuthorization: Bearer pl_…https://reach.prod.fabric.gbgplatforms.com/mcphttps://mcp.cosmicjs.com/v1/agent…/v1/buckets/{your-bucket-slug}templatehttps://coveragecat.com/api/consumer/mcphttps://mcp.docs.webiny.com/mcphttps://weaviate-docs.mcp.kapa.aihttps://evlog.dev/mcpHTTP 200, initialize ok. No separate docs page found, so this rests on the repo's own probeFix 2: report hosted endpoints that are still withheld (pipeline)
A domain covered by another source with no MCP surface still has its discovered record skipped wholesale by the domain-wide
knownRawDomainscheck. Examples of such sources: an apis.guru spec, a GraphQL or CLI feed row, or a curated file without an MCP interface. #26's commit message describes the intended rule as kind-aware, but for exact-domain matches it is still domain-wide.I did not auto-publish these. Several crawled endpoints in this group are wrong:
apigee.net→api.marketcheck.com/mcp: a different vendor.xero.com→https://api.xero.com: the API base, not MCP.zuora.com→ a sandbox host.1password.dev: no longer resolves.The repo has no per-surface rejection, and
catalog-denylist.jsonis whole-domain only. So the build now reports them instead of dropping them silently:withheldDiscoveredMcp()skips endpoints already published under another domain. Ten of the 60 gaps are that case (correct behaviour): bufferapp.com → buffer.com, fly.io → sprites.dev, polygon.io → massive.com, swaggerhub.com → smartbear.com, brex.io → brexapis.com, ote-godaddy.com → godaddy.com, planetscale.com → pscale.dev, opentargets.io → targetvalidation.org, mandrillapp.com → list-manage.com, domotz.app → domotz.com.Fix 3: source data,
overrides/mcp/Both records come from the OpenAI directory feed (
sources/openai.json):mcp/deelhttps://api-staging.letsdeel.com/mcp(staging)https://api.letsdeel.com/mcphttps://api.letsdeel.com/mcp, OAuth2 or bearer token, no staging host documented. Both hosts serve PRMmcp/appdeployhttps://api.appdeploy.ai/mcphttps://api-v2.appdeploy.ai/mcphttps://api-v2.appdeploy.ai,/mcp, OAuth 2.0 + PKCE or bearerAuth stays
oauth, which matches both vendors' docs. Each override sets onlymcp.remoteUrland still goes through the existing endpoint verdicts.Tests (
scripts/normalize.test.ts, local fixtures only){APP_ID}template, is published, and the domain's other records and slugs are unchanged.With fix 1 disabled, its test fails; with the duplicate guard disabled, its test fails. Both pass with the code as committed.
Verification (actual results)
bun test scripts/bun scripts/normalize.ts, all outputs diffed against unmodifiedmainopenapi.json,graphql.json,cli.jsonunchanged.mcp.json1327 → 1340 (the 13 above). Changed records:curated/resend-com-mcp(#97),mcp/deel,mcp/appdeploy. Search index 3369 → 3370 rows (evlog.dev is new). Cross-domain duplicate MCP URLs: 22 → 22bun run buildtsc --noEmit -p .mainbun run validate:batchmain(pre-existingdomains/alias duplicates)Needs maintainer review / live validation (not changed here)
mcp.hubspot.com), Vimeo, TomTom, Netlify, Avaza, PocketSmith, Synq, Shotstack, elmah.io, Icons8, X (api.x.com/mcp), and Cisco ThousandEyes; most return401with PRM naming the endpoint. Others are wrong (see above). Making the known-domain rule kind-aware for MCP is a one-line change once there is a way to reject a single bad surface. Alternatively they could go in as curated records.api_key=…in the query string. Discovery listshttps://mcp.vio.com/mcpwithauth: none. I can't confirm which is right without opening a session.people.googleapis.com,searchconsole.googleapis.comanddeveloperknowledge.googleapis.comare withheld or aliased. Left for issue file.googleapis.com MCP is misidentified as Google Drive and auth-free #69.curated/GENERATION.mdreferencesscripts/validate-curated.ts, which doesn't exist.🤖 Generated with Claude Code