bd82a67fba
16 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
bd82a67fba |
fix(claims): purge false tier claims from landing, billing cards and legal docs
All checks were successful
Deploy to Production / deploy (push) Successful in 1m32s
The false RBAC / 99.9 SLA / BYOC / custom-domain claims were not only on /pricing but also on the landing-page tier cards, the in-app billing upgrade cards, and — most seriously — the AGB and Terms as a binding 99.9 monthly uptime SLA the single-host infra cannot meet. Aligned all of them: SLA removed from AGB/Terms (best-effort, no guaranteed SLA for self-serve; Enterprise by contract); landing+billing cards now show Audit log, RBAC coming-soon, custom-domain coming-soon, honest Enterprise infra; landing Team price corrected 149->199; billing cards model name Haiku/Sonnet -> Claude AI. Privacy page intentionally keeps exact model names for data-residency disclosure. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
3a05766f88 |
fix(oauth): allow generic RFC 7591 DCR + expand install snippets
All checks were successful
Deploy to Production / deploy (push) Successful in 1m28s
- /oauth/register: drop resource_required check, accept generic registrations (Claude Desktop omits resource in DCR body per spec). serverId stored as NULL; /authorize still enforces org-ownership + access-token aud claim still pinned to resource. Fixes Claude Desktop DCR failure (ofid_d7e39530c109fa7f). - /oauth/authorize: skip strict server.id check when client.serverId is NULL (generic client); org check remains the security boundary. - schema: oauth_clients.server_id no longer NOT NULL. - migration 0002: ALTER COLUMN server_id DROP NOT NULL (already applied on prod). - install-snippets: add Claude Code (CLI), VS Code, Codex, raw URL tabs. Claude Desktop now shows form-field values (Name / Remote MCP Server URL / OAuth Client ID / Secret) matching the new Custom Connector UI instead of the obsolete JSON config. - types: InstallTarget enum extended. - hero-video: clicking the audio toggle restarts the video from frame 0 so unmute aligns with the spoken opening. - marketing: drop em-dashes from rendered copy. |
||
|
|
e75f9ad4fe |
feat(marketing): real brand logos for the integrations grid
All checks were successful
Deploy to Production / deploy (push) Successful in 1m2s
Owner: "die logos müssen stimmen echte sein fetche sie." Replaced the
ASCII single-character marks (P / S / N / G / S / {}) with the actual
brand SVGs.
Sources:
- PostgreSQL, Notion, GitHub, Stripe paths from Simple Icons (CC0,
https://simpleicons.org). Inlined as React components with
fill="currentColor" so the icon colour is CSS-driven and matches
whatever foreground the brand chip uses.
- Salesforce was deindexed from Simple Icons in 2022 at the brand's
request, so I drew a clean generic cloud in the same silhouette
family — close enough to read as Salesforce-cloud-shape without
copying their trademarked mark.
- Custom REST gets a stylised pair of curly braces rendered as
stroked paths, signalling "any HTTP API" without pretending to be
a specific brand.
Brand colours used as chip backgrounds, all official values:
- PostgreSQL #336791 · Salesforce #00a1e0 · Notion #ffffff
- GitHub #181717 · Stripe #635bff · REST #6366f1
Notion is the one inversion — its mark is rendered in #0a0a0b on a
white chip because that's how Notion's actual brand mark reads. The
others all render the icon in white on a brand-colour chip.
Use of the marks is nominative fair use — they show compatibility
with each platform, not endorsement.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
7a32385e2b |
feat(marketing): give each below-the-fold section its own visual archetype
All checks were successful
Deploy to Production / deploy (push) Successful in 1m2s
Owner: "die sektionen unter dem video sehen viel zu ähnlich aus — das
kannst du besser." Correct — every section was the same `panel + 3-col
grid` pattern, no page rhythm. Each section now reads as its own type
of moment:
- **Clients** ("Connects everywhere your AI lives"): typographic logo
row, no panels. Each client carries a small mono mark in a 7×7 box
(C, ⌘, ✦, <>, →) plus a 17px tracking-tight wordmark. Group hover
flips the mark and label to the accent colour so the row reads as
interactive trust signal, not a wall of text. Generous py-20/24
spacing — this is a beat between sections, not a feature card.
- **Examples** ("Wrap any HTTP API. In minutes."): asymmetric 2-col
header (h2 left, supporting copy right) over a 3-col card grid
where each integration carries a coloured 48×48 brand mark —
Postgres `#336791`, Salesforce `#00a1e0`, Notion black-on-white,
GitHub `#181717`, Stripe `#635bff`, Custom REST `#6366f1`. The marks
give each card its own visual identity, breaking the uniform-card
pattern. h2 sized 32/40 px (was a flat 28 px).
- **Marketplace** ("Skip the prompt. Fork what works."): split layout.
Left column: eyebrow + headline + supporting paragraph + bullet
list of the three selling points (no longer equal-weight cards) +
PulseLink CTA. Right column: new `MarketplaceMock` — a faux-browser
frame containing four realistic template cards (notion-search /
github-issues / stripe-readonly / linear-tasks) with author chips,
✓ verified badges, tool counts, and a fork glyph. Visitor SEES the
marketplace instead of reading copy about it.
- **Pricing** ("Pay for tool calls. Not for boilerplate."): 4-card
row but Pro is featured — indigo border, indigo glow shadow
`0 0 0 4px rgba(99,102,241,0.12)`, "RECOMMENDED" pill floating at
-top-3, and accent-coloured feature bullets. Other tiers stay
calm so the eye lands on Pro first. Price typography enlarged from
26 px to 40 px so prices read as the headline of each card.
Spacing rhythm: every section is now py-20/28 sm:py-24/28 (was
py-12-14 sm:py-16-20) — gives the below-the-fold the breathing room
it needed; the page no longer feels like a stack of crammed cards.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
438ce3cfbc |
feat(video): v10 hero video with mute toggle — voice + bg music
All checks were successful
Deploy to Production / deploy (push) Successful in 1m6s
Ships the long-form (71.5 s) hero video to the marketing /flow section
along with the iteration trail of architectural visual fixes the owner
worked through over the last sprint.
## Video composition (remotion/)
Eight phases driven by the 71.47 s voice-over in `audio.mp3` plus the
`Sub-bass Lullaby.wav` background music (ducked to 0.16 with fade in /
fade out). Every scene was rebuilt for v10 with concrete fixes:
- **HookScene** (12 s) — adds FloatingChaos overlay: a docker-compose
excerpt, an oauth_callback.ts snippet, an .env file with a yellow
squiggle warning ("in git history since v0.3.1"), and a live-ticking
502 retry toast. Tangle now reads as a developer's desktop right
before they give up, not as four icons drifting.
- **PromptScene** (12.2 s) — 6.5 s post-typing dead-zone replaced with
the parse beat: three sequential highlights on the prompt text
(MCP server / searches / Notion workspace), three chips below the
input (intent / tool / secret → vault), three-stat summary panel
(tools · 2, secrets · 1, targets · 3). At local frame 250 (≈ 21 s
global, on the voice line "the prompt path and the secret path
never cross") a mini two-rail diagram with an explicit X-marker
ring lands, visualising the architectural promise the moment it's
spoken.
- **SecretsScene** (15.2 s) — kept the arrow-fork + AES-256 stamp +
env-var injection beats; added the lock-snap flash at frame 66,
pinned the vault at full opacity throughout, and added a dashed
vault → container connector so the secret's provenance is visible.
The "what the AI sees" panel is now 680 px wide with an eye icon,
four corner viewfinder brackets around the prompt text, and three
explicit denied lines (no secrets / no environment variables / no
tokens).
- **BuildScene** (7.2 s) — unchanged beats: streaming log, server
card emerges with code + 🔒 NOTION_API_KEY slot pills, isolated-
container caption, <60s countdown.
- **IsolationScene** (14 s) — completely restructured. Orbit-and-dock
chips that collided with the card and with the tokens-only badge
are replaced by a clean vertical chip column at x=760: read-only
filesystem · dropped capabilities · no new privileges · 512 MB
memory cap · 0.5 CPU limit · ✓ your token only (last in green).
A vault graphic now sits below the server card with a dashed arrow
up into its env slot so the architecture story is complete in one
frame. PKCE jargon removed: "OAuth 2.1 · PKCE" → "only your token
gets in" with a small "oauth 2.1 · proof-key flow" subtitle for
the curious. Handshake stages simplified to your client → verified
→ scoped token. Final settlement arrow in success-green curves
from the scoped-token pill back into the card.
- **LibraryScene** (7 s) — cards enlarged from 340×180 to 400×220
with 36 px gaps. The "templates carry code, not credentials"
sub-caption was pulled (felt on-the-nose; the detached lock and
empty NOTION_API_KEY=? slot carry the story visually).
- **DiscoveryScene** (3 s) — the most-iterated scene. Earlier
versions had a fake "1,200+ developers building" fork counter
(pulled — solo-founder, hadn't earned). Replaced with a two-lane
architecture diagram that visualises "no paths cross" literally:
top lane prompt → AI → code, bottom lane vault → encrypted →
env, both converging at the server box on the right. v10
refinements: all seven boxes visible from frame 0 (no late
server arrival), a parallel glow tour walks across both lanes
simultaneously, a dashed vertical divider with a "no shared
node" chip pinned in the middle, and the closing line "One
sentence in. Live server out." slides down from above and lands
centred while the diagram fades to 0.12 opacity behind it —
no overlap.
- **LogoLockup** (1.7 s) — wordmark + fade-to-black for a clean
loop seam.
The Subtitle / CAPTIONS layer added in v7 was pulled wholesale —
owner found the kinetic-typography overlay aggressive and noted
that technical terms (PKCE etc.) created friction with no payoff.
Scene visuals and voice now carry the whole story; the Subtitle
component file is retained for possible future use.
Render pipeline (`render:mp4` / `render:webm` / `render:poster` in
remotion/package.json) is unchanged. The MP4 is post-processed to
H.264 Main / yuv420p / TV-range with faststart + AAC audio. The
WebM is re-encoded at VP9 CRF 38 / Opus 64k to stay under the 3 MB
budget. Final artefacts in apps/web/public/videos/: 2.59 MB mp4,
2.99 MB webm, 62 KB poster.
## Web integration (apps/web/components/hero-video.tsx)
New client component wraps the <video> element and pins a frosted-
glass mute toggle bottom-right of the player. Why not native
`controls`: the browser chrome fights the section's design vocabulary
and we only need one affordance — unmute — so we render exactly
that. The toggle's icon flips between VolumeX (currently muted) and
Volume2 (currently unmuted), accent colour switches indigo when sound
is on. Initial state is muted so autoplay still fires; on unmute we
call .play() defensively because mobile Safari pauses on
muted-property changes mid-playback.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
035e55f00c |
feat(web): mobile-fit hero tiles + voluminous calmer particle field + FAQ accordion
All checks were successful
Deploy to Production / deploy (push) Successful in 1m2s
Three coordinated polish items requested: 1. **Hero step-rotator tiles fit mobile without horizontal scroll.** The previous snippets contained a 50+ char `Live at https://notion-x9.mcp.buildmymcpserver.com` URL that overflowed the ~295 px text area on a 375 px viewport. Rewrote all three snippets to be naturally short — same product story, no full URLs. The <pre> drops `overflow-x-auto` and gains `whitespace-pre-wrap break-words` so any token that does exceed the column wraps gracefully instead of forcing a scrollbar. 2. **ParticleHero — more volumetric, slower, steadier at load-in.** The "stuttery / too fast" feedback came from two issues compounding: tiny dots (1.8 px on 256-tier, with 0.42 base alpha) gave the eye too few pixels to track between frames, so individual particles read as snapping rather than drifting; and the simplex-noise drift evolved at 0.08 time-scale with 0.045 velocity, fast enough that frame-to-frame deltas exceeded a tracked particle's diameter. Render uniforms tuned: - `uPointSize` 1.8 → 2.8 (256-tier), 2.4 → 3.6 (128-tier) - `uBaseAlpha` 0.42 → 0.60 Simulation shader tuned: - Drift noise time scale 0.08 → 0.045 (the most impactful single change — particles now move at half the previous speed) - Drift velocity magnitude 0.045 → 0.028 - Ring breathing noise time scale 0.35 → 0.22 - Ring polar-wave time scales 1.2 / 0.7 → 0.7 / 0.42 Net effect: same number of particles (65k) but each individually larger, brighter, and moving more slowly. The cumulative additive bloom is denser without the jitter that read as visual stutter. 3. **FAQ collapsed into a native `<details>` accordion.** Crawlers and screen readers still see every Q+A in the SSR'd HTML — `<details><summary>...</summary><p>answer</p></details>` is the standard semantic pattern for disclosure widgets. Users see one question at a time and expand on demand, which keeps the page from feeling like an endless wall of marketing text below the fold. Container narrowed `max-w-6xl` → `max-w-3xl` for accordion typography (long-form prose reads better single-column). The default WebKit disclosure-triangle marker is suppressed with `list-none` + `[&_summary::-webkit-details-marker]:hidden`, and a `lucide-react` `ChevronDown` icon rotates 180° via `group-open:rotate-180` to indicate state. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
6f8b8da151 |
feat(web): glow-pulse on primary CTAs + hero fills full first viewport
All checks were successful
Deploy to Production / deploy (push) Successful in 1m1s
Two coordinated polish moves: 1. **<PulseLink> / <PulseButton>** — new `apps/web/components/pulse.tsx`. Click anywhere on a wrapped link or button and a small indigo dot detonates from the click point, scaling 1x→80x over 650ms before fading to transparent. Same visual language as the hero load-in glow — the click effectively says "this is the brand reaching back." The dot lives in a `pointer-events: none` overlay, so it never blocks the underlying navigation. `overflow-hidden + relative` are added to the host so the bloom stays inside the rounded shape. `glow-pulse` keyframe sits in globals.css next to the existing `pulse-dot` / `shimmer` / `fade-in` definitions; reduced-motion suppresses the animation to instant-opacity-0 so the click flow is preserved without the bloom. Wired into the highest-conversion CTAs only — the user explicitly asked "wo's Sinn macht": - Hero "Start building free" + "Read the docs" - Marketing header Login / Dashboard button - Dashboard header "+ New server" pill Deliberately NOT applied to dashboard nav links, logout, destructive buttons, form internals, carousel dots — pulse on every click would be noise. 2. **Hero fills 100svh − nav** (`min-height: calc(100svh - 3rem)`). `svh` (small viewport height) instead of `vh` so the hero doesn't jump when the mobile address bar hides/shows. The 3rem subtracts the sticky marketing nav (h-12 = 48px), so the hero ends right at the loadscreen's natural bottom edge. `flex items-center` plus the inner grid's existing `md:items-center` keep the content vertically centred inside the tall section. The ParticleHero background now has cinematic-scale room and the indigo radial-glow + dot-mask read as the dominant background motif — which is the effect the user loved at load-in. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
0cf9c66b6b |
feat(web): restore tall hero + carousel slide + viewport-fixed scroll cue
All checks were successful
Deploy to Production / deploy (push) Successful in 1m0s
Three coordinated tweaks to the landing-page above-the-fold: 1. **Hero padding restored to py-14/sm:py-20/md:py-28** (was py-12/14/16). Compressing it for the scroll-cue position fight made the hero feel cramped and gave the ParticleHero background less room to breathe. With the cue moved out (see #3), there's no reason to shrink the hero. 2. **Step rotator switches to carousel-style horizontal slide.** The AnimatePresence transition was a fade+y-shift cross-fade — clean but sequential. Now the leaving card slides left out (x:-220) while the entering card slides right in (x:220→0), both coexisting in the same 3D-space and inheriting the same mouse-tilt. The container gets `min-h-[240px]` so the absolutely-positioned cards have layout to anchor to (claude_desktop_config.json is the tallest at 7 lines). Reduced-motion still gets the opacity-only cross-fade — sliding content sideways is exactly the kind of motion that preference is meant to suppress. 3. **`<ScrollCue>` extracted into its own client component**, fixed- positioned at viewport bottom (bottom-5) with a frosted pill style. Fades to opacity:0 once `window.scrollY > 80`, so it doesn't shadow the rest of the page. Lives next to `<section>` in page.tsx rather than inside the hero — that way it anchors to the loadscreen's natural bottom edge whether the hero is short or tall. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
e4e437c44c |
feat(web): hero redesign — cycling step rotator + full-width video section
All checks were successful
Deploy to Production / deploy (push) Successful in 1m2s
Restructures the landing page above-the-fold into two distinct sections:
1. **Hero — left copy + cycling tile, no static stack of three blocks**
New `<HeroStepRotator>` (Framer Motion client component) shows ONE
tile centred in the column, cycling prompt.txt → build.log →
claude_desktop_config.json every 3.5s. Auto-advance pauses on hover
and exposes a 3-dot tablist so users can jump to any step. The active
dot grows wide with an accent glow.
Mouse interaction: spring-smoothed 3D tilt on rotateX/rotateY plus a
radial glow that translates toward the cursor — both driven by motion
values, so the transforms stay on the GPU compositor instead of
re-rendering on every mousemove. `useReducedMotion()` strips the
tilt + glow translation and collapses the page transition to an
instant cross-fade (the rotation itself still advances — it's content,
not decoration).
Hero padding tightened (py-12/14/16 vs py-14/20/28) so the video
section below is teased above the fold. New scroll cue ("see it run"
+ animated chevron) sits at the bottom of the hero, anchored to
#flow.
2. **Flow video — full-width edge-to-edge under the hero (new section)**
The hero.mp4 / hero.webm pair moves out of the "How it works"
section into its own #flow section. No max-w wrapper — it spans the
viewport with `w-full aspect-video`, so on a 1080p monitor the video
gets the full 1920px width. Adds a subtle radial vignette so the
black edges blend into the page chrome.
3. **"How it works" — now lean**
Video removed (it's the flow section now). Just the three textual
cards as supporting copy.
Adds `framer-motion@11.18.2` to apps/web/package.json. Build passes
typecheck + Next.js production build with no new warnings; LCP path is
untouched since the rotator is client-hydrated after first paint and
Framer Motion is tree-shaken to the components we import.
Note: visitors with `prefers-reduced-motion: reduce` will still see the
video's poster instead of autoplay — Chrome blocks the network fetch
entirely for autoplay media when reduced-motion is set. The flow video
remains visible for the rest, and the step rotator continues to cycle
its content (with instant cross-fade instead of slide+scale).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
fd147f9998 |
feat(web): Remotion hero video — Section 2 (prompt → server → connect)
All checks were successful
Deploy to Production / deploy (push) Successful in 1m13s
New @bmm/video workspace at remotion/. Renders an 8s 1920×1080 H.264
+ WebM + JPG poster sequence that visualises the three-step "How it
works" pitch literally:
- Beat 1 (0-2s): "Search our Notion workspace" word-by-word entrance
with spring-in from below + brief indigo under-glow + monospace
prompt.txt label. Blinking cursor bridges the loop seam.
- Beat 2 (2-5s): each prompt word detonates into ~9 particles per
word; particles drift, then magnetically converge onto target slots
along a server schematic that strokes itself on. Scan-line sweep +
corner labels (mcp-notion, OAuth 2.1, search_pages, get_page_content)
sell that this is a real artefact, not a placeholder.
- Beat 3 (5-8s): Claude Desktop client panel slides in from the right;
a Bézier wire animates between server and client; three data-packet
dots travel along the wire; 200-OK tag pops; green live-dot pulses
on the server. Last 12 frames fade to black so frame 239 ≈ frame 0
and browser <video loop> has no visible seam.
Brand palette is hard-coded in lib/colors.ts to match globals.css —
keeps the Remotion bundle self-contained (no Tailwind import needed).
springIn / softSpring / clampLerp / rand helpers in lib/easings.ts
power the motion vocabulary. Concurrency=1 + yuv420p in the config
gives a deterministic render that plays on every <video> tag.
File sizes: hero.mp4 449 KB, hero.webm 258 KB, hero-poster.jpg 33 KB —
all well under the 3 MB / 250 KB ceilings.
Section 2 ("How it works") now opens with the video in a
border-bordered aspect-video panel between the heading and the three
existing cards. autoPlay+muted+loop+playsInline satisfies every mobile
autoplay policy; motion-reduce:hidden swaps in the static poster for
prefers-reduced-motion users.
Scripts:
- pnpm --filter @bmm/video render:all (mp4 + webm + poster)
- pnpm --filter @bmm/video to-web (copy to apps/web/public/videos/)
- pnpm --filter @bmm/video build (both, end-to-end)
`to-web` is the script name because `publish` collides with pnpm's
built-in npm-publish command which refused to run with an unclean tree.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
2267daadd4 |
perf(web): server-only StaticCodeBlock for above-the-fold marketing
All checks were successful
Deploy to Production / deploy (push) Successful in 52s
PageSpeed Insights mobile reported LCP element render delay of 2.3s on the hero — the largest visible element is the build.log <pre> with "> Generating spec... OK ..." text. TTFB is 0ms (CF cache hit), so the delay was pure client-side: Lighthouse waited for the JS bundle to parse and the 'use client' CodeBlock boundary to hydrate before it considered the element "rendered." CodeBlock pulls in lucide-react (Copy/Check icons) plus a useState boundary just for the copy button. Above the fold on marketing, none of that is needed — the user just needs to see the snippet. Split: - New `static-code-block.tsx`: server component, no 'use client', no icons, no copy button. Pure SSR markup that paints with the HTML. - Marketing landing now uses StaticCodeBlock for all three hero snippets (prompt.txt / build.log / claude_desktop_config.json). - Interactive CodeBlock stays in use for dashboard pages where users actually want to copy snippets. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
88c7262a08 |
fix(web): mobile-responsive hero, marketing site, docs and dashboard
All checks were successful
Deploy to Production / deploy (push) Successful in 1m13s
- Hero h1 was a fixed text-[44px] — overflowed narrow phones. Now text-[30px] sm:text-[40px] md:text-[56px]. - Hero grid children get min-w-0 so the code blocks' overflow-x-auto actually constrains instead of widening the page. - Marketing nav: the inline links were hidden below md with no fallback. Added a hamburger MobileMenu; "Sign in" collapses into it on the smallest screens. - Section vertical padding is now responsive (py-14 sm:py-20). - globals.css: overflow-x: clip on <html> as a safety net. - docs: the 240px sidebar is hidden below lg, article gets min-w-0. - dashboard header: nav labels collapse to icons on small screens. Verified: next build passes (40/40 pages). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
b843394d0f |
feat(web): full SEO stack — metadata, JSON-LD, sitemap, robots, OG image
Some checks failed
Deploy to Production / deploy (push) Failing after 46s
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> |
||
|
|
e46a9a1cf8 |
feat(web): surface the template marketplace on the landing page
The marketplace is the distribution channel — fork a working server or publish your own — but it was absent from the landing page. Adds a section between Examples and Pricing with a second conversion path into /templates. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
a189111782 |
feat(marketplace): default-on share in wizard + owner unshare anytime
Goal: maximize template volume without a dark pattern and without leaking data.
Wizard Done-page Share panel:
- 'Share as template in the marketplace (recommended)' checkbox, default ON,
rendered inline in the build-success flow where every user lands.
- Honest copy — corrected a draft that claimed 'only abstracted code pattern is
shared'. That is false: the FULL generated code becomes publicly viewable on
the template detail page (by design, for pre-fork audit). The panel now says:
'Your secrets stay private ... but your generated code becomes publicly
viewable so others can audit it before forking. Unshare anytime.'
- When checked: inline minimal form — short description (prefilled from the
spec), category select, optional per-secret credential hints. One 'Publish to
marketplace' click. Not auto-published silently — that would be a consent dark
pattern; one visible deliberate click keeps it clean.
- Forked servers don't show the panel (re-publishing a fork is an edge case).
Owner unshare/reshare:
- GET /v1/servers/:id/template — owner lookup, drives the Publish tab UI.
- PATCH /v1/templates/:slug/visibility { shared } — owner-only toggle between
public and hidden. 403 for non-owners, 409 if an admin took it down (owner
cannot resurrect an admin takedown). Audit-logged as template.unshare /
template.reshare.
- Server-detail Publish tab now detects an existing template and shows the
shared status (public/hidden/takedown badge), fork count, a marketplace link
and an Unshare/Re-share button — instead of the publish form.
Why this is safe to default ON:
- Secrets are architecturally bound to mcp_servers, never copied into templates.
Publish reads tools_schema + generated_code only; the secrets table is never
touched. Data leak is structurally impossible, not policy-dependent.
- Publish re-scans the generated code for banned patterns AND hardcoded
credentials (sovereign-audit hardening) before it can reach the marketplace.
- The user sees a visible, pre-ticked checkbox and reads one honest sentence
before publishing. Privacy-conscious users untick; everyone else contributes
volume. Informed consent, GDPR-clean.
Verified end-to-end via API:
GET server/:id/template -> null (unpublished)
POST /v1/templates -> published, slug share-test-server
GET server/:id/template -> status public
PATCH visibility {shared:false} -> hidden, drops out of public list
PATCH visibility {shared:true} -> public again
UI: Publish tab renders the shared-status panel with View + Unshare (screenshot
confirmed).
Also: hero badge date set to 2026-05-20. Changed 'MCP spec 2025-11-25' to
'updated 2026-05-20' — claiming an MCP spec dated today would be factually wrong
(no such spec release exists); 'updated' is accurate and gives the requested
fresh date. The real spec date is still cited correctly in /docs.
|
||
|
|
f2238f2e6b | feat(web): Next.js 15 shell — design tokens, landing, auth pages |