Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"devDependencies": {
"@biomejs/biome": "2.4.15",
"@clerk/clerk-react": "^5.61.8",
"@tabler/icons-react": "^3.45.0",
"@tailwindcss/vite": "^4.3.1",
"@types/inquirer": "^9.0.9",
"@types/node": "^22.10.0",
Expand Down
49 changes: 49 additions & 0 deletions src/ui-app/components/landing/CTABanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Button } from "../ui/Button";
import { Link } from "../ui/Link";

export function CTABanner() {
return (
<div
className="mb-4 md:mb-8 w-full shrink-0"
style={{
background: "linear-gradient(180deg, rgba(241, 231, 255, 0.8) 0%, #FFFFFF 100%)",
}}
>
<div className="flex flex-col items-center justify-center py-24 md:py-32 px-4">
<div className="flex flex-col items-center gap-6 text-center max-w-3xl">
<h2 className="font-sans text-[3.5rem] font-medium leading-[107%] tracking-tight text-[#2F2F37]">
Your observability data deserves better than a dashboard
</h2>
<p className="font-inter text-base font-normal text-black/60 leading-7 max-w-xl">
Connect Parseable to Claude, Cursor, or any MCP-compatible agent and investigate incidents across logs, metrics, traces, and alerts — in natural language, without switching context.
</p>
<div className="flex gap-3 mt-2 flex-wrap justify-center">
<Link
href="https://app.parseable.com"
target="_blank"
rel="noopener noreferrer"
>
<Button className="flex px-6 h-11 justify-center items-center gap-1 rounded-[8px] bg-[#3A3A8C] shadow-[0_1px_2px_0_rgba(20,21,26,0.05)] font-inter text-base font-medium text-white hover:bg-[#2F2F70]">
Explore Parseable
</Button>
</Link>
<Link
href="https://www.parseable.com/docs/mcp"
target="_blank"
rel="noopener noreferrer"
>
<Button
variant="secondary"
className="flex px-6 h-11 justify-center items-center gap-1 rounded-[8px] border border-[#DEE0E3] bg-white shadow-[0_1px_2px_0_rgba(20,21,26,0.05)] font-inter text-base font-medium text-[#14151A] hover:bg-gray-50"
>
Read the docs
</Button>
</Link>
</div>
</div>
</div>
</div>
);
}

// ─── Footer ───────────────────────────────────────────────────────────────────
105 changes: 105 additions & 0 deletions src/ui-app/components/landing/FeatureGrid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import {
IconBell,
IconBolt,
IconDatabase,
IconEye,
IconSearch,
IconShieldCheck,
} from "@tabler/icons-react";

const FEATURES = [
{
icon: <IconSearch size={20} stroke={1.5} aria-hidden="true" />,
iconColor: "#3A3A8C",
iconBg: "rgba(58,58,140,0.08)",
title: "Natural language querying",
desc: "Ask questions in plain English. The server translates them to SQL and runs against your Parseable datasets.",
},
{
icon: <IconBolt size={20} stroke={1.5} aria-hidden="true" />,
iconColor: "#D97706",
iconBg: "rgba(217,119,6,0.08)",
title: "Sub-second search",
desc: "Full-fidelity queries across millions of log events, powered by Parseable's columnar storage engine.",
},
{
icon: <IconDatabase size={20} stroke={1.5} aria-hidden="true" />,
iconColor: "#0891B2",
iconBg: "rgba(8,145,178,0.08)",
title: "Full tool surface",
desc: "Datasets, alerts, RBAC roles, and cluster health are all exposed — not just raw log search.",
},
{
icon: <IconShieldCheck size={20} stroke={1.5} aria-hidden="true" />,
iconColor: "#059669",
iconBg: "rgba(5,150,105,0.08)",
title: "Same auth as Parseable",
desc: "Uses your existing Parseable credentials or OAuth token. No separate secret management.",
},
{
icon: <IconEye size={20} stroke={1.5} aria-hidden="true" />,
iconColor: "#7C3AED",
iconBg: "rgba(124,58,237,0.08)",
title: "Dashboard-free investigation",
desc: "Debug production incidents, find anomalies, and correlate signals without switching context.",
},
{
icon: <IconBell size={20} stroke={1.5} aria-hidden="true" />,
iconColor: "#DC2626",
iconBg: "rgba(220,38,38,0.08)",
title: "Safety rails built in",
desc: "query_sql blocks all DDL and DML. Admin tools are read-only. You can't break production by asking.",
},
];

export function FeatureGrid() {
return (
<section
className="mt-40 w-full"
style={{
background:
"linear-gradient(180deg, #FFFFFF 0%, rgba(241, 231, 255, 0.8) 100%)",
}}
>
<div className="max-w-page mx-auto px-4 md:px-0">
<div className="flex flex-col items-center text-center gap-4 mb-14">
<h2
className="font-sans text-[3rem] font-medium leading-[112%] tracking-tight text-[rgba(0,0,0,0.76)]"
style={{ fontFamily: '"Open Sans", sans-serif' }}
>
Everything you need to investigate faster
</h2>
</div>

<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-5">
{FEATURES.map(({ icon, iconColor, iconBg, title, desc }) => (
<div
key={title}
className="flex flex-col gap-4 p-7 rounded-xl border border-black/[0.06] bg-white hover:border-black/[0.1] transition-all"
>
<div
className="w-10 h-10 rounded-lg flex items-center justify-center"
style={{ background: iconBg, color: iconColor }}
>
{icon}
</div>
<div className="flex flex-col gap-2">
<h3
className="font-sans text-base font-medium text-[#14151A]"
style={{ fontFamily: '"Open Sans", sans-serif' }}
>
{title}
</h3>
<p className="font-inter text-sm text-black/60 leading-6">
{desc}
</p>
</div>
</div>
))}
</div>
</div>
</section>
);
}

