feat(web): two-mode pricing (hosted + self-hosted) across landing
Some checks failed
CI / Lint (push) Has been cancelled
CI / Typecheck (push) Has been cancelled
CI / Broker tests (Postgres) (push) Has been cancelled
CI / Docker build (linux/amd64) (push) Has been cancelled

Rewrites pricing section from single "public beta" card to side-by-side
hosted vs self-hosted comparison reflecting the cleaner product
architecture. Enterprise sell is now concrete: "Run our Docker image,
point your CLI at it, done — your mesh never leaves your VPC."

Updates hero subtitle, CTA, FAQ, and where-mesh-fits claim card to
reinforce the two deployment modes consistently across the landing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alejandro Gutiérrez
2026-04-12 21:17:38 +01:00
parent f1d35b10da
commit d0fbc64e7e
5 changed files with 163 additions and 126 deletions

View File

@@ -33,8 +33,8 @@ export const CallToAction = () => {
style={{ fontFamily: "var(--cm-font-serif)" }}
>
Anthropic built Claude Code per developer. The next unlock is
between developers. 43 tools, five databases, E2E encryption
open-source and ready now.
between developers. Hosted on claudemesh.com or self-hosted in
your VPC same CLI, same features, same encryption.
</p>
</Reveal>
<Reveal delay={3}>

View File

@@ -17,7 +17,7 @@ const ITEMS = [
},
{
q: "Do I need to run a server?",
a: "No — claudemesh.com hosts the broker for you. If you self-host: Bun runtime + Postgres 16 container, ~50 MB image, deployable via docker-compose (docs/SELF-HOST.md). Two long-lived processes: broker + Postgres. Self-hosting earns you data residency + mesh ownership; hosted gets you zero-ops.",
a: "Not for hosted mode — claudemesh.com runs the broker for you. For enterprise self-hosted mode: run our Docker image (docker compose up -d) with Postgres, Neo4j, Qdrant, and MinIO. Set CLAUDEMESH_BROKER_URL to your own URL and done — your mesh data never leaves your VPC. Same CLI, same features.",
},
{
q: "Does it work across offices / continents?",
@@ -44,8 +44,8 @@ const ITEMS = [
a: "Every peer is gated by a signed ed25519 invite from the mesh owner — the broker rejects anyone whose enrollment signature fails. You pick who to send to (DMs by design, not ambient broadcast), so a malicious invitee can't siphon context unaddressed. The broker can't read payloads, but it does see routing metadata. Revoking keys rotates the mesh.",
},
{
q: "Why a hosted broker instead of pure peer-to-peer?",
a: "Rendezvous + offline queueing. Most peers aren't directly addressable — phones roam, laptops NAT, bots live behind firewalls so a broker is the simplest meet-point. It also holds ciphertext for offline peers until they reconnect. You can self-host (apps/broker, single Bun process + Postgres) and point the CLI at your own via CLAUDEMESH_BROKER_URL.",
q: "Why a broker instead of pure peer-to-peer?",
a: "Rendezvous + offline queueing. Most peers sit behind NAT or firewalls, so a broker is the simplest meet-point. It also holds ciphertext for offline peers until they reconnect. Two deployment modes: hosted on claudemesh.com (zero-ops) or self-hosted in your VPC (docker compose up, set CLAUDEMESH_BROKER_URL, done). Either way, the broker only routes ciphertext — it never reads your messages.",
},
{
q: "Do I need Claude Code to use claudemesh?",

View File

@@ -68,8 +68,8 @@ export const HeroWithMesh = () => {
}}
>
Share context, files, skills, and MCPs across every Claude Code
session encrypted, with zero setup. The broker routes ciphertext.
It never reads your messages.
session end-to-end encrypted. Hosted on claudemesh.com or
self-hosted in your VPC. Same CLI, same wire, your choice.
</p>
</Reveal>

View File

@@ -1,10 +1,10 @@
import Link from "next/link";
import { Reveal, SectionIcon } from "./_reveal";
const SHIPPING = [
"CLI + 43 MCP tools (Claude Code integration)",
"Hosted broker on claudemesh.com",
"E2E encrypted messaging + file sharing",
const HOSTED_INCLUDES = [
"CLI + MCP server (same binary, every feature)",
"Hosted broker on wss://ic.claudemesh.com/ws",
"E2E encrypted messaging, files, skills, MCPs",
"Priority routing (now / next / low)",
"Shared state, memory, tasks, and streams",
"Per-mesh SQL database, vector search, and graph DB",
@@ -12,13 +12,15 @@ const SHIPPING = [
"Mesh invites + ed25519 identity",
];
const ROADMAP = [
"Mesh dashboard (browser UI)",
"Message history + retention controls",
"Audit log",
"Slack / WhatsApp / Telegram gateways",
"Self-host broker + SSO",
"Cross-broker federation",
const SELF_HOSTED_INCLUDES = [
"claudemesh-broker Docker image — one command",
"docker-compose.yml for full stack (broker + Postgres + Neo4j + Qdrant + MinIO)",
"All mesh data stays in your VPC — messages, memories, files, vectors, graph, SQL",
"Same CLI binary — point at your URL via CLAUDEMESH_BROKER_URL",
"SSO / SAML integration",
"Env var reference, backup/restore guide, upgrade procedures",
"Security hardening documentation",
"Air-gapped deployment support",
];
export const Pricing = () => {
@@ -33,31 +35,42 @@ export const Pricing = () => {
className="text-center text-[clamp(2rem,4.5vw,3.25rem)] font-medium leading-[1.1] text-[var(--cm-fg)]"
style={{ fontFamily: "var(--cm-font-serif)" }}
>
Get started with claudemesh
Two modes, same CLI
</h2>
</Reveal>
<Reveal delay={2}>
<p
className="mx-auto mt-4 max-w-[520px] text-center text-[15px] leading-[1.6] text-[var(--cm-fg-secondary)]"
className="mx-auto mt-4 max-w-[580px] text-center text-[15px] leading-[1.6] text-[var(--cm-fg-secondary)]"
style={{ fontFamily: "var(--cm-font-sans)" }}
>
Free during public beta. The CLI is MIT-licensed. The hosted
broker stays free while the roadmap ships. No billing today.
One binary. Pick where the broker runs. Hosted on claudemesh.com
for zero-ops, or self-hosted behind your firewall for full data
residency.
</p>
</Reveal>
<div className="mx-auto mt-16 grid max-w-[960px] gap-6 md:grid-cols-2">
{/* Hosted tier */}
<Reveal delay={3}>
<div className="mx-auto mt-16 max-w-[720px] rounded-[var(--cm-radius-md)] border border-[var(--cm-border)] bg-[var(--cm-bg-elevated)] p-8 md:p-10">
<div className="flex h-full flex-col rounded-[var(--cm-radius-md)] border border-[var(--cm-border)] bg-[var(--cm-bg-elevated)] p-8">
<div className="mb-6 flex items-baseline justify-between gap-4">
<div>
<div
className="mb-1 text-[10px] uppercase tracking-[0.18em] text-[var(--cm-clay)]"
style={{ fontFamily: "var(--cm-font-mono)" }}
>
Default
</div>
<h3
className="text-[28px] font-medium leading-tight text-[var(--cm-fg)]"
className="text-[24px] font-medium leading-tight text-[var(--cm-fg)]"
style={{ fontFamily: "var(--cm-font-serif)" }}
>
Public beta
Hosted
</h3>
</div>
<div className="text-right">
<div
className="text-[32px] font-medium text-[var(--cm-fg)]"
className="text-[28px] font-medium text-[var(--cm-fg)]"
style={{ fontFamily: "var(--cm-font-serif)" }}
>
Free
@@ -66,21 +79,22 @@ export const Pricing = () => {
className="text-xs text-[var(--cm-fg-tertiary)]"
style={{ fontFamily: "var(--cm-font-mono)" }}
>
no card required
during public beta
</div>
</div>
</div>
<div className="grid gap-8 md:grid-cols-2">
<div>
<div
className="mb-3 text-[10px] uppercase tracking-wider text-[var(--cm-fg-tertiary)]"
style={{ fontFamily: "var(--cm-font-mono)" }}
<p
className="mb-5 text-[13px] leading-[1.6] text-[var(--cm-fg-secondary)]"
style={{ fontFamily: "var(--cm-font-sans)" }}
>
Shipping today
</div>
<ul className="space-y-2">
{SHIPPING.map((item) => (
We run the broker. You run the CLI. Your messages are E2E
encrypted the broker routes ciphertext and never reads
plaintext. 99% of teams start here.
</p>
<ul className="flex-1 space-y-2">
{HOSTED_INCLUDES.map((item) => (
<li
key={item}
className="flex items-start gap-2 text-[13px] leading-[1.6] text-[var(--cm-fg-secondary)]"
@@ -91,33 +105,10 @@ export const Pricing = () => {
</li>
))}
</ul>
</div>
<div>
<div
className="mb-3 text-[10px] uppercase tracking-wider text-[var(--cm-fg-tertiary)]"
style={{ fontFamily: "var(--cm-font-mono)" }}
>
Roadmap · v0.2v0.3
</div>
<ul className="space-y-2">
{ROADMAP.map((item) => (
<li
key={item}
className="flex items-start gap-2 text-[13px] leading-[1.6] text-[var(--cm-fg-tertiary)]"
style={{ fontFamily: "var(--cm-font-sans)" }}
>
<span className="mt-[6px] block h-[6px] w-[6px] shrink-0 rounded-full border border-[var(--cm-fg-tertiary)]" />
<span>{item}</span>
</li>
))}
</ul>
</div>
</div>
<div className="mt-8 flex flex-col items-start gap-3 border-t border-[var(--cm-border)] pt-6 sm:flex-row sm:items-center sm:justify-between">
<div className="mt-8 border-t border-[var(--cm-border)] pt-6">
<p
className="text-[12px] leading-[1.5] text-[var(--cm-fg-tertiary)]"
className="mb-4 text-[12px] leading-[1.5] text-[var(--cm-fg-tertiary)]"
style={{ fontFamily: "var(--cm-font-sans)" }}
>
Paid tiers launch when the dashboard ships. Beta users keep
@@ -125,40 +116,85 @@ export const Pricing = () => {
</p>
<Link
href="/auth/register"
className="inline-flex shrink-0 items-center gap-2 rounded-[var(--cm-radius-xs)] bg-[var(--cm-fg)] px-5 py-2.5 text-sm font-medium text-[var(--cm-bg)] transition-colors hover:bg-[var(--cm-gray-150)]"
className="inline-flex w-full items-center justify-center gap-2 rounded-[var(--cm-radius-xs)] bg-[var(--cm-clay)] px-5 py-3 text-[15px] font-medium text-[var(--cm-fg)] transition-colors duration-300 hover:bg-[var(--cm-clay-hover)]"
style={{ fontFamily: "var(--cm-font-sans)" }}
>
Start free
<span className="transition-transform duration-300 group-hover:translate-x-0.5">
</span>
Start free
</Link>
</div>
</div>
</Reveal>
{/* Enterprise tier */}
{/* Self-hosted / Enterprise tier */}
<Reveal delay={4}>
<div className="mx-auto mt-6 max-w-[720px] rounded-[var(--cm-radius-md)] border border-dashed border-[var(--cm-border)] p-6 md:p-8">
<div className="flex flex-col items-start gap-4 sm:flex-row sm:items-center sm:justify-between">
<div className="flex h-full flex-col rounded-[var(--cm-radius-md)] border border-[var(--cm-border)] bg-[var(--cm-bg-elevated)] p-8">
<div className="mb-6 flex items-baseline justify-between gap-4">
<div>
<h3
className="text-[18px] font-medium text-[var(--cm-fg)]"
style={{ fontFamily: "var(--cm-font-serif)" }}
<div
className="mb-1 text-[10px] uppercase tracking-[0.18em] text-[var(--cm-fg-tertiary)]"
style={{ fontFamily: "var(--cm-font-mono)" }}
>
Enterprise
</div>
<h3
className="text-[24px] font-medium leading-tight text-[var(--cm-fg)]"
style={{ fontFamily: "var(--cm-font-serif)" }}
>
Self-hosted
</h3>
</div>
<div className="text-right">
<div
className="text-[20px] font-medium text-[var(--cm-fg)]"
style={{ fontFamily: "var(--cm-font-serif)" }}
>
Custom
</div>
<div
className="text-xs text-[var(--cm-fg-tertiary)]"
style={{ fontFamily: "var(--cm-font-mono)" }}
>
annual license
</div>
</div>
</div>
<p
className="mt-1 text-[13px] leading-[1.5] text-[var(--cm-fg-secondary)]"
className="mb-5 text-[13px] leading-[1.6] text-[var(--cm-fg-secondary)]"
style={{ fontFamily: "var(--cm-font-sans)" }}
>
Self-hosted broker. SSO. Custom SAML. Dedicated support.
Air-gapped deployment. SLA.
Run the broker in your VPC. Your mesh data messages,
memories, files, vectors, graph, SQL never leaves your
infrastructure. Same CLI, same features, your URL.
</p>
<ul className="flex-1 space-y-2">
{SELF_HOSTED_INCLUDES.map((item) => (
<li
key={item}
className="flex items-start gap-2 text-[13px] leading-[1.6] text-[var(--cm-fg-secondary)]"
style={{ fontFamily: "var(--cm-font-sans)" }}
>
<span className="mt-[6px] block h-[6px] w-[6px] shrink-0 rounded-full border border-[var(--cm-fg-tertiary)]" />
<span>{item}</span>
</li>
))}
</ul>
<div className="mt-8 border-t border-[var(--cm-border)] pt-6">
<div
className="mb-4 rounded-[var(--cm-radius-xs)] bg-[var(--cm-bg)]/60 px-4 py-3 text-[12px] leading-[1.5] text-[var(--cm-fg-secondary)]"
style={{ fontFamily: "var(--cm-font-mono)" }}
>
docker compose up -d
<br />
export CLAUDEMESH_BROKER_URL=wss://mesh.your-company.com/ws
<br />
claudemesh join
</div>
<a
href="mailto:info@claudemesh.com"
className="inline-flex shrink-0 items-center gap-2 rounded-[var(--cm-radius-xs)] border border-[var(--cm-fg-tertiary)] px-5 py-2.5 text-sm font-medium text-[var(--cm-fg)] transition-colors hover:border-[var(--cm-fg)] hover:bg-[var(--cm-bg-elevated)]"
className="inline-flex w-full items-center justify-center gap-2 rounded-[var(--cm-radius-xs)] border border-[var(--cm-fg-tertiary)] px-5 py-3 text-[15px] font-medium text-[var(--cm-fg)] transition-colors duration-300 hover:border-[var(--cm-fg)] hover:bg-[var(--cm-bg-elevated)]"
style={{ fontFamily: "var(--cm-font-sans)" }}
>
Contact sales
@@ -167,6 +203,7 @@ export const Pricing = () => {
</div>
</Reveal>
</div>
</div>
</section>
);
};

View File

@@ -38,7 +38,7 @@ const CARDS: Card[] = [
title: "The wire between Claude Code sessions",
theyDo:
"Every Claude Code session today is an island. Context dies with the terminal. Skills and MCPs are per-developer. Teammates relay insights through Slack.",
weDo: "claudemesh is one thing: a peer network for Claude Code. Share context, files, skills, MCPs, and slash commands across sessions — end-to-end encrypted. The broker routes ciphertext. It never reads your messages.",
weDo: "claudemesh is one thing: a peer network for Claude Code. Share context, files, skills, MCPs, and slash commands across sessions — end-to-end encrypted. Host the broker on claudemesh.com or run it in your VPC. Same CLI either way.",
tone: "claim",
},
];