com.nessgate/nessgate
Resolves how an MCP client can connect to Supabase by reading its published MCP metadata, returning the protocol, streamable-http transport, MCP endpoint, and OAuth2 authorization/token endpoints and scopes needed to connect.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@com.nessgate/nessgatewhat agent capabilities does stripe.com publish?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
NessGate
Give NessGate a domain and your client's capabilities, and it tells you how that client can connect — and what's still missing. One call turns "here's a domain" into a concrete, sourced connection plan: which protocol to use, at which endpoint, over which transport, and exactly what authentication the service published — or, if it can't be done yet, the precise field the service is missing.
curl -sX POST https://nessgate.com/connect/supabase.com \
-H 'content-type: application/json' \
-d '{"client":{"supports":[{"protocol":"mcp","auth":["oauth2","none"]}]}}'{
"domain": "supabase.com",
"outcome": "credentials-required", // ready | credentials-required | incomplete | no-compatible-method
"connection": {
"protocol": "mcp", "transport": "streamable-http",
"endpoint": "https://mcp.supabase.com/mcp",
"auth": { "type": "oauth2",
"authorizationEndpoint": "https://api.supabase.com/v1/oauth/authorize",
"tokenEndpoint": "https://api.supabase.com/v1/oauth/token",
"scopes": ["projects:read", "database:write", "…"] }
}
}
// → everything needed to connect is known; you just supply your own credentials
// (which never touch NessGate). No scores; each field links back to its source.Four honest outcomes, never a guess: ready (connect now, no credentials), credentials-required
(everything's known — bring your own secret), incomplete (the service under-published — NessGate
names the exact missing field), no-compatible-method (nothing your client speaks). Prefer the
per-resource view? Add ?readiness=1 to /explore. Prefer the raw list of what a domain publishes?
That's the original resolver, GET /discover/{domain} — unchanged and still here.
Why not just build this yourself?
You can — it's not impossible, just permanent. To turn a domain into a working connection you'd have
to read and track every discovery standard (ARD, A2A, llms.txt, api-catalog, OpenAPI, ORD, host-meta,
ANP, UCP, AID, MCP, GB/Z 185.4…), follow each one's auth story (OpenAPI security schemes, the MCP OAuth
metadata chain RFC 9728 → RFC 8414, A2A card schemes), handle server quirks, timeouts, redirects, and
SSRF safety on every hop, normalize it all into one shape, and keep doing that as the protocols change.
NessGate does exactly that, reads on demand, stores nothing, and stays neutral — so you write your
agent, not a compatibility layer. It's free, open (Apache-2.0), and independently implementable; if
nessgate.com vanished, every domain's files would still stand on the domain itself.
Publishing a service? Test yourself before agents do:
npx @nessgate/resolver yourdomain.com # exit 0 = agents can connect; otherwise it names the exact missing fieldRuns the open readiness predicate on your machine (nothing reported anywhere), 3 observations, strict: flaky endpoints fail. Put it in CI to keep your publication connectable.
Live at https://nessgate.com · Specification · Charter · API
NessGate reads the standards a domain already publishes; it defines none of them and stores nothing. The domain is always the authority.
Use it
Embeddable library — dependency-free, fetches the target domain directly (no runtime
dependency on nessgate.com), runs anywhere with fetch — Node, Deno, Workers, and agent runtimes.
(It runs in a browser too, but a browser can only read other domains that send CORS headers, and
most .well-known files don't — so from a browser, resolve arbitrary domains via the hosted
endpoint below, which sends open CORS.) Published as
@nessgate/resolver:
import { resolve } from "@nessgate/resolver"; // or "https://nessgate.com/resolver.mjs"
const { resources } = await resolve("example.com");Hosted endpoint — open CORS, no auth:
curl https://nessgate.com/discover/example.comMCP — the same lookup as a tool (discover_domain) at https://nessgate.com/mcp. Listed in the
official MCP Registry
as com.nessgate/nessgate (domain-verified remote server), so MCP-aware clients can install it directly.
Integrate it (≈5 lines)
Give an agent a domain, get back what to use — no per-standard code. Drop this into a tool, a retrieval step, or an onboarding flow:
import { resolve } from "@nessgate/resolver"; // dependency-free, no key, no account
const { resources } = await resolve(domain); // reads the domain directly
for (const r of resources)
console.log(r.type, r.url, "←", r.sourceUrl); // normalized record + where it came from
// each r: { source, type, url, sourceUrl } — pick the one your agent needs (OpenAPI, A2A, MCP, …)No SDK? The hosted endpoint is one HTTP GET (GET https://nessgate.com/discover/{domain}, open
CORS, no auth), and the MCP tool discover_domain returns the same shape. Adding a new standard
is a new adapter upstream — integrations don't change.
Full integration guide — library, HTTP, and MCP client config (including the mcp-remote bridge
for stdio-only clients): docs/integrations.md.
Related MCP server: nod-mcp-server
Principles
NessGate is free, neutral infrastructure — see the Charter. It never charges to use or to be read, never sells ranking or placement (there is none), keeps no accounts, and stores no domain data. It reads a domain on demand (answers are cached at the edge for up to 10 minutes), never crawls or indexes, and makes no ownership or safety claim — it reports what a domain serves and links back to each source. The specification is open and the reference implementation is Apache-2.0 licensed: anyone may run their own resolver, and if nessgate.com disappeared, every domain's files would still stand on the domain itself.
Architecture
One stateless Cloudflare Worker (
src/worker.js) serves the static site (public/, via the assets binding withrun_worker_first), the resolver API, the MCP server, the per-domain pages, and the sitemap. There is no database.The resolver (
GET /discover/{domain}, and the embeddablepublic/resolver.mjs) reads what a domain publishes, normalizes it into one answer, fetches the domain directly, and stores nothing. Answers are computed fresh and cached at the edge for 10 minutes. A parity test keeps the worker's and the library's normalization byte-identical, and keepspackages/resolver/index.mjs(the npm package) byte-identical topublic/resolver.mjs.Adapter architecture — four discovery channels. Each supported standard is a small, independent adapter, and every adapter uses one of four channels to locate its document:
well-known — GET a fixed path (or paths) on the domain:
llms.txt,ard-catalog(ARD /ai-catalog),a2a-agent-card(A2A),api-catalog(RFC 9727),ai-info.json,openapi,ord(Open Resource Discovery),awp(draft),host-meta(RFC 6415),anp(Agent Network Protocol/.well-known/agent-descriptions), anducp(Universal Commerce Protocol/.well-known/ucp).link-rel — parse
<link rel="ard">in the homepage, then GET the target (ard-link).robots — parse an
Agentmap:directive in/robots.txt, then GET the target (ard-agentmap).dns — a DoH TXT lookup at
_agent.<domain>(aid:v=aid1;u=<uri>;p=<proto>;a=<auth>).
ARD: NessGate implements ARD's normative domain resolution — it fetches
/.well-known/ard.jsonand honours the<link rel="ard">relation (both MUST in ARD v0.91 §5.1) — plus the robotsAgentmap:surface. ARD's optional in-page JSON-LD is found only by general web crawling, which NessGate does not do; ARD's DNS mechanism is described in §5.1 but not yet normatively specified (no record type or parameters). Neither is implemented — publishing a guessed record would be fake conformance. ANP and UCP are emerging; the AID TXT record (v=aid1at_agent) and AWP are drafts, read as-is with no adoption claim. Note: theaidadapter is the AID TXT mechanism, not the IETF DNS-AID draft (SVCB at_agents.<domain>— a separate, unimplemented mechanism).GB/Z 185 (China, 智能体互联) — 185.4 yes, 185.5 gated. NessGate normalizes GB/Z 185.4 agent descriptions ("ACS"): an ACS is an A2A-family card with GB/Z extensions (an agent identity code
aic, an mTLS scheme, acertificateblock), recognized by content and labelledgbz-185-4, preserving those fields and provenance. Recognition is domain-first: an ACS served at the agent-description location NessGate already reads is normalized — no GB/Z-specific.well-knownpath is guessed. GB/Z 185.5 discovery is a federated gateway service with no domain-native location, so it is not part of the hosted resolver and is never auto-discovered. The embeddable library exposes it as an opt-in, Node-only call (resolve(domain, { gbz: { gatewayUrl, fetch, query } })) that POSTs to the reference implementation's real…/acps-adp-v2/discoverendpoint with a caller-supplied authenticated fetch (bring-your-own mTLS/OIDC — NessGate embeds no credentials) and normalizes the ACS records it returns. No guessed endpoints, no fake conformance.Cloudflare KV (
NESSGATE_KV) holds only approximate, IP-keyed hourly rate-limit counters that expire within the hour. Nothing else is stored.Rate limiting: a Cloudflare-native edge limiter (burst, per-colo and eventually consistent — approximate by design) in front of an approximate KV hourly cap. Abuse protection, not exact global accounting.
SSRF protections: DoH pre-check against private/reserved IPs, on-domain redirects only (≤ 3), 1 MB caps, 8 s timeouts, HTTPS-only. Probes are read-only GETs of public well-known paths; the DNS-rebinding TOCTOU window is documented in
src/worker.jsand is immaterial here (Worker egress has no private network behind it, and probes assert nothing).No accounts, no emails, no stored domain data.
Endpoints
Endpoint | Purpose |
| The resolver. Reads what the domain publishes across the supported adapters (llms.txt, ARD/ai-catalog via well-known paths, |
| Evidence-based resolver (v2, additive). Everything |
| Connection-readiness (opt-in, additive). Everything |
| Connection plan. Body |
| Model Context Protocol server (Streamable HTTP, stateless, no auth) exposing three read-only tools: |
| Human-readable domain page — the resolver rendered for humans (live discovery). |
| The embeddable resolver library (also on npm as |
| Machine discovery & docs |
Operations runbook
Deploy flow: commit →
npm run deploy(runs the full regression suite as a hard pre-deploy gate, then stamps the build with the git SHA viaBUILD_ID) →npm run check(regression tests + live smoke checks, including proof that/versionon production equals local HEAD) → push. CI (GitHub Actions) runs the regression suite on every push. The deploy-script gate is the effective production gate, since deploys run from the workstation.Build verification:
GET /versionand theX-NessGate-Buildheader on every response identify the exact deployed commit.Tests:
npm test— no-network regression suite for the security-critical logic (normalization, SSRF/private-IP detection, probe-content validation, thin normalization, and worker↔library↔npm parity).Rollback:
npm run rollback(ornpx wrangler rollback [version-id]; versions listed bynpx wrangler deployments list).Logs:
npx wrangler tail nessgate.CSS changes: bump the
?v=Non the stylesheet link in all pages (assets are cached; unversioned CSS changes will not reach browsers).
Configuration
wrangler.toml binds: assets (run_worker_first), KV, and a [[ratelimits]] binding. There
are no D1 databases, no cron triggers, and no secrets — the resolver is stateless.
npm package
packages/resolver/ is published as @nessgate/resolver
via GitHub Actions Trusted Publishing (OIDC, tokenless, with provenance) — see
.github/workflows/publish-resolver.yml. index.mjs is kept byte-identical to
public/resolver.mjs by the parity test.
License & contributing
The reference implementation is licensed under Apache-2.0 (LICENSE); the WordPress
plugin is GPL, as required by WordPress.org. The protocol is open and independently
implementable — see CONTRIBUTING.md, the naming/trademark policy in TRADEMARK.md, and the
Charter. Anyone may build a compatible resolver without asking
permission; independent implementations are a goal, not a threat. The canonical
resolver/normalization logic lives in public/resolver.mjs and src/worker.js (kept
byte-identical by a parity test).
Security contacts
security@nessgate.com (see /.well-known/security.txt),
abuse@nessgate.com, privacy@nessgate.com, contact@nessgate.com.
This server cannot be deployed
Maintenance
Related MCP Connectors
Discover, compare, route, and execute machine-accessible capabilities for AI agents.
31What a domain publishes for AI agents: ai-catalog.json, llms.txt, agents.md, robots.txt rules. Free.
List a public API where AI agents discover tools, after a bounded readiness check.
36 SEC, WCAG and entity-diligence tools behind 2 low-context ones: discover_tools, call_tool.
Related MCP Servers
- FlicenseNot gradedqualityNot gradedmaintenanceEnables AI agents to dynamically discover and interact with APIs through Swagger/OpenAPI specifications and Postman collections using a strategic four-tool approach. It streamlines API integration by providing universal tools for endpoint discovery, detailed request information, and authenticated execution.1-
- AlicenseAqualityDmaintenanceEnables AI agents to discover and interact with business capabilities by reading structured nod.json manifests from domains, supporting actions like ordering, booking, and searching.2MIT
- AlicenseAqualityDmaintenanceEnables AI agents to perform real-time WHOIS and RDAP lookups, domain availability checks, and TLD infrastructure exploration using native protocols without API keys.8MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to discover, search, and call any REST API described by an OpenAPI or Swagger document. Supports multiple API endpoints with authentication and parameter handling.9 npmMIT