feat(web): full SEO stack — metadata, JSON-LD, sitemap, robots, OG image
Ported and adapted from the BuildMyDiscord SEO setup:
- lib/seo.ts — single source for site constants, the FAQ data (shared by
the rendered FAQ and the FAQPage schema so they never drift) and JSON-LD
builders.
- Rich root metadata: title template, keywords, Open Graph, Twitter card,
robots directives, canonical.
- JSON-LD: Organization + WebSite + SoftwareApplication sitewide, FAQPage
on the landing page. No AggregateRating — there are no real reviews yet.
- app/robots.ts — allow all, explicit allow-list for AI answer-engine
crawlers (GPTBot, ClaudeBot, PerplexityBot, …), disallow private routes.
- app/sitemap.ts — every public marketing + docs route.
- app/opengraph-image.tsx — monochrome on-brand 1200x630 share card.
- app/manifest.ts + public/llms.txt.
- Per-page metadata for pricing, changelog, security, privacy, terms,
docs, templates and status.
- opengraph-image + apple-icon pinned to the edge runtime — next/og
crashes during a Node-runtime prerender.
Verified: next build passes; /robots.txt, /sitemap.xml,
/manifest.webmanifest and /opengraph-image all generate.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 19:16:40 +02:00
import { pageMetadata } from '@/lib/seo' ;
export const metadata = pageMetadata ( {
title : 'Privacy' ,
description :
'BuildMyMCPServer privacy policy — what data we collect, how it is used, and the rights you have over it.' ,
path : '/privacy' ,
} ) ;
feat(web): real 3-step wizard, settings, audit, docs, marketing pages
Sprint 3.5: close every dead link and replace the single-step wizard with the
spec-mandated 3-step flow.
Wizard:
- Step 1 collects prompt + name + slug, calls /v1/servers/preview.
- Step 2 renders parsed tools (name, description, input schema as copyable JSON)
+ a credential field per requiredSecret Claude actually identified. Self-contained
servers see 'No credentials needed' instead of generic Notion placeholders.
- Step 3 streams the live build over WebSocket and shows install snippets.
New dashboard pages:
- /settings — org, plan/usage, members table, API keys + billing stubs (Sprint 4),
encryption status. Reads /v1/me/org.
- /audit — filterable table over /v1/audit with action pills, resource refs, IP,
metadata JSON.
Docs site (/docs + 6 sub-pages):
- Sticky 240px sidebar, max-w-prose article column, shared DocsTitle/H2/Code primitives.
- Quickstart, MCP concepts, OAuth 2.1 flow (full walkthrough with curl), Authoring
tools, Self-hosting, API reference, FAQ.
Marketing pages:
- /changelog with tagged release timeline.
- /security with 8 pillars + disclosure.
- /privacy with GDPR-aware sections.
- /terms (10 clauses).
- /pricing full page (nav now points here instead of /#pricing anchor).
- /status with live 10s probes against /api/health and /login.
Footer 'system status' badge now links to /status.
All 20 routes 200 OK in smoke crawl. Typecheck clean across packages.
2026-05-19 18:20:31 +02:00
const SECTIONS = [
{
h : 'What we collect' ,
p : [
'Account: email, organization name, the IP address of your sign-in.' ,
'Workspace: the prompts you send to the generator, the generated server specifications, build logs, server names and slugs you choose.' ,
'Tool-call metrics: counts, latencies, status codes — never the request or response payloads. We only know that a tool was called, how long it took, and whether it succeeded.' ,
'Billing: Stripe customer id + subscription metadata for paid plans. Card details never touch our servers.' ,
] ,
} ,
{
h : 'What we do NOT collect' ,
p : [
'Plaintext credentials. Every secret you save is AES-256-GCM encrypted before it hits storage. We have no ability to read them; only your container at runtime can.' ,
'Tool-call payloads. The arguments your AI client sends and the responses our server returns are not stored or logged.' ,
'Browsing data, cross-site tracking, advertising identifiers.' ,
] ,
} ,
{
h : 'Where it lives' ,
p : [
'EU region by default (Hetzner Falkenstein, Germany).' ,
'Postgres + Redis + container hosts are all in the same region.' ,
'Backups encrypted at rest in Backblaze B2 EU.' ,
] ,
} ,
{
h : 'Subprocessors' ,
p : [
feat: tiered LLM (GLM free / Claude paid) + rate limits + quota enforcement
The free tier was hemorrhaging Anthropic cost with no abuse cap (no rate
limit on /preview, Opus default in the build worker, 5-min cache TTL that
made cache-miss the common case). This switches free users to GLM, paid
users to Claude tiers, and tightens every leak found in the audit.
Backend:
- @bmm/llm: GLM provider via Zhipu's OpenAI-compatible endpoint, pickPreviewModel
+ pickBuildModel helpers, plan-aware ModelChoice
- preview-cache TTL 5min -> 24h (kills the cache-miss path)
- /v1/servers/preview: picks model from caller's plan, returns model name to UI
- /v1/servers POST: enforces SERVER_LIMITS per plan (402), rate-limits builds
- daily rate-limit on preview (5/40/150/1000) and build (3/20/100/500)
- /v1/auth/me returns plan so the wizard can show the right model name
- generator worker: GLM default, Anthropic Sonnet fallback if GLM errors
Frontend:
- Wizard fetches plan, shows "<model> is drafting the tool spec" pre-emptively,
upgrade hint for hobby users, friendly errors for 402 / 429
- Pricing page: AI-model line per tier (Open-tier / Haiku / Sonnet / Opus),
Team €149 -> €199, Enterprise €499 -> €999, daily-preview limit per tier
- Privacy + Security: explicit subprocessor disclosure for Anthropic (US) /
Zhipu (CN) and which tier uses which
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 23:50:00 +02:00
"Anthropic, USA (Claude AI — used for prompt analysis and code generation on Pro / Team / Enterprise tiers). Only the prompt text and resulting spec are sent. Anthropic's data-retention policy applies." ,
'Zhipu AI, China (GLM model — used for prompt analysis on the free Hobby tier only). Only the prompt text and resulting spec are sent. Upgrade to a paid tier to keep all AI processing within Anthropic (US).' ,
'Hetzner, Germany (compute).' ,
'Backblaze, EU (encrypted backups).' ,
'Stripe, Ireland (billing).' ,
'Cloudflare (DNS + DDoS protection).' ,
] ,
} ,
{
h : 'AI processing per tier' ,
p : [
'Hobby (free): prompts are sent to Zhipu AI (GLM, China) for analysis. Choose a paid tier if your prompts contain data that must not leave the EU/US.' ,
'Pro: prompts are sent to Anthropic (Claude Haiku 4.5, USA).' ,
'Team: prompts are sent to Anthropic (Claude Sonnet 4.6, USA).' ,
'Enterprise: Anthropic (Claude Sonnet + Opus, USA) with EU-data-residency opt-in available on request.' ,
feat(web): real 3-step wizard, settings, audit, docs, marketing pages
Sprint 3.5: close every dead link and replace the single-step wizard with the
spec-mandated 3-step flow.
Wizard:
- Step 1 collects prompt + name + slug, calls /v1/servers/preview.
- Step 2 renders parsed tools (name, description, input schema as copyable JSON)
+ a credential field per requiredSecret Claude actually identified. Self-contained
servers see 'No credentials needed' instead of generic Notion placeholders.
- Step 3 streams the live build over WebSocket and shows install snippets.
New dashboard pages:
- /settings — org, plan/usage, members table, API keys + billing stubs (Sprint 4),
encryption status. Reads /v1/me/org.
- /audit — filterable table over /v1/audit with action pills, resource refs, IP,
metadata JSON.
Docs site (/docs + 6 sub-pages):
- Sticky 240px sidebar, max-w-prose article column, shared DocsTitle/H2/Code primitives.
- Quickstart, MCP concepts, OAuth 2.1 flow (full walkthrough with curl), Authoring
tools, Self-hosting, API reference, FAQ.
Marketing pages:
- /changelog with tagged release timeline.
- /security with 8 pillars + disclosure.
- /privacy with GDPR-aware sections.
- /terms (10 clauses).
- /pricing full page (nav now points here instead of /#pricing anchor).
- /status with live 10s probes against /api/health and /login.
Footer 'system status' badge now links to /status.
All 20 routes 200 OK in smoke crawl. Typecheck clean across packages.
2026-05-19 18:20:31 +02:00
] ,
} ,
{
h : 'Retention' ,
p : [
'Active account: all workspace data kept while subscribed.' ,
'Cancelled account: 30-day grace period, then full deletion (servers, builds, logs, audit).' ,
'Audit log: 1 year on Team+, 30 days on Pro/Hobby.' ,
'Tool-call metrics: 30 days, then aggregated to daily counts.' ,
] ,
} ,
{
h : 'Your rights (GDPR)' ,
p : [
'Access — export everything in JSON via the settings page (Sprint 4) or by email.' ,
'Deletion — delete your organization in settings; everything goes within 30 days.' ,
'Rectification — change name and email yourself; everything else is editable on request.' ,
'Portability — the generated TypeScript source of every server is yours, downloadable.' ,
] ,
} ,
] ;
export default function Privacy() {
return (
< div className = "mx-auto max-w-3xl px-6 py-16" >
< header className = "mb-12" >
< div className = "text-[11px] uppercase tracking-[0.16em] text-[--color-fg-subtle]" >
Privacy policy
< / div >
< h1 className = "mt-2 text-[32px] font-semibold tracking-tight" > Privacy < / h1 >
< p className = "mt-3 text-[14px] leading-relaxed text-[--color-fg-muted]" >
Plain language . What we collect , where it lives , how to get it deleted . Last updated
2026 - 05 - 19 .
< / p >
< / header >
< div className = "space-y-9" >
{ SECTIONS . map ( ( s ) = > (
< section key = { s . h } >
< h2 className = "text-[16px] font-semibold tracking-tight" > { s . h } < / h2 >
< ul className = "mt-3 space-y-1.5" >
{ s . p . map ( ( p ) = > (
< li
key = { p }
className = "relative pl-4 text-[13.5px] leading-relaxed text-[--color-fg-muted] before:absolute before:left-0 before:top-2 before:size-1 before:rounded-full before:bg-[--color-fg-subtle]"
>
{ p }
< / li >
) ) }
< / ul >
< / section >
) ) }
< section >
< h2 className = "text-[16px] font-semibold tracking-tight" > Contact < / h2 >
< p className = "mt-3 text-[13.5px] leading-relaxed text-[--color-fg-muted]" >
Data controller : BuildMyMCPServer. Email { ' ' }
feat(web): full SEO stack — metadata, JSON-LD, sitemap, robots, OG image
Ported and adapted from the BuildMyDiscord SEO setup:
- lib/seo.ts — single source for site constants, the FAQ data (shared by
the rendered FAQ and the FAQPage schema so they never drift) and JSON-LD
builders.
- Rich root metadata: title template, keywords, Open Graph, Twitter card,
robots directives, canonical.
- JSON-LD: Organization + WebSite + SoftwareApplication sitewide, FAQPage
on the landing page. No AggregateRating — there are no real reviews yet.
- app/robots.ts — allow all, explicit allow-list for AI answer-engine
crawlers (GPTBot, ClaudeBot, PerplexityBot, …), disallow private routes.
- app/sitemap.ts — every public marketing + docs route.
- app/opengraph-image.tsx — monochrome on-brand 1200x630 share card.
- app/manifest.ts + public/llms.txt.
- Per-page metadata for pricing, changelog, security, privacy, terms,
docs, templates and status.
- opengraph-image + apple-icon pinned to the edge runtime — next/og
crashes during a Node-runtime prerender.
Verified: next build passes; /robots.txt, /sitemap.xml,
/manifest.webmanifest and /opengraph-image all generate.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 19:16:40 +02:00
< a
className = "text-[--color-accent] underline"
href = "mailto:privacy@buildmymcpserver.com"
>
feat(web): real 3-step wizard, settings, audit, docs, marketing pages
Sprint 3.5: close every dead link and replace the single-step wizard with the
spec-mandated 3-step flow.
Wizard:
- Step 1 collects prompt + name + slug, calls /v1/servers/preview.
- Step 2 renders parsed tools (name, description, input schema as copyable JSON)
+ a credential field per requiredSecret Claude actually identified. Self-contained
servers see 'No credentials needed' instead of generic Notion placeholders.
- Step 3 streams the live build over WebSocket and shows install snippets.
New dashboard pages:
- /settings — org, plan/usage, members table, API keys + billing stubs (Sprint 4),
encryption status. Reads /v1/me/org.
- /audit — filterable table over /v1/audit with action pills, resource refs, IP,
metadata JSON.
Docs site (/docs + 6 sub-pages):
- Sticky 240px sidebar, max-w-prose article column, shared DocsTitle/H2/Code primitives.
- Quickstart, MCP concepts, OAuth 2.1 flow (full walkthrough with curl), Authoring
tools, Self-hosting, API reference, FAQ.
Marketing pages:
- /changelog with tagged release timeline.
- /security with 8 pillars + disclosure.
- /privacy with GDPR-aware sections.
- /terms (10 clauses).
- /pricing full page (nav now points here instead of /#pricing anchor).
- /status with live 10s probes against /api/health and /login.
Footer 'system status' badge now links to /status.
All 20 routes 200 OK in smoke crawl. Typecheck clean across packages.
2026-05-19 18:20:31 +02:00
privacy @buildmymcpserver . com
< / a > { ' ' }
for any of the above .
< / p >
< / section >
< / div >
< / div >
) ;
}