This appendix specifies how the verified MCP database turns records into indexable, citation-worthy pages without leaving the zero-build model. It is written so it can be implemented incrementally: every stage is independently shippable, and none requires a running application server or a client-side-rendered corpus.
6.1 Goals and non-goals
Goals
- Every public page is backed by a real, verified record or a real aggregate — no doorway pages, no fabricated
rating/reviewfields. - Every factual field is traceable (
source_url,fetched_at,check_method,confidence) and freshness is shown, not assumed. - The corpus is understandable to both classic crawlers (SEO) and retrieval systems / LLMs (GEO): static HTML for the former, machine-readable facts and citations for the latter.
- Adding a source, a facet, a client, or a transport must be configuration, not a rewrite.
- Output must remain fully static files deployable to cPanel by
git push, with optional edge functions only for interactive search.
Non-goals (explicitly out of scope)
- A user-account system or a server-rendered application.
- Redistributing licensed third-party datasets (e.g. Glama) verbatim; we link and cite, never mirror.
- Scraping authenticated content or bypassing rate limits /
robots.txt.
6.2 URL schema (stable, semantic, version-safe)
| Entity | URL pattern | Notes |
|---|---|---|
| Hub / index | /servers/ |
Primary browse entry, paginated ?page=N (canonical folds to page 1) |
| Server detail | /servers/<slug>/ |
Slug = normalized package/server name; immutable once claimed |
| Server version | /servers/<slug>/v/<version>/ |
Snapshots for breaking changes; latest v canonicalizes to detail |
| Category | /category/<category>/ |
Controlled vocabulary, one word where possible (/category/finance/) |
| Transport | /transport/<transport>/ |
e.g. /transport/stdio/, /transport/streamable-http/ |
| Client compatibility | /works-with/<client>/ |
e.g. /works-with/cursor/ — exclusive, probe-derived |
| Compare | /compare/<a>-vs-<b>/ |
Alphabetical pair, one canonical orientation |
| Alternatives | /alternatives/<slug>/ |
Curated/peer cluster |
| Pricing facet | /pricing/<tier>/ |
free, freemium, paid, self-hosted (only when evidence-backed) |
| Ranking | /ranking/ |
Transparent, appealable multi-factor score |
| Changelog/refresh log | /servers/<slug>/changelog/ |
Verification history per record |
| Data & API | /data/, /data/api/ |
Licensing, bulk snapshots, API terms |
| Whitepaper | /docs/business-plan/ + /docs/business-plan/<chapter>.html |
This document |
Rules. Lowercase, hyphenated, ASCII, no trailing query params on canonical pages. Slugs are minted once and kept with 301 redirects on rename. Pagination and sort/filter combinations that produce near-duplicate content use a self-referential canonical only for page 1 and noindex,follow for thin filter permutations.
6.3 Canonical data model (single source of truth)
One normalized record per server; all pages and feeds are projections of it. Provenance lives alongside every value, never in a separate tribal-knowledge layer.
{
"server_id": "string (uuid)",
"slug": "string (immutable)",
"name": "string",
"canonical_source": { "kind": "official-registry|github|npm|docker|manual", "url": "https://…", "verified_at": "ISO-8601" },
"one_liner": { "value": "string", "source_url": "…", "confidence": 0.0 },
"transports": [{ "type": "stdio|streamable-http|sse", "endpoint": "string|null", "evidence_url": "…" }],
"auth": { "required": true, "methods": ["oauth|api_key|none"], "source_url": "…" },
"pricing": { "tier": "free|freemium|paid|unknown", "plans_url": "…|null", "currency": "USD|null", "evidence_level": "declared|tested|none" },
"clients": [{ "client": "cursor", "compatible": true, "check_method": "probe|docs", "checked_at": "ISO-8601", "run_id": "string" }],
"tools": [{ "name": "string", "schema_hash": "sha256" }],
"activity": { "stars": 0, "open_issues": 0, "npm_weekly": 0, "docker_pulls": 0, "measured_at": "ISO-8601" },
"version": { "current": "semver", "published_at": "ISO-8601", "is_latest": true },
"lifecycle": { "status": "active|stale|deprecated", "reason": "string", "last_success_at": "ISO-8601" },
"categories": ["string"],
"tags": ["string"],
"sources": [{ "field": "string", "source_url": "…", "fetched_at": "ISO-8601", "check_method": "string" }]
}
Immutability contract. Raw fetched payloads are written once to raw/<source>/<date>/<id>.json and never mutated. The normalized and verified layers are fully derivable from raw, so any improvement to verification logic can backfill history and recompute scores. This is the same discipline described in §4 (immutable snapshots + recomputable derived layers).
6.4 Static generation pipeline
sources/ (adapters: official-registry, github, npm, docker, docs, manual review)
│ fetch + respect robots/ToS, rate-limit, store raw payload
▼
raw/… immutable snapshots (content-addressed, dated)
│ normalize → merge/dedupe by canonical identity
▼
normalized/<id>.json
│ verification layer (liveness probe, client matrix, price/auth evidence)
▼
verified/<id>.json + checks/<run_id>.json (pass/fail per gate)
│ project into pages + feeds
▼
site/… static HTML / JSON / XML → git commit → cPanel (push = deploy)
- Adapters are pluggable. Each source implements the same interface (
fetch → raw,normalize → record fragment,confidence()). Adding a source is a new adapter file plus a config row, never a pipeline change. - Identity & dedupe first. Multiple sources for the same server resolve to one
server_idvia a priority merge (official registry > package manager > repository > manual). Conflicts are kept, not silently overwritten, and surfaced for review. - Verification is a gate, not a label. A detail page is only published (or shows a "verified" state) when its run passes the configured checks; otherwise the record renders with an explicit "unverified/stale" treatment.
- Idempotent, dated runs. Each run writes a
run_id; pages embed which run produced them so freshness is auditable. - Scale is a non-issue on a static host. Even 20k servers × several projections is a few hundred thousand small files; generation runs on a schedule (cron/GitHub Actions) and deploys only changed files.
6.5 Page templates and on-page SEO (per page type)
Every generated page shares a strict head contract: unique title/description, absolute canonical, Open Graph, Twitter card, JSON-LD, and correct language. Detail pages additionally emit breadcrumb and entity schema.
Detail page (/servers/<slug>/)
title:<Name> MCP Server — <transport>, <pricing tier>, <client> support | MCPera.- H1 = server name only; a one-line value proposition under it.
- Visible verification badge + "last verified <relative time>" with a tooltip showing
check_method; deprecated/stale gets a visibly different state. - Copy-ready config snippet (one per supported transport), client-compatibility table, pricing/auth card with source link and date, tools list, activity metrics, versions/changelog, alternatives.
- Schema:
SoftwareSourceCode/SoftwareApplication+BreadcrumbList; useoffersonly when pricing evidence is real; never emit aggregateRating without genuine ratings. - Internal links: category, transport, client pages, alternatives, changelog — keeps link equity on data pages, not the homepage.
Facet/aggregate pages (category, transport, works-with, pricing, ranking)
- Each leads with genuine editorial guidance ("how to choose", scope definition, last-updated date) before the ranked table — this is what separates a useful aggregate from a thin directory.
- Pagination uses
rel="next"/"rel="prev"and self-canonical on page 1; deep filter permutations arenoindex,follow. ItemListJSON-LD enumerating the servers shown (name + url), kept in sync with the visible table.
Hub pages and comparison pages
- Comparison pages only exist for pairs with enough real overlap to compare; the data delta (price/auth/transport/compatibility) is the content.
- Alternatives clusters come from shared categories/tags plus client overlap, not arbitrary cross-links.
6.6 GEO: making the database citable by retrieval systems
Generative engines and agents quote sources they can parse and trust. The GEO layer therefore emphasizes machine-readable facts, provenance, and stable references.
- Self-describing JSON at predictable URLs. Publish per-server
…/index.jsonalongside HTML, plus feeds at/data/: full snapshot, changelog feed, and category indexes. Same data, two projections. - Entity clarity. Consistent name + slug everywhere;
sameAslinks to the official registry entry, GitHub repo, npm/Docker packages so external systems can reconcile identity. - Citations built in. Every derived claim links to its
source_urland showsverified_at; pages expose a short "Methodology" block describing the check and its date. This mirrors how cited research is surfaced in answers. - Answerable structure. Short, factual lead summaries ("Does X work with Cursor? Last tested …") appear as the first block, then detail — easy for extraction and featured treatment.
llms.txtand feeds. Ship/llms.txt(index of key sections + data endpoints), and keepsitemap.xmlexhaustive with<lastmod>. Provide an RSS/Atom changelog for fresh-content signals.- Feeding the ecosystem directly. Publish a small, well-documented JSON API/snapshot under clear terms; being the clean upstream source is both a GEO strategy and the top of the data-licensing funnel (§5).
- No paywall on facts required to evaluate — the open HTML/JSON is the citation surface; bulk history, SLAs, and redistribution rights are the paid layer (avoid quotation leakage problems).
6.7 Crawl budget, sitemaps, and index control
- Segmented sitemaps, one index + per-type maps:
sitemap-servers.xml,sitemap-categories.xml,sitemap-clients.xml,sitemap-docs.xml. Every URL carries accurate<lastmod>equal to the producingrun_iddate; stale-but-valid records keep their URL but show freshness state instead of 404ing. - Quality gate before a URL is indexable. A detail page is
indexonly if it has a verified name, one-liner, at least one transport, and a successful recent check; otherwisenoindex,followso crawler equity is spent on pages that answer queries. This directly controls thin-content risk as the corpus scales to tens of thousands. - Consolidation. Canonical on every page;
m.example/query variants/www vs apexresolved by one redirect rule; trailing-slash policy enforced site-wide. - robots.txt allows HTML, JSON data feeds, and assets; disallows internal/filter noise and any
/tools/build scaffolding. - No orphan pages — generated cross-links (facets ↔ detail ↔ alternatives) are emitted in the same run, and a build assertion fails if any indexable URL is unreachable from internal navigation.
6.8 Extensibility by configuration
The schema treats facets, clients, transports, and sources as data, enabling growth without template changes:
facets.yml— controlled category/tag vocabulary with labels, descriptions, and merge rules.clients.yml— each client (cursor,claude-desktop,windsurf, …) declares its probe recipe and compatibility rules; adding a client creates its/works-with/<client>/page automatically.transports.yml— transport types and endpoint validation rules.sources/<name>.js— adapters registered insources.ymlwith priority, rate limits, and enabled flags.- Templates are generic over these lists: a new value propagates to URLs, nav, sitemap, and JSON-LD with no code edit.
- Versioned contracts: the record schema and data snapshot carry a
schema_version; consumers pin@vN(immutable), matching the broader project's no-surprises data philosophy.
6.9 Quality, governance, and neutrality
- No invented social proof.
aggregateRating/revieware emitted only from genuine, attributable feedback; pricing and compatibility always carry evidence level and date. - Appealable ranking. The ranking formula and its weights are public and versioned; a "report this record" flow feeds the manual-review queue and changelog.
- Provenance is the compliance asset. Field-level sources and dated raw snapshots make licensing defensible and takedowns surgical (remove a source → recompute), supporting the data-licensing business in §5.
- Legal hygiene per source. Each adapter records ToS/robots stance and allowed use; licensed sources are never redistributed, only cited; PII is not collected.
6.10 Build sequence (incremental, each step ships)
- v1 — head contract + this whitepaper public. Tighten metadata, JSON-LD, canonical, OG/Twitter, sitemap across the existing site (the deliverable accompanying this appendix).
- v2 — record schema + one source (official registry) + static detail pages for a curated 200–500 verified servers, with source/date on every field and
SoftwareSourceCode+ breadcrumb schema. - v3 — verification gate (liveness + one client matrix) and
/works-with/facet pages; introduce segmented sitemaps and the index-quality gate. - v4 — more adapters (npm/Docker/GitHub activity), category & pricing facets, comparison/alternatives, ranking.
- v5 — GEO/data business: public JSON snapshots +
/data/,llms.txt, changelog feeds, and the paid bulk/API/license layer behind terms.
Acceptance test for the whole architecture (any version): fetch any public URL without executing JavaScript and you must receive complete content, correct canonical/schema, and a freshness statement; delete any single source and the pipeline must recompute the affected records rather than fail silently; and every machine-readable claim must resolve to a human-checkable source link.