@@ -177,8 +177,8 @@ export default function Landing() {
AI uses it.
- From prompt to production MCP server in 60 seconds. OAuth 2.1, Streamable HTTP, ready
- for Claude, Cursor and ChatGPT.
+ From a prompt to a production MCP server — OAuth 2.1, Streamable HTTP, ready for
+ Claude, Cursor and ChatGPT.
- See a live build
+ Watch a build
-
+
- OAuth 2.1 + PKCE
+ OAuth 2.1 + PKCE
- Streamable HTTP
+ Streamable HTTP
- AES-256 secrets
+ AES-256 secrets
- Per-server isolation
+ Per-server isolation
@@ -290,13 +290,13 @@ export default function Landing() {
{/* Proof by specificity — three verifiable claims, each one click from
its evidence. Replaces the old pseudo-logo row: no invented marks,
just a plain-text compatibility line. */}
-
+
verify_it_yourself
-
- No testimonials yet — we're new.
+
+ Don't take our word for it.
- So check the claims instead.
+ Every claim links to its proof.
{PROOF_POINTS.map((p) => {
@@ -319,15 +319,16 @@ export default function Landing() {
);
})}
-
+
Works with Claude Desktop, Cursor, ChatGPT, VS Code Copilot and Continue.dev — anything
that speaks MCP.
- {/* Use cases — brand-coloured integration grid. */}
-
+ {/* Use cases — brand-coloured integration grid. No bottom hairline:
+ the marketplace section below brings its own border-y. */}
+
@@ -335,11 +336,11 @@ export default function Landing() {
Wrap any HTTP API.
- In minutes.
+ From one prompt.
- Ship integrations like these from one prompt each.
+ Each shipped from a single prompt.
@@ -375,8 +376,9 @@ export default function Landing() {
{/* Marketplace — split layout: selling points left, honest preview
- frame right. */}
-
+ frame right. Elevated background (no hairline) so the page reads
+ in blocks instead of one continuously ruled ledger. */}
+
marketplace
@@ -602,9 +604,9 @@ function MarketplacePreview() {
{/* Browser chrome */}
-
-
-
+
+
+
buildmymcpserver.com/templates
diff --git a/apps/web/app/login/page.tsx b/apps/web/app/login/page.tsx
index d28227c..7417786 100644
--- a/apps/web/app/login/page.tsx
+++ b/apps/web/app/login/page.tsx
@@ -208,6 +208,7 @@ export default function LoginPage() {
// product should never see a phone-number field as the front door. It only
// renders expanded when SMS is the sole configured provider.
const [phoneOpen, setPhoneOpen] = useState(false);
+ const [providersState, setProvidersState] = useState<'loading' | 'ready' | 'failed'>('loading');
const [error, setError] = useState
(null);
// Email magic-link
@@ -228,11 +229,21 @@ export default function LoginPage() {
)
.then((p) => {
setProviders(p);
+ setProvidersState('ready');
// SMS as the only provider → show the phone form directly (no point
// hiding the sole sign-in method behind a toggle).
if (p.sms && !p.email && !p.google && !p.github) setPhoneOpen(true);
})
- .catch(() => undefined);
+ .catch(() => {
+ // If the providers lookup fails, the page must not strand the visitor
+ // with zero sign-in methods — fall back to SMS + phone form expanded
+ // (the one flow that has no provider-specific client config) and say
+ // why the other options are missing.
+ setProviders({ google: false, github: false, sms: true, email: false });
+ setPhoneOpen(true);
+ setProvidersState('failed');
+ setError('Some sign-in options could not be loaded. Reload the page to try again.');
+ });
const err = new URLSearchParams(window.location.search).get('error');
if (err) setError(ERROR_COPY[err] ?? 'Sign-in failed. Please try again.');
}, []);
@@ -296,6 +307,15 @@ export default function LoginPage() {
Passwordless — pick whichever is easiest.
+ {/* Providers still loading → neutral skeleton instead of a blank card
+ (previously nothing rendered until the fetch resolved). */}
+ {providersState === 'loading' && (
+
+ )}
+
{hasOAuth && (
{providers.google && (
diff --git a/apps/web/lib/articles.ts b/apps/web/lib/articles.ts
index 82f3337..dc006d8 100644
--- a/apps/web/lib/articles.ts
+++ b/apps/web/lib/articles.ts
@@ -43,7 +43,7 @@ export const ARTICLES: Article[] = [
slug: 'rest-api-to-mcp-server',
title: 'Wrap any REST API as an MCP server',
description:
- 'How to turn a REST API into an MCP server your AI clients can use: designing the tool surface, handling auth headers with encrypted secrets, and respecting upstream rate limits.',
+ 'How to turn a REST API into an MCP server your AI clients can use: designing the tool surface (fewer, better tools beat 1:1 endpoint mapping), handling auth headers with encrypted secrets, and respecting upstream rate limits.',
tag: 'Guide',
datePublished: '2026-07-08',
},