// ─── Prompts ──────────────────────────────────────────────────────────────────
33 changes: 33 additions & 0 deletions src/ui-app/components/landing/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Link } from "../ui/Link";

export function Footer() {
return (
<footer className="border-t border-black/[0.06] py-4">
<div className="max-w-page mx-auto px-4 md:px-0 flex flex-col sm:flex-row items-center justify-between gap-4">
<p className="font-inter text-sm text-black/40">
© {new Date().getFullYear()} Parseable, Inc.
</p>
<nav className="flex items-center gap-5" aria-label="Footer links">
{[
{ label: "Terms", href: "/tos" },
{ label: "Privacy", href: "/policy" },
{ label: "Docs", href: "https://www.parseable.com/docs/mcp" },
{ label: "GitHub", href: "https://github.com/parseablehq/parseable-mcp-server" },
].map(({ label, href }) => (
<Link
key={label}
href={href}
target={href.startsWith("http") ? "_blank" : undefined}
rel={href.startsWith("http") ? "noopener noreferrer" : undefined}
className="font-inter text-sm text-black/40 hover:text-[#14151A] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#3A3A8C] rounded"
>
{label}
</Link>
))}
</nav>
</div>
</footer>
);
}

// ─── Page ─────────────────────────────────────────────────────────────────────
30 changes: 30 additions & 0 deletions src/ui-app/components/landing/Hero.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export function Hero() {
return (
<section className="pt-32 pb-0">
<div className="max-w-page mx-auto px-4 md:px-0 flex flex-col items-center text-center gap-6">
{/* Badge */}
<div className="inline-flex items-center gap-2 px-3 py-1.5 rounded border border-black/8 bg-white">
<span className="w-1.5 h-1.5 rounded-full bg-[#00A896]" />
<span className="font-inter text-xs font-medium text-[#5E5F6E]">
Observability, meet AI
</span>
</div>

{/* H1 */}
<h1
className="max-w-3xl font-sans text-[2.75rem] md:text-[3.5rem] font-medium leading-[107%] tracking-tight text-[#2F2F37]"
style={{ fontFamily: '"Open Sans", sans-serif' }}
>
Parseable MCP Server
</h1>

{/* Description */}
<p className="max-w-2xl font-inter text-base text-black/60 leading-7">
Connect Claude, Cursor, or any MCP-compatible agent to Parseable.
Query terabytes of logs, metrics, and traces in natural language — at
sub-second speed.
</p>
</div>
</section>
);
}
64 changes: 64 additions & 0 deletions src/ui-app/components/landing/Nav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { useEffect, useState } from "react";
import { IconArrowUpRight, IconBrandGithub } from "@tabler/icons-react";
import { Image } from "../ui/Image";
import { Link } from "../ui/Link";

export function Nav() {
const [scrolled, setScrolled] = useState(false);

useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > 8);
onScroll();
window.addEventListener("scroll", onScroll, { passive: true });
return () => window.removeEventListener("scroll", onScroll);
}, []);

return (
<header
className={`fixed top-0 left-0 right-0 z-50 transition-all duration-200 ${
scrolled
? "bg-white/80 backdrop-blur-sm border-b border-black/[0.06]"
: "bg-transparent"
}`}
>
<div className="max-w-page mx-auto px-4 md:px-0 h-14 flex items-center justify-between">
<Link
href="https://parseable.com"
aria-label="Parseable home"
className="inline-flex items-center gap-2"
>
<Image
src="/assets/CompleteLogo.svg"
alt="Parseable"
width={180}
height={100}
priority
className="w-35 md:w-45"
/>
</Link>

<nav className="flex items-center gap-1" aria-label="MCP page navigation">
<Link
href="https://github.com/parseablehq/parseable-mcp-server"
target="_blank"
rel="noopener noreferrer"
aria-label="GitHub repository"
className="inline-flex items-center justify-center w-9 h-9 rounded-[6px] text-[#5E5F6E] hover:text-[#14151A] hover:bg-black/[0.04] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#3A3A8C]"
>
<IconBrandGithub size={18} stroke={1.5} aria-hidden="true" />
</Link>
<Link
href="https://www.parseable.com/docs/mcp"
target="_blank"
rel="noopener noreferrer"
className="ml-2 inline-flex items-center gap-1.5 px-4 h-9 rounded-[8px] bg-[#3A3A8C] font-inter text-sm font-medium text-white hover:bg-[#2F2F70] shadow-[0_1px_2px_0_rgba(20,21,26,0.05)] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#3A3A8C] focus-visible:ring-offset-2"
>
Docs <IconArrowUpRight size={14} aria-hidden="true" />
</Link>
</nav>
</div>
</header>
);
}

// ─── Hero ─────────────────────────────────────────────────────────────────────
Loading
Loading