From 9434551e4eee9e36fbea4d7dfb421f3ef5be96fb Mon Sep 17 00:00:00 2001 From: Marcelo Kunze Date: Mon, 1 Dec 2025 11:26:47 -0300 Subject: [PATCH 1/8] Update Hero3D and Navbar components for improved clarity and navigation - Changed headings and descriptions in Hero3D to emphasize pay-per-use model. - Updated button labels and links in Hero3D for better alignment with new messaging. - Modified Navbar to reflect changes in navigation options, replacing 'REGISTER' with 'MONETIZE' and adjusting link paths accordingly. --- apps/app/src/components/custom-ui/hero-3d.tsx | 26 ++++++++++--------- apps/app/src/components/custom-ui/navbar.tsx | 18 ++++++------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/apps/app/src/components/custom-ui/hero-3d.tsx b/apps/app/src/components/custom-ui/hero-3d.tsx index ceebaaa..c8b7574 100644 --- a/apps/app/src/components/custom-ui/hero-3d.tsx +++ b/apps/app/src/components/custom-ui/hero-3d.tsx @@ -120,10 +120,11 @@ export default function Hero3D({ variants={fadeUp} >

- Payments infrastructure for the agent economy + Pay cents per tool call instead of subscriptions

- In one minute, add our open-source proxy to your APIs or MCPs and get discovered and paid by autonomous agents. + Single connection to use paid MCP tools across any client.
+ Pay-per-use instead of expensive subscriptions.

@@ -139,14 +140,14 @@ export default function Hero3D({ animate={isMounted ? "visible" : "hidden"} variants={fadeUp} > - + - + @@ -226,24 +227,25 @@ export default function Hero3D({ > {/* Heading */}

- Payments infrastructure for the agent economy + Pay cents per tool calls instead of subscriptions

{/* Subheading */}

- In one minute, add our open-source proxy to your APIs or MCPs and get discovered and paid by autonomous agents. + Single connection to use paid MCP tools across any client.
+ Pay-per-use instead of expensive subscriptions.

{/* CTAs */}
- + - +
diff --git a/apps/app/src/components/custom-ui/navbar.tsx b/apps/app/src/components/custom-ui/navbar.tsx index 3a6a33c..67c2d18 100644 --- a/apps/app/src/components/custom-ui/navbar.tsx +++ b/apps/app/src/components/custom-ui/navbar.tsx @@ -71,7 +71,7 @@ export default function Navbar() { - {/* Center (desktop only): BROWSE / EXPLORER / REGISTER */} + {/* Center (desktop only): BROWSE / MONETIZE / EXPLORER */}
@@ -172,18 +172,18 @@ export default function Navbar() { - EXPLORER + MONETIZE - REGISTER + EXPLORER From 7d3eb9ca086e42e1cce15387494021781c61530a Mon Sep 17 00:00:00 2001 From: Marcelo Kunze Date: Wed, 3 Dec 2025 16:33:51 -0300 Subject: [PATCH 2/8] Reorganize sections in MCPBrowser component for improved layout - Moved DeveloperInfo and Stats sections to a new position for better flow and visibility. - Ensured ConsumerInfo and FAQSection remain accessible while enhancing overall structure. --- apps/app/src/app/page.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/app/src/app/page.tsx b/apps/app/src/app/page.tsx index eb236e0..5c02c56 100644 --- a/apps/app/src/app/page.tsx +++ b/apps/app/src/app/page.tsx @@ -125,14 +125,6 @@ export default function MCPBrowser() { -
- -
- -
- -
-
@@ -151,6 +143,14 @@ export default function MCPBrowser() { +
+ +
+ +
+ +
+
From 25df82bac796be865b2bbafb4b4f29c8256c0c98 Mon Sep 17 00:00:00 2001 From: Marcelo Kunze Date: Wed, 3 Dec 2025 16:48:14 -0300 Subject: [PATCH 3/8] typo --- apps/app/src/components/custom-ui/hero-3d.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/app/src/components/custom-ui/hero-3d.tsx b/apps/app/src/components/custom-ui/hero-3d.tsx index c8b7574..e5562f3 100644 --- a/apps/app/src/components/custom-ui/hero-3d.tsx +++ b/apps/app/src/components/custom-ui/hero-3d.tsx @@ -227,7 +227,7 @@ export default function Hero3D({ > {/* Heading */}

- Pay cents per tool calls instead of subscriptions + Pay cents per tool call instead of subscriptions

{/* Subheading */} From 7697d8e6fb7a208c795cf8ad4d4add9dcb922631 Mon Sep 17 00:00:00 2001 From: Marcelo Kunze Date: Wed, 3 Dec 2025 17:59:12 -0300 Subject: [PATCH 4/8] Update ConsumerInfo and DeveloperInfo components for clarity and new messaging - Changed headings in ConsumerInfo to emphasize MCP server consumption. - Updated DeveloperInfo heading to reflect the provision of paid endpoints. - Added McpExampleCard to ConsumerInfo for enhanced user guidance. - Modified Hero3D component headings to focus on payments infrastructure. --- apps/app/public/x-logo.svg | 3 + .../components/custom-ui/consumer-info.tsx | 12 +- .../components/custom-ui/developer-info.tsx | 2 +- apps/app/src/components/custom-ui/hero-3d.tsx | 4 +- .../components/custom-ui/highlighter-text.tsx | 2 + .../components/custom-ui/mcp-example-card.tsx | 339 ++++++++++++++++++ 6 files changed, 355 insertions(+), 7 deletions(-) create mode 100644 apps/app/public/x-logo.svg create mode 100644 apps/app/src/components/custom-ui/mcp-example-card.tsx diff --git a/apps/app/public/x-logo.svg b/apps/app/public/x-logo.svg new file mode 100644 index 0000000..437e2bf --- /dev/null +++ b/apps/app/public/x-logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/app/src/components/custom-ui/consumer-info.tsx b/apps/app/src/components/custom-ui/consumer-info.tsx index e0e2808..265dd15 100644 --- a/apps/app/src/components/custom-ui/consumer-info.tsx +++ b/apps/app/src/components/custom-ui/consumer-info.tsx @@ -5,6 +5,7 @@ import { cn } from "@/lib/utils" import HighlighterText from "./highlighter-text" import InfoCard from "./info-card" import { ChartLine, DoorOpen, PiggyBank } from "lucide-react" +import McpExampleCard from "./mcp-example-card" interface ConsumerInfoProps extends React.HTMLAttributes { className?: string @@ -26,14 +27,17 @@ export default function ConsumerInfo({ {/* Header */}
- FOR ANY HUMAN + CONSUME MCP SERVERS
-

- Let your agents transact.{" "} - Fund your account with FIAT and use any paid MCP. +

+ Pay cents per tool call.{" "} + Instead of expensive subscriptions. Consume any paid MCP with a single account.

+ {/* MCP Example Card */} + + {/* Info Cards Grid */}
- FOR BUSINESSES & DEVELOPERS + PROVIDE PAID ENDPOINTS

The AI Gateway for your app.{" "} diff --git a/apps/app/src/components/custom-ui/hero-3d.tsx b/apps/app/src/components/custom-ui/hero-3d.tsx index e5562f3..0e24384 100644 --- a/apps/app/src/components/custom-ui/hero-3d.tsx +++ b/apps/app/src/components/custom-ui/hero-3d.tsx @@ -120,7 +120,7 @@ export default function Hero3D({ variants={fadeUp} >

- Pay cents per tool call instead of subscriptions + Payments infrastructure for the agent economy

Single connection to use paid MCP tools across any client.
@@ -227,7 +227,7 @@ export default function Hero3D({ > {/* Heading */}

- Pay cents per tool call instead of subscriptions + Payments infrastructure for the agent economy

{/* Subheading */} diff --git a/apps/app/src/components/custom-ui/highlighter-text.tsx b/apps/app/src/components/custom-ui/highlighter-text.tsx index 4c763a0..d9a66f2 100644 --- a/apps/app/src/components/custom-ui/highlighter-text.tsx +++ b/apps/app/src/components/custom-ui/highlighter-text.tsx @@ -11,6 +11,7 @@ const highlighterTextVariants = cva( default: "bg-muted text-muted-foreground", blue: "text-blue-700 bg-blue-500/10 dark:text-blue-200 dark:bg-blue-800/50", amber: "text-amber-700 bg-amber-500/10 dark:text-amber-200 dark:bg-amber-800/50", + red: "text-red-700 bg-red-500/10 dark:text-red-200 dark:bg-red-800/50", }, }, defaultVariants: { @@ -27,6 +28,7 @@ const highlighterIconVariants = cva( default: "bg-muted text-muted-foreground", blue: "text-blue-700 bg-blue-500/10 dark:text-blue-200 dark:bg-blue-800/50", amber: "text-amber-700 bg-amber-500/10 dark:text-amber-200 dark:bg-amber-800/50", + red: "text-red-700 bg-red-500/10 dark:text-red-200 dark:bg-red-800/50", }, }, defaultVariants: { diff --git a/apps/app/src/components/custom-ui/mcp-example-card.tsx b/apps/app/src/components/custom-ui/mcp-example-card.tsx new file mode 100644 index 0000000..af85f30 --- /dev/null +++ b/apps/app/src/components/custom-ui/mcp-example-card.tsx @@ -0,0 +1,339 @@ +"use client" + +import * as React from "react" +import { useState, useEffect, useMemo } from "react" +import { cn } from "@/lib/utils" +import HighlighterText from "./highlighter-text" +import { Button } from "@/components/ui/button" +import Link from "next/link" +import { PlugZap } from "lucide-react" +import { ToolExecutionModal, type ToolFromMcpServerWithStats } from "./tool-execution-modal" +import { mcpDataApi } from "@/lib/client/utils" +import { Spinner } from "@/components/ui/spinner" +import Image from "next/image" + +interface McpExampleCardProps extends React.HTMLAttributes { + className?: string + serverId?: string +} + +// Example tool data matching the structure from server-page-client +const exampleTools: Array<{ + id: string + name: string + description: string + inputSchema?: Record + paymentHint?: boolean + paymentPriceUSD?: number + paymentNetworks?: Array<{ + network: string + recipient: string + maxAmountRequired: string + asset: { address: string; symbol?: string; decimals?: number } + type: 'evm' | 'svm' + }> +}> = [ + { + id: "getUserInfo", + name: "getUserInfo", + description: "Retrieve user profile information by username or user ID", + paymentHint: true, + paymentPriceUSD: 0.01, + paymentNetworks: [{ + network: "base", + recipient: "0x0000000000000000000000000000000000000000", + maxAmountRequired: "1000000", + asset: { address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", symbol: "USDC", decimals: 6 }, + type: "evm" + }] + }, + { + id: "getUserTweets", + name: "getUserTweets", + description: "Fetch recent tweets from a specific user", + paymentHint: true, + paymentPriceUSD: 0.02, + paymentNetworks: [{ + network: "base", + recipient: "0x0000000000000000000000000000000000000000", + maxAmountRequired: "2000000", + asset: { address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", symbol: "USDC", decimals: 6 }, + type: "evm" + }] + }, + { + id: "advancedTweetSearch", + name: "advancedTweetSearch", + description: "Search tweets with advanced filters and parameters", + paymentHint: true, + paymentPriceUSD: 0.03, + paymentNetworks: [{ + network: "base", + recipient: "0x0000000000000000000000000000000000000000", + maxAmountRequired: "3000000", + asset: { address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", symbol: "USDC", decimals: 6 }, + type: "evm" + }] + }, + { + id: "getTweetThread", + name: "getTweetThread", + description: "Get a complete thread of tweets starting from a root tweet", + paymentHint: true, + paymentPriceUSD: 0.02, + paymentNetworks: [{ + network: "base", + recipient: "0x0000000000000000000000000000000000000000", + maxAmountRequired: "2000000", + asset: { address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", symbol: "USDC", decimals: 6 }, + type: "evm" + }] + }, + { + id: "getTrends", + name: "getTrends", + description: "Retrieve trending topics and hashtags", + paymentHint: true, + paymentPriceUSD: 0.01, + paymentNetworks: [{ + network: "base", + recipient: "0x0000000000000000000000000000000000000000", + maxAmountRequired: "1000000", + asset: { address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", symbol: "USDC", decimals: 6 }, + type: "evm" + }] + }, +] + +export default function McpExampleCard({ + className, + serverId, + ...props +}: McpExampleCardProps) { + const [selectedTool, setSelectedTool] = useState(null) + const [showToolModal, setShowToolModal] = useState(false) + const [data, setData] = useState<{ + serverId: string + tools: Array> + summary?: { totalTools: number; totalRequests: number } + info?: { name?: string; description?: string } + } | null>(null) + const [loading, setLoading] = useState(true) + const [totalRequests, setTotalRequests] = useState(null) + const [loadingRequests, setLoadingRequests] = useState(true) + + useEffect(() => { + if (!serverId) { + setLoading(false) + setLoadingRequests(false) + return + } + + // Fetch server data directly using serverId + const fetchData = async () => { + setLoading(true) + setLoadingRequests(true) + + try { + const serverData = await mcpDataApi.getServerById(serverId) + setData({ + serverId: serverData.serverId, + tools: (serverData.tools || []) as Array>, + summary: serverData.summary, + info: serverData.info, + }) + setTotalRequests(serverData.summary?.totalRequests || 0) + setLoadingRequests(false) + } catch (e) { + console.error('Failed to fetch server data:', e) + setData(null) + setTotalRequests(0) + setLoadingRequests(false) + } finally { + setLoading(false) + } + } + + fetchData() + }, [serverId]) + + // Normalize tools data exactly like server-page-client does + const normalizedTools = useMemo(() => { + if (!data?.tools) return [] + return (data.tools || []).map((t, idx) => { + const annotations = (t as { annotations?: Record })?.annotations || {}; + const paymentHint = Boolean(annotations.paymentHint); + const paymentPriceUSD = annotations.paymentPriceUSD as number | undefined; + const paymentNetworks = annotations.paymentNetworks as Array<{ + network: string; + recipient: string; + maxAmountRequired: string; + asset: { address: string; symbol?: string; decimals?: number }; + type: 'evm' | 'svm'; + }> | undefined; + const paymentVersion = annotations.paymentVersion as number | undefined; + + return { + id: (t?.id as string) || (t?.name as string) || `tool-${idx}`, + name: (t?.name as string) || `tool-${idx}`, + description: (t?.description as string) || '', + inputSchema: ((t as { inputSchema?: unknown; parameters?: { jsonSchema?: unknown } })?.inputSchema || (t as { parameters?: { jsonSchema?: unknown } })?.parameters?.jsonSchema || {}) as Record, + pricing: Array.isArray((t as { pricing?: unknown[] })?.pricing) ? (t as { pricing?: unknown[] }).pricing as Array<{ label?: string; amount?: number; currency?: string; active?: boolean }> : [], + isMonetized: Array.isArray((t as { pricing?: Array<{ active?: boolean }> })?.pricing) && ((t as { pricing?: Array<{ active?: boolean }> }).pricing || []).some((p) => p?.active === true), + paymentHint, + paymentPriceUSD, + paymentNetworks, + paymentVersion, + }; + }) + }, [data?.tools]) + + // Get first 5 tools + const displayTools = useMemo(() => { + return normalizedTools.slice(0, 5) + }, [normalizedTools]) + + const openToolModal = (tool: typeof normalizedTools[0]) => { + // Convert normalized tool to format expected by ToolExecutionModal + // Include payment info in the tool object as the modal expects it + const toolForModal = { + id: tool.id, + name: tool.name, + description: tool.description, + inputSchema: tool.inputSchema || {}, + pricing: tool.pricing || [], + isMonetized: tool.isMonetized || false, + paymentHint: tool.paymentHint, + paymentPriceUSD: tool.paymentPriceUSD, + paymentNetworks: tool.paymentNetworks, + } as unknown as ToolFromMcpServerWithStats + + setSelectedTool(toolForModal) + setShowToolModal(true) + } + + return ( + <> +
+
+ SERVER EXAMPLE +
+ + {/* Image + Title Section */} +
+
+ {/* Square black image - bigger with same rounded corners as tools, smaller on mobile */} +
+ X Logo +
+ + {/* Title */} +
+

+ {data?.info?.name || "Loading..."} +

+ + {/* Description - hidden on mobile, shown next to title on desktop */} +

+ Regular subscription{" "} + $200 /month via MCPay{" "} + $0.05 /tool +

+
+
+ + {/* Description - shown below image on mobile */} +

+ Regular subscription{" "} + $200 /month +
+ via MCPay{" "} + $0.05 /tool +

+
+ + {/* Tools List - First 5 tools */} +
+ {loading ? ( +
Loading tools...
+ ) : displayTools.length === 0 ? ( +
No tools available
+ ) : ( + displayTools.map((tool) => ( +
+ {/* Left: Name + Description */} +
+

{tool.name}

+ {tool.description && ( +

{tool.description}

+ )} +
+ + {/* Right: Price + RUN Button */} +
+ {tool.paymentHint && tool.paymentPriceUSD && ( + ${tool.paymentPriceUSD} + )} + +
+
+ )) + )} +
+ + {/* Text + Buttons Section */} +
+

+ Connect to any paid MCP server with a single account.{" "} + Pay per tool call, no subscriptions required. +

+
+ + + + +
+
+
+ + {/* Tool Execution Modal */} + {selectedTool && ( + { + setShowToolModal(false) + setSelectedTool(null) + }} + tool={selectedTool} + serverId={data?.serverId || ""} + /> + )} + + ) +} + From 96cc2cfc2f7c37b66462390d43420c2ca55ac37a Mon Sep 17 00:00:00 2001 From: Marcelo Kunze Date: Wed, 3 Dec 2025 18:14:26 -0300 Subject: [PATCH 5/8] Enhance UI components with new styles and features - Added a green variant to highlighter text and icon components for improved visual options. - Updated InfoCard, McpExampleCard, MinimalExplorer, StatsCard, and VisualProxy components to use a consistent rounded style. - Modified McpExampleCard to include origin data and improved button functionality for copying server URLs. --- .../components/custom-ui/highlighter-text.tsx | 2 + .../src/components/custom-ui/info-card.tsx | 2 +- .../components/custom-ui/mcp-example-card.tsx | 48 +++++++++++++------ .../components/custom-ui/minimal-explorer.tsx | 2 +- .../src/components/custom-ui/stats-card.tsx | 2 +- apps/app/src/components/custom-ui/stats.tsx | 2 +- .../src/components/custom-ui/visual-proxy.tsx | 2 +- 7 files changed, 40 insertions(+), 20 deletions(-) diff --git a/apps/app/src/components/custom-ui/highlighter-text.tsx b/apps/app/src/components/custom-ui/highlighter-text.tsx index d9a66f2..d811a7c 100644 --- a/apps/app/src/components/custom-ui/highlighter-text.tsx +++ b/apps/app/src/components/custom-ui/highlighter-text.tsx @@ -12,6 +12,7 @@ const highlighterTextVariants = cva( blue: "text-blue-700 bg-blue-500/10 dark:text-blue-200 dark:bg-blue-800/50", amber: "text-amber-700 bg-amber-500/10 dark:text-amber-200 dark:bg-amber-800/50", red: "text-red-700 bg-red-500/10 dark:text-red-200 dark:bg-red-800/50", + green: "text-teal-700 bg-teal-500/10 dark:text-teal-200 dark:bg-teal-800/50", }, }, defaultVariants: { @@ -29,6 +30,7 @@ const highlighterIconVariants = cva( blue: "text-blue-700 bg-blue-500/10 dark:text-blue-200 dark:bg-blue-800/50", amber: "text-amber-700 bg-amber-500/10 dark:text-amber-200 dark:bg-amber-800/50", red: "text-red-700 bg-red-500/10 dark:text-red-200 dark:bg-red-800/50", + green: "text-teal-700 bg-teal-500/10 dark:text-teal-200 dark:bg-teal-800/50", }, }, defaultVariants: { diff --git a/apps/app/src/components/custom-ui/info-card.tsx b/apps/app/src/components/custom-ui/info-card.tsx index 28805aa..16a93f3 100644 --- a/apps/app/src/components/custom-ui/info-card.tsx +++ b/apps/app/src/components/custom-ui/info-card.tsx @@ -25,7 +25,7 @@ export default function InfoCard({ return (
{ className?: string @@ -114,6 +115,7 @@ export default function McpExampleCard({ const [showToolModal, setShowToolModal] = useState(false) const [data, setData] = useState<{ serverId: string + origin?: string tools: Array> summary?: { totalTools: number; totalRequests: number } info?: { name?: string; description?: string } @@ -138,6 +140,7 @@ export default function McpExampleCard({ const serverData = await mcpDataApi.getServerById(serverId) setData({ serverId: serverData.serverId, + origin: serverData.origin, tools: (serverData.tools || []) as Array>, summary: serverData.summary, info: serverData.info, @@ -214,7 +217,7 @@ export default function McpExampleCard({ return ( <> -
+
SERVER EXAMPLE
@@ -241,20 +244,21 @@ export default function McpExampleCard({ {/* Description - hidden on mobile, shown next to title on desktop */}

- Regular subscription{" "} - $200 /month via MCPay{" "} - $0.05 /tool + Regular subscription{" "} + $200 /month{" "} + via MCPay{" "} + $0.05 /tool

{/* Description - shown below image on mobile */}

- Regular subscription{" "} + Regular subscription{" "} $200 /month
- via MCPay{" "} - $0.05 /tool + via MCPay{" "} + $0.05 /tool

@@ -300,19 +304,33 @@ export default function McpExampleCard({ {/* Text + Buttons Section */}

- Connect to any paid MCP server with a single account.{" "} + Consume any paid MCP server with a single account.{" "} Pay per tool call, no subscriptions required.

- - - + {data?.serverId && ( + + + + )}