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
// Central SEO source of truth — site constants, FAQ data, JSON-LD builders.
// The FAQ array here is rendered on the landing page AND emitted as FAQPage
// structured data, so the two never drift (Google requires them to match).
import type { Metadata } from 'next' ;
export const SITE_URL = process . env . NEXT_PUBLIC_APP_URL ? ? 'https://buildmymcpserver.com' ;
export const SITE_NAME = 'BuildMyMCPServer' ;
export const SITE_TAGLINE = 'Describe your tool. We host the MCP server.' ;
export const SITE_DESCRIPTION =
'From a natural-language prompt to a hosted, OAuth 2.1-protected MCP server in 60 seconds. Streamable HTTP, ready for Claude, Cursor and ChatGPT.' ;
export const SEO_KEYWORDS = [
'MCP server' ,
'Model Context Protocol' ,
'hosted MCP server' ,
'MCP server hosting' ,
'MCP server builder' ,
'create MCP server' ,
'deploy MCP server' ,
'MCP server generator' ,
'OAuth MCP server' ,
'Streamable HTTP MCP' ,
'Claude MCP server' ,
'Cursor MCP' ,
'ChatGPT connector' ,
'MCP template marketplace' ,
] ;
export interface FaqItem {
q : string ;
a : string ;
}
// Rendered on the landing page and emitted as FAQPage JSON-LD — keep in sync
// by virtue of being a single export.
export const FAQ : FaqItem [ ] = [
{
q : 'What is MCP?' ,
a : 'Model Context Protocol — an open standard from Anthropic for connecting AI assistants to external tools, data and APIs over a transport like Streamable HTTP.' ,
} ,
{
q : 'Do I need to write code?' ,
a : 'No. You describe the tool in natural language. We generate the TypeScript server, run static checks, build a Docker image and deploy it to a public OAuth-protected URL.' ,
} ,
{
q : 'Which clients work?' ,
a : 'Claude Desktop, Cursor, ChatGPT Custom Connectors, VS Code Copilot, Continue.dev — anything that speaks the MCP spec.' ,
} ,
{
q : 'How is auth handled?' ,
a : 'Every generated server is an OAuth 2.1 Resource Server. Our control plane is the Authorization Server (PKCE + Dynamic Client Registration + Resource Indicators per RFC 8707).' ,
} ,
{
q : 'Can I self-host?' ,
a : 'Yes. The runner is a plain Docker container; the control plane is open to BYO Postgres + Redis. See the self-hosting guide in docs.' ,
} ,
{
q : 'What about secrets?' ,
a : 'AES-256-GCM at rest in Postgres, injected as environment variables into the runtime container. Never logged, never echoed back.' ,
} ,
{
q : 'Cold starts?' ,
2026-05-31 13:33:41 +02:00
a : 'No cold starts — each server runs in a container that stays warm (auto-restarts on failure), so there is no spin-up delay on a tool call.' ,
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
} ,
{
q : 'Rate limits?' ,
2026-05-31 13:33:41 +02:00
a : 'Every request is gated by OAuth 2.1 before it reaches your container. Configurable per-server rate limiting is on the roadmap.' ,
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
} ,
{
q : 'How fast is generation?' ,
a : 'Spec to image to live URL typically completes in 45-90 seconds.' ,
} ,
{
q : 'Logs and metrics?' ,
2026-05-31 13:33:41 +02:00
a : 'Live build-log streaming to the dashboard, plus structured tool-call metrics — latency, error rate and per-tool throughput — viewable per server.' ,
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
} ,
{
q : 'What if I cancel?' ,
a : 'You can export the full TypeScript source of every server you built. No vendor lock-in.' ,
} ,
{
q : 'Custom domain?' ,
2026-05-31 13:33:41 +02:00
a : 'On the roadmap. Today every server is reachable at a buildmymcpserver.com URL with TLS; bring-your-own-domain support is coming.' ,
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
} ,
] ;
const SOFTWARE_FEATURES = [
'Prompt to a deployed MCP server in under 60 seconds' ,
'OAuth 2.1 authorization server — PKCE, Dynamic Client Registration (RFC 7591), Resource Indicators (RFC 8707)' ,
'Streamable HTTP transport, compatible with Claude Desktop, Cursor, ChatGPT, VS Code Copilot and Continue.dev' ,
'Every generated server runs in an isolated Docker container' ,
'Customer secrets encrypted with AES-256-GCM, injected only at runtime' ,
'Live build-log streaming to the dashboard' ,
'Template marketplace — publish your server or fork someone else’ s' ,
'Full TypeScript source export, no vendor lock-in' ,
'Self-hostable control plane with BYO Postgres and Redis' ,
] ;
const OFFERS = [
{
name : 'Hobby' ,
price : '0' ,
description : '1 server, 100k tool calls/month, BMM subdomain, community support.' ,
} ,
{
name : 'Pro' ,
price : '49' ,
description :
2026-05-31 13:33:41 +02:00
'5 servers, 1M tool calls/month, faster Claude analysis, priority build queue, email support.' ,
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
} ,
{
name : 'Team' ,
2026-05-31 13:33:41 +02:00
price : '199' ,
description : '25 servers, 10M tool calls/month, audit log, shared Slack support.' ,
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
} ,
{
name : 'Enterprise' ,
price : '499' ,
description :
2026-05-31 13:22:50 +02:00
'Unlimited servers; custom infrastructure and data residency on request; dedicated hosting and SSO/SAML scoped per contract; customer success.' ,
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
} ,
] ;
/** Organization + WebSite + SoftwareApplication graph — emitted sitewide. */
export function siteJsonLd ( ) : object {
return {
'@context' : 'https://schema.org' ,
'@graph' : [
{
'@type' : 'Organization' ,
'@id' : ` ${ SITE_URL } /#organization ` ,
name : SITE_NAME ,
url : SITE_URL ,
logo : { '@type' : 'ImageObject' , url : ` ${ SITE_URL } /icon.svg ` } ,
foundingDate : '2026' ,
foundingLocation : {
'@type' : 'Place' ,
address : { '@type' : 'PostalAddress' , addressCountry : 'CH' } ,
} ,
} ,
{
'@type' : 'WebSite' ,
'@id' : ` ${ SITE_URL } /#website ` ,
url : SITE_URL ,
name : SITE_NAME ,
publisher : { '@id' : ` ${ SITE_URL } /#organization ` } ,
description : SITE_DESCRIPTION ,
inLanguage : 'en' ,
} ,
{
'@type' : 'SoftwareApplication' ,
'@id' : ` ${ SITE_URL } /#software ` ,
name : SITE_NAME ,
applicationCategory : 'DeveloperApplication' ,
operatingSystem : 'Web Browser' ,
url : SITE_URL ,
inLanguage : 'en' ,
description :
'BuildMyMCPServer turns a natural-language prompt into a hosted, OAuth 2.1-protected Model Context Protocol (MCP) server. Describe the tools you need; the platform generates a TypeScript server, runs static checks, builds a Docker image and deploys it to a public Streamable HTTP endpoint that Claude, Cursor and ChatGPT can connect to. A template marketplace lets users publish and fork ready-made servers.' ,
featureList : SOFTWARE_FEATURES ,
offers : OFFERS.map ( ( o ) = > ( {
'@type' : 'Offer' ,
name : o.name ,
price : o.price ,
priceCurrency : 'EUR' ,
description : o.description ,
} ) ) ,
} ,
] ,
} ;
}
/** FAQPage structured data — emitted on the page that displays the FAQ. */
export function faqJsonLd ( items : FaqItem [ ] = FAQ ) : object {
return {
'@context' : 'https://schema.org' ,
'@type' : 'FAQPage' ,
mainEntity : items.map ( ( item ) = > ( {
'@type' : 'Question' ,
name : item.q ,
acceptedAnswer : { '@type' : 'Answer' , text : item.a } ,
} ) ) ,
} ;
}
2026-05-31 12:08:05 +02:00
/** TechArticle structured data for /guides/* SEO articles. */
export function articleJsonLd ( opts : {
title : string ;
description : string ;
path : string ;
datePublished : string ;
dateModified? : string ;
} ) : object {
return {
'@context' : 'https://schema.org' ,
'@type' : 'TechArticle' ,
headline : opts.title ,
description : opts.description ,
url : ` ${ SITE_URL } ${ opts . path } ` ,
mainEntityOfPage : { '@type' : 'WebPage' , '@id' : ` ${ SITE_URL } ${ opts . path } ` } ,
datePublished : opts.datePublished ,
dateModified : opts.dateModified ? ? opts . datePublished ,
inLanguage : 'en' ,
author : { '@id' : ` ${ SITE_URL } /#organization ` } ,
publisher : { '@id' : ` ${ SITE_URL } /#organization ` } ,
} ;
}
/** SoftwareApplication structured data for a published marketplace template. */
export function templateJsonLd ( opts : {
slug : string ;
title : string ;
description : string ;
category : string ;
tools : string [ ] ;
author : string | null ;
} ) : object {
return {
'@context' : 'https://schema.org' ,
'@type' : 'SoftwareApplication' ,
'@id' : ` ${ SITE_URL } /templates/ ${ opts . slug } #software ` ,
name : opts.title ,
description : opts.description ,
url : ` ${ SITE_URL } /templates/ ${ opts . slug } ` ,
applicationCategory : 'DeveloperApplication' ,
applicationSubCategory : 'MCP server' ,
operatingSystem : 'Web Browser' ,
inLanguage : 'en' ,
keywords : [ 'MCP server' , 'Model Context Protocol' , opts . category ] ,
featureList : opts.tools ,
isAccessibleForFree : true ,
offers : { '@type' : 'Offer' , price : '0' , priceCurrency : 'EUR' } ,
. . . ( opts . author ? { author : { '@type' : 'Person' , name : opts.author } } : { } ) ,
publisher : { '@id' : ` ${ SITE_URL } /#organization ` } ,
} ;
}
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
/ * *
* Per - page metadata . ` title ` is a bare string so the root layout ' s
* "%s | BuildMyMCPServer" template appends the brand exactly once .
* /
export function pageMetadata ( opts : { title : string ; description : string ; path : string } ) : Metadata {
const fullTitle = ` ${ opts . title } | ${ SITE_NAME } ` ;
return {
title : opts.title ,
description : opts.description ,
alternates : { canonical : opts.path } ,
openGraph : {
type : 'website' ,
siteName : SITE_NAME ,
title : fullTitle ,
description : opts.description ,
url : ` ${ SITE_URL } ${ opts . path } ` ,
} ,
twitter : {
card : 'summary_large_image' ,
title : fullTitle ,
description : opts.description ,
} ,
} ;
}