kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
pull/715/head
rodzic
a42ea77ff2
commit
6f71ac6635
|
@ -50,7 +50,7 @@ export default function RootLayout({
|
|||
<div className='w-full min-h-[100vh] relative flex flex-col items-center'>
|
||||
<Header />
|
||||
|
||||
<main className='flex-1 w-full flex flex-col items-center max-w-[1200px] gap-16 pt-8 pb-16 px-4 md:px-0'>
|
||||
<main className='flex-1 w-full flex flex-col items-center max-w-[1200px] gap-16 pt-16 pb-24 px-4 md:px-0'>
|
||||
{children}
|
||||
</main>
|
||||
|
||||
|
|
|
@ -75,9 +75,6 @@ export default function LoginPage() {
|
|||
>
|
||||
<div className='flex flex-col items-center gap-2 text-center'>
|
||||
<h1 className='text-2xl font-bold'>Login to your account</h1>
|
||||
<p className='text-muted-foreground text-sm text-balance'>
|
||||
Enter your email below to login to your account
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className='grid gap-6'>
|
||||
|
|
|
@ -4,7 +4,6 @@ import { GitHubStarCounter } from '@/components/github-star-counter'
|
|||
import { SupplySideCTA } from '@/components/supply-side-cta'
|
||||
import {
|
||||
calendarBookingUrl,
|
||||
discordUrl,
|
||||
docsUrl,
|
||||
githubUrl,
|
||||
twitterUrl
|
||||
|
@ -15,7 +14,7 @@ export default function TheBestDamnLandingPageEver() {
|
|||
<>
|
||||
{/* Hero section */}
|
||||
<section className='gap-8'>
|
||||
<h1 className='text-center text-balance leading-snug md:leading-none text-4xl font-extrabold'>
|
||||
<h1 className='text-center text-balance leading-snug md:leading-none text-4xl font-bold'>
|
||||
Your API → Paid MCP, Instantly
|
||||
</h1>
|
||||
|
||||
|
@ -30,7 +29,7 @@ export default function TheBestDamnLandingPageEver() {
|
|||
|
||||
{/* How it works section */}
|
||||
<section className='flex flex-col gap-8'>
|
||||
<h2 className='text-center text-balance leading-snug md:leading-none text-2xl font-heading'>
|
||||
<h2 className='text-center text-balance leading-snug md:leading-none text-3xl font-heading'>
|
||||
How It Works
|
||||
</h2>
|
||||
|
||||
|
@ -39,11 +38,11 @@ export default function TheBestDamnLandingPageEver() {
|
|||
|
||||
{/* Features section */}
|
||||
<section className='flex flex-col gap-8'>
|
||||
<h2 className='text-center text-balance leading-snug md:leading-none text-2xl font-heading'>
|
||||
<h2 className='text-center text-balance leading-snug md:leading-none text-3xl font-heading'>
|
||||
Production-Ready and Extremely Flexible
|
||||
</h2>
|
||||
|
||||
<div className='grid gap-6'>
|
||||
<div className='grid gap-6 max-w-2xl'>
|
||||
<div className='flex flex-col gap-2'>
|
||||
<h4 className='text-center text-balance text-lg font-heading'>
|
||||
Auth
|
||||
|
@ -68,21 +67,22 @@ export default function TheBestDamnLandingPageEver() {
|
|||
|
||||
<div className='flex flex-col gap-2'>
|
||||
<h4 className='text-center text-balance text-lg font-heading'>
|
||||
Monetization
|
||||
Stripe Billing
|
||||
</h4>
|
||||
|
||||
<p className='text-sm'>
|
||||
Charge for your MCP products with a flexible, declarative pricing
|
||||
model built on top of Stripe. Agentic supports almost any
|
||||
combination of fixed and usage-based billing models, both at the
|
||||
MCP level, at the tool-call level, and at the custom metric level
|
||||
(e.g., tokens, image transformations, etc).
|
||||
combination of fixed and{' '}
|
||||
<span className='font-semibold'>usage-based billing</span> models,
|
||||
both at the MCP level, at the tool-call level, and at the custom
|
||||
metric level (e.g., tokens, image transformations, etc).
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className='flex flex-col gap-2'>
|
||||
<h4 className='text-center text-balance text-lg font-heading'>
|
||||
Support both MCP <em>and</em> HTTP
|
||||
Support both MCP and HTTP
|
||||
</h4>
|
||||
|
||||
<p className='text-sm'>
|
||||
|
@ -97,18 +97,30 @@ export default function TheBestDamnLandingPageEver() {
|
|||
</p>
|
||||
</div>
|
||||
|
||||
<div className='flex flex-col gap-2'>
|
||||
<h4 className='text-center text-balance text-lg font-heading'>
|
||||
API keys
|
||||
</h4>
|
||||
|
||||
<p className='text-sm'>
|
||||
When a customer subscribes to your product, they're given a unique
|
||||
API key. MCP URLs are appended with this API key to correlate
|
||||
usage with their subscription. Customer HTTP tool calls use the
|
||||
same API key as a standard HTTP <em>Authorization</em> header.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className='flex flex-col gap-2'>
|
||||
<h4 className='text-center text-balance text-lg font-heading'>
|
||||
Rate-limiting
|
||||
</h4>
|
||||
|
||||
<p className='text-sm'>
|
||||
Customize your MCP product with durable rate-limiting built on top
|
||||
of Cloudflare's global infrastructure. Create default rate-limits,
|
||||
change them based on a customer's subscribed pricing plan, and
|
||||
create custom tool-specific overrides, all with a simple,
|
||||
strongly-typed JSON config. REST assured that your origin API will
|
||||
be safe behind Agentic's robust API gateway.
|
||||
All agentic products are protected by durable rate-limiting built
|
||||
on top of Cloudflare's global infrastructure. Customize the
|
||||
default rate-limits, change them based on a customer's pricing
|
||||
plan, or create custom tool-specific overrides. REST assured that
|
||||
your origin API will be safe behind Agentic's robust API gateway.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
@ -119,11 +131,11 @@ export default function TheBestDamnLandingPageEver() {
|
|||
|
||||
<p className='text-sm'>
|
||||
Opt-in to caching with familiar <em>cache-control</em> and{' '}
|
||||
<em>stale-while-revalidate</em> features. MCP tool calls include
|
||||
caching information in their <em>_meta</em> fields with symmetry
|
||||
to standard HTTP headers. All caching takes place in Cloudflare's
|
||||
global edge cache, and will only be enabled if you choose to
|
||||
enable it for your product or specific tools.
|
||||
<em>stale-while-revalidate</em> options. MCP tool calls include
|
||||
caching information in their <em>_meta</em> fields, providing
|
||||
parity with standard HTTP headers. All caching takes place in
|
||||
Cloudflare's global edge cache, and caching will only be enabled
|
||||
if you choose to enable it for your product or individual tools.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
@ -133,9 +145,9 @@ export default function TheBestDamnLandingPageEver() {
|
|||
</h4>
|
||||
|
||||
<p className='text-sm'>
|
||||
Agentic tracks usage-based billing and analytics at a fine-grained
|
||||
level, so you can understand how your customers are using your
|
||||
product.
|
||||
Agentic tracks all tool calls for usage-based billing and
|
||||
analytics at a fine-grained level, so you can drill in and deeply
|
||||
understand how your customers are using your product.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
@ -149,7 +161,7 @@ export default function TheBestDamnLandingPageEver() {
|
|||
time you make a change to your product's config, pricing, or docs,
|
||||
a unique preview deployment is created for that change. This
|
||||
enables instant rollbacks if there are problems with a deployment.
|
||||
Publish deployment publicly uses semantic versioning (
|
||||
Publishing deployments publicly uses semantic versioning (
|
||||
<em>semver</em>), so your customers can choose how to handle
|
||||
breaking changes.
|
||||
</p>
|
||||
|
@ -157,43 +169,42 @@ export default function TheBestDamnLandingPageEver() {
|
|||
|
||||
<div className='flex flex-col gap-2'>
|
||||
<h4 className='text-center text-balance text-lg font-heading'>
|
||||
And more!
|
||||
That's just the start
|
||||
</h4>
|
||||
|
||||
<p className='text-sm'>
|
||||
Checkout our <Link href={docsUrl}>docs</Link> for more details on
|
||||
Agentic's MCP API gateway.
|
||||
<Link href={docsUrl} className='link'>
|
||||
Check out our docs
|
||||
</Link>{' '}
|
||||
for more details on Agentic's MCP API gateway.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Marketplace section */}
|
||||
<section className='flex flex-col gap-8'>
|
||||
<h2 className='text-center text-balance leading-snug md:leading-none text-2xl font-heading'>
|
||||
{/* <section className='flex flex-col gap-8'>
|
||||
<h2 className='text-center text-balance leading-snug md:leading-none text-3xl font-heading'>
|
||||
MCP Marketplace
|
||||
</h2>
|
||||
|
||||
<p>Coming soon...</p>
|
||||
</section>
|
||||
<p>
|
||||
<i>Coming soon...</i>
|
||||
</p>
|
||||
</section> */}
|
||||
|
||||
{/* Open source section */}
|
||||
<section className='flex flex-col items-center gap-8 max-w-2xl text-center'>
|
||||
<h2 className='text-center text-balance leading-snug md:leading-none text-2xl font-heading italic'>
|
||||
Agentic is 100% Open Source!
|
||||
<h2 className='text-center text-balance leading-snug md:leading-none text-3xl font-heading'>
|
||||
Agentic is 100% Open Source
|
||||
</h2>
|
||||
|
||||
<p className='text-sm'>
|
||||
Join the tens of thousands of TypeScript AI engineers who've{' '}
|
||||
<Link
|
||||
href={githubUrl}
|
||||
target='_blank'
|
||||
rel='noopener'
|
||||
className='link'
|
||||
>
|
||||
starred the project on GitHub
|
||||
</Link>
|
||||
.{' '}
|
||||
<p className=''>
|
||||
Open source is very dear to my heart, and I couldn't be happier that
|
||||
Agentic is fully OSS. It's written in{' '}
|
||||
<span className='font-semibold'>TypeScript</span>, stands on the
|
||||
shoulders of infra giants (Vercel, Cloudflare, Postgres), and has a
|
||||
small but vibrant developer community.{' '}
|
||||
<Link
|
||||
href={githubUrl}
|
||||
target='_blank'
|
||||
|
@ -201,17 +212,8 @@ export default function TheBestDamnLandingPageEver() {
|
|||
className='link'
|
||||
>
|
||||
Check out the source on GitHub
|
||||
</Link>
|
||||
,{' '}
|
||||
<Link
|
||||
href={discordUrl}
|
||||
target='_blank'
|
||||
rel='noopener'
|
||||
className='link'
|
||||
>
|
||||
join our community on Discord
|
||||
</Link>
|
||||
, or{' '}
|
||||
</Link>{' '}
|
||||
or{' '}
|
||||
<Link
|
||||
href={twitterUrl}
|
||||
target='_blank'
|
||||
|
@ -219,16 +221,31 @@ export default function TheBestDamnLandingPageEver() {
|
|||
className='link'
|
||||
>
|
||||
ping me on Twitter
|
||||
</Link>
|
||||
.
|
||||
</Link>{' '}
|
||||
with questions / feedback.
|
||||
</p>
|
||||
|
||||
<GitHubStarCounter />
|
||||
</section>
|
||||
|
||||
{/* Social proof section */}
|
||||
<section className='gap-8'>
|
||||
<h2 className='text-center text-balance leading-snug md:leading-none text-3xl font-heading'>
|
||||
TODO: social proof
|
||||
</h2>
|
||||
|
||||
<p className='text-center text-lg max-w-2xl'>TODO</p>
|
||||
</section>
|
||||
|
||||
{/* CTA section */}
|
||||
<section className='flex flex-col gap-8'>
|
||||
<SupplySideCTA />
|
||||
<section className='flex flex-col gap-12'>
|
||||
<h2 className='text-center text-balance leading-snug md:leading-none text-3xl font-heading'>
|
||||
Deploy Your MCP Product Today
|
||||
</h2>
|
||||
|
||||
<p>Join the AI gold rush && deploy your first MCP product today.</p>
|
||||
|
||||
<SupplySideCTA variant='github-2' />
|
||||
</section>
|
||||
</>
|
||||
)
|
||||
|
|
|
@ -89,9 +89,6 @@ export default function SignupPage() {
|
|||
>
|
||||
<div className='flex flex-col items-center gap-2 text-center'>
|
||||
<h1 className='text-2xl font-bold'>Create an account</h1>
|
||||
<p className='text-muted-foreground text-sm text-balance'>
|
||||
Enter your info below to create an account
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className='grid gap-6'>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import NumberFlow from '@number-flow/react'
|
||||
import Link from 'next/link'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { type ReactNode, useEffect, useState } from 'react'
|
||||
|
||||
import { GitHubIcon } from '@/icons/github'
|
||||
import { githubUrl } from '@/lib/config'
|
||||
|
@ -13,7 +13,13 @@ import { Button } from './ui/button'
|
|||
// TODO: fetch this dynamically
|
||||
const numGitHubStars = 17_600
|
||||
|
||||
export function GitHubStarCounter({ className }: { className?: string }) {
|
||||
export function GitHubStarCounter({
|
||||
className,
|
||||
children
|
||||
}: {
|
||||
className?: string
|
||||
children?: ReactNode
|
||||
}) {
|
||||
const [numStars, setNumStars] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -35,9 +41,11 @@ export function GitHubStarCounter({ className }: { className?: string }) {
|
|||
notation: 'compact',
|
||||
roundingPriority: 'morePrecision'
|
||||
}}
|
||||
suffix=' stars'
|
||||
suffix={children ? undefined : ' stars'}
|
||||
willChange
|
||||
/>
|
||||
|
||||
{children}
|
||||
</Link>
|
||||
</Button>
|
||||
)
|
||||
|
|
|
@ -5,16 +5,22 @@ import Link from 'next/link'
|
|||
|
||||
import { HeroButton } from '@/components/hero-button'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { calendarBookingUrl, docsQuickStartUrl } from '@/lib/config'
|
||||
import { GitHubIcon } from '@/icons/github'
|
||||
import { calendarBookingUrl, docsQuickStartUrl, githubUrl } from '@/lib/config'
|
||||
|
||||
import { useAgentic } from './agentic-provider'
|
||||
import { GitHubStarCounter } from './github-star-counter'
|
||||
|
||||
export function SupplySideCTA() {
|
||||
export function SupplySideCTA({
|
||||
variant = 'github'
|
||||
}: {
|
||||
variant?: 'book-call' | 'github' | 'github-2'
|
||||
}) {
|
||||
const ctx = useAgentic()
|
||||
|
||||
return (
|
||||
<div className='flex justify-center items-center gap-8'>
|
||||
<HeroButton asChild className='h-full'>
|
||||
<HeroButton asChild className=''>
|
||||
<Link
|
||||
href={
|
||||
ctx?.isAuthenticated
|
||||
|
@ -26,11 +32,22 @@ export function SupplySideCTA() {
|
|||
</Link>
|
||||
</HeroButton>
|
||||
|
||||
<Button variant='outline' asChild className='h-full'>
|
||||
<Link href={calendarBookingUrl} target='_blank' rel='noopener'>
|
||||
Book a call with me 👋
|
||||
{variant === 'github' ? (
|
||||
<GitHubStarCounter className='h-full py-[9px]' />
|
||||
) : variant === 'github-2' ? (
|
||||
<Button variant='outline' asChild className='h-full py-[9px]'>
|
||||
<Link href={githubUrl} target='_blank' rel='noopener'>
|
||||
<GitHubIcon />
|
||||
Star Agentic on GitHub
|
||||
</Link>
|
||||
</Button>
|
||||
) : (
|
||||
<Button variant='outline' asChild className='h-full py-[9px]'>
|
||||
<Link href={calendarBookingUrl} target='_blank' rel='noopener'>
|
||||
Book a call with the founder 👋
|
||||
</Link>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
- stripe billing portal
|
||||
- should we bypass stripe for `free` plans to increase conversions?
|
||||
- handle browser back/forward with `?next=`
|
||||
- add some social proof to signup page
|
||||
- **API gateway**
|
||||
- oauth flow
|
||||
- https://docs.scalekit.com/guides/mcp/oauth
|
||||
|
@ -43,6 +44,7 @@
|
|||
- consider using [neon serverless driver](https://orm.drizzle.team/docs/connect-neon) for production
|
||||
- can this also be used locally?
|
||||
- may need to update our `drizzle-orm` fork
|
||||
- figure out the best OSS license for launch
|
||||
|
||||
## TODO: Post-MVP
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue