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
2 changes: 1 addition & 1 deletion apps/blog/components.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"tsx": true,
"tailwind": {
"config": "",
"css": "src/app/global.css",
"css": "../../packages/ui/src/styles/globals.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/components.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"tsx": true,
"tailwind": {
"config": "",
"css": "src/app/global.css",
"css": "../../packages/ui/src/styles/globals.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
Expand Down
4 changes: 2 additions & 2 deletions apps/eclipse/components.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/styles/globals.css",
"config": "",
"css": "src/app/global.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
Expand Down
2 changes: 1 addition & 1 deletion apps/site/components.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"tsx": true,
"tailwind": {
"config": "",
"css": "src/app/global.css",
"css": "../../packages/ui/src/styles/globals.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
Expand Down
3 changes: 3 additions & 0 deletions apps/site/public/mcp/logos/chatgpt.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions apps/site/public/mcp/logos/claude-code.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions apps/site/public/mcp/logos/cursor.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/site/public/mcp/logos/gemini.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions apps/site/public/mcp/logos/vscode.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions apps/site/public/mcp/logos/warp.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions apps/site/public/mcp/logos/windsurf.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 15 additions & 1 deletion apps/site/src/app/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,21 @@
)
}

@keyframes mcp-cursor-blink {
0%,
48% {
opacity: 1;
}
52%,
100% {
opacity: 0;
}
}

.mcp-type-cursor {
animation: mcp-cursor-blink 1s step-end infinite;
}

@keyframes glitch-1 {
0% {
clip-path: inset(20% 0 60% 0);
Expand Down Expand Up @@ -86,4 +101,3 @@
clip-path: inset(75% 0 15% 0);
}
}

45 changes: 45 additions & 0 deletions apps/site/src/app/mcp/_components/agent-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import Image from "next/image";

export function AgentCard({
logo,
alt,
icon,
href,
}: {
logo: string | null;
alt: string;
icon: string | null;
href: string;
}) {
return (
<a
href={href}
title={alt}
aria-label={alt}
className="group relative flex h-30 w-full max-w-[165px] items-center justify-center rounded-[12px] border border-stroke-neutral bg-background-neutral-weaker shadow-box-low no-underline outline-offset-4 transition-[border-color,background-color,box-shadow] hover:border-stroke-ppg/60 hover:bg-background-default hover:shadow-box-high focus-visible:ring-2 focus-visible:ring-stroke-ppg dark:bg-background-neutral-weaker dark:hover:bg-background-neutral"
>
{logo ? (
<Image
src={logo}
alt=""
width={48}
height={48}
className="size-12 object-contain brightness-0 opacity-45 transition-opacity group-hover:opacity-65 dark:opacity-55 dark:invert"
unoptimized
/>
) : (
<span className="font-mono text-lg text-foreground-neutral-weak">
Any AI agent
</span>
)}
{icon ? (
<span
className="absolute right-1.75 top-1.75 text-foreground-neutral-weaker opacity-50 transition-opacity group-hover:opacity-100"
aria-hidden
>
<i className={`${icon} text-[16px]`} />
</span>
) : null}
</a>
);
}
112 changes: 112 additions & 0 deletions apps/site/src/app/mcp/_components/capability-cards.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { McpPromptBubble } from "./mcp-bubble";

const capabilityIconClass = "shrink-0 text-[24px] text-foreground-ppg";
const capabilityCardClass =
"relative flex w-full flex-col overflow-hidden rounded-[12px] border border-stroke-neutral bg-[linear-gradient(180deg,var(--color-background-default)_0%,var(--color-background-ppg)_262.5%)] shadow-box-low";
const capabilityHeaderClass = "flex items-center gap-4";
const capabilityDescriptionClass =
"max-w-full text-[16px] leading-6 text-foreground-neutral-weak";

function CapabilityCardContent({
icon,
title,
description,
}: {
icon: string;
title: string;
description: string;
}) {
return (
<div className="flex flex-col gap-4 p-4">
<div className={capabilityHeaderClass}>
<div className="flex size-12 shrink-0 items-center justify-center rounded-square bg-background-ppg">
<i className={`${icon} ${capabilityIconClass}`} aria-hidden />
</div>
<h4 className="stretch-display font-sans-display text-[20px] leading-7 font-black text-foreground-neutral">
{title}
</h4>
</div>
<p className={capabilityDescriptionClass}>{description}</p>
</div>
);
}

export function MobileCapabilityCard({
icon,
title,
description,
prompt,
mobileTall,
}: {
icon: string;
title: string;
description: string;
prompt: string;
mobileTall: boolean;
}) {
return (
<CapabilityCard
icon={icon}
title={title}
description={description}
prompt={prompt}
mobileTall={mobileTall}
size="compact"
/>
);
}

export function CapabilityCard({
icon,
title,
description,
prompt,
mobileTall = false,
size,
}: {
icon: string;
title: string;
description: string;
prompt: string;
mobileTall?: boolean;
size: "wide" | "compact";
}) {
const isWide = size === "wide";
const cardHeightClass = mobileTall
? "h-[227px] xl:h-[179px]"
: isWide
? "h-[203px] xl:h-[179px]"
: "h-[203px]";
const promptInsetClass = isWide
? "bottom-[14px] left-[14px] right-[14px] xl:bottom-[15px] xl:left-[16px] xl:right-[25px]"
: "bottom-[14px] left-[14px] right-[14px] xl:left-[16px] xl:right-[27px]";
const contentPadClass = mobileTall
? "pb-[104px] xl:pb-[60px]"
: isWide
? "pb-[80px] xl:pb-[60px]"
: "pb-[80px] xl:pb-[66px]";
const promptVariant = mobileTall
? "mobile-tall"
: isWide
? "wide"
: "compact";

return (
<div
className={`relative w-full ${cardHeightClass} ${isWide ? "xl:col-span-3" : "sm:col-span-1 xl:col-span-2"}`}
>
<div className={`${capabilityCardClass} h-full`}>
<div className={contentPadClass}>
<CapabilityCardContent
icon={icon}
title={title}
description={description}
/>
</div>
</div>
<div className={`absolute ${promptInsetClass}`}>
<McpPromptBubble variant={promptVariant}>{prompt}</McpPromptBubble>
</div>
</div>
);
}
48 changes: 48 additions & 0 deletions apps/site/src/app/mcp/_components/mcp-agents-section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Button } from "@prisma/eclipse";

import { AgentCard } from "./agent-card";

export type McpAgent = {
logo: string | null;
alt: string;
icon: string | null;
href: string;
};

export function McpAgentsSection({
docsHref,
agents,
}: {
docsHref: string;
agents: readonly McpAgent[];
}) {
return (
<section className="px-4 py-12 md:px-0">
<div className="mx-auto flex max-w-[790px] flex-col items-center gap-12 text-center">
<div className="flex max-w-[768px] flex-col items-center gap-4">
<h2 className="font-sans-display stretch-display font-black text-foreground-neutral text-3xl">
Works with your AI agent
</h2>
<p className="text-base leading-6 text-foreground-neutral-weak">
Works with any AI agent, whether you prefer to use a remote or a local server,
we&apos;ve got you.
</p>
</div>

<div className="grid w-full max-w-[368px] grid-cols-2 justify-items-center gap-4 min-[400px]:gap-8 md:max-w-[790px] md:grid-cols-4 md:gap-8">
{agents.map(({ logo, alt, icon, href }) => (
<AgentCard key={alt} logo={logo} alt={alt} icon={icon} href={href} />
))}
</div>

<Button
href={docsHref}
variant={"link"}
className="text-sm font-semibold text-foreground-ppg underline"
>
Want to see your tool listed?
</Button>
</div>
</section>
);
}
Loading
Loading