kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
pull/715/head
rodzic
463671abde
commit
99d0edb6b6
|
@ -1,7 +1,8 @@
|
|||
import Link from 'next/link'
|
||||
|
||||
import { DotsSection } from '@/components/dots-section'
|
||||
import { ExampleAgenticConfigs } from '@/components/example-agentic-configs'
|
||||
import { GitHubStarCounter } from '@/components/github-star-counter'
|
||||
import { HeroSimulation2 } from '@/components/hero-simulation-2'
|
||||
import { SupplySideCTA } from '@/components/supply-side-cta'
|
||||
import {
|
||||
calendarBookingUrl,
|
||||
|
@ -10,37 +11,25 @@ import {
|
|||
twitterUrl
|
||||
} from '@/lib/config'
|
||||
|
||||
export default function TheSecondBestDamnLandingPageEver() {
|
||||
export default function MCPAuthorsPage() {
|
||||
return (
|
||||
<>
|
||||
{/* Hero section */}
|
||||
<section className='mb-16 relative'>
|
||||
<div className='flex gap-8'>
|
||||
{/* <div className='absolute top-0 bottom-0 left-0 right-0 bg-[url(/dots.svg)] bg-repeat bg-center bg-size-[32px_auto] opacity-30 dark:opacity-100' />
|
||||
<DotsSection className='mb-16'>
|
||||
<div className='flex flex-col gap-8 relative z-10'>
|
||||
<h1 className='text-center text-balance leading-snug md:leading-none text-4xl font-semibold'>
|
||||
Your API → Paid MCP, Instantly
|
||||
</h1>
|
||||
|
||||
<div className='absolute top-0 bottom-0 left-0 right-0 bg-[radial-gradient(39%_50%_at_50%_50%,rgba(255,255,255,.3)_0%,rgb(255,255,255)_100%)] dark:bg-[radial-gradient(39%_50%_at_50%_50%,rgba(10,10,10,0)_0%,rgb(10,10,10)_100%)]' /> */}
|
||||
<h5 className='text-center text-lg max-w-2xl'>
|
||||
Run one command to turn any MCP server or OpenAPI service into a
|
||||
paid MCP product,{' '}
|
||||
<em>with built-in distribution to over 20k AI engineers</em>.
|
||||
</h5>
|
||||
|
||||
<div className='flex flex-col gap-8 relative z-10'>
|
||||
<h1 className='text-center text-balance leading-snug md:leading-none text-4xl font-semibold'>
|
||||
Your API → Paid MCP, Instantly
|
||||
</h1>
|
||||
|
||||
<h5 className='text-center text-lg max-w-2xl'>
|
||||
Run one command to turn any MCP server or OpenAPI service into a
|
||||
paid MCP product,{' '}
|
||||
<em>with built-in distribution to over 20k AI engineers</em>.
|
||||
</h5>
|
||||
|
||||
<SupplySideCTA />
|
||||
</div>
|
||||
|
||||
<div className='w-[40%] h-full min-h-full' />
|
||||
|
||||
<HeroSimulation2 className='absolute! top-[-50%]! left-[30%] w-full h-[200%]!' />
|
||||
<SupplySideCTA />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section></section>
|
||||
</DotsSection>
|
||||
|
||||
{/* How it works section */}
|
||||
<section className='flex flex-col gap-8 mb-16'>
|
||||
|
@ -51,6 +40,27 @@ export default function TheSecondBestDamnLandingPageEver() {
|
|||
<div>TODO</div>
|
||||
</section>
|
||||
|
||||
{/* Config section */}
|
||||
<section className='flex flex-col gap-8 mb-16'>
|
||||
<h2 className='text-center text-balance leading-snug md:leading-none text-3xl font-heading'>
|
||||
Simple, Declarative Configuration
|
||||
</h2>
|
||||
|
||||
<ExampleAgenticConfigs />
|
||||
|
||||
<div className='flex flex-col gap-4 text-sm max-w-2xl text-center'>
|
||||
<p>
|
||||
Configuring your Agentic project is straightforward, regardless of
|
||||
whether your origin is an MCP server or an OpenAPI service. For TS
|
||||
projects, you can use a fully-typed{' '}
|
||||
<span className='font-semibold'>agentic.config.ts</span> file, or
|
||||
fall back to using an{' '}
|
||||
<span className='font-semibold'>agentic.config.json</span> file to
|
||||
configure your project.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Features section */}
|
||||
<section className='flex flex-col gap-8 mb-16'>
|
||||
<h2 className='text-center text-balance leading-snug md:leading-none text-3xl font-heading'>
|
||||
|
@ -197,17 +207,6 @@ export default function TheSecondBestDamnLandingPageEver() {
|
|||
</div>
|
||||
</section>
|
||||
|
||||
{/* Marketplace section */}
|
||||
{/* <section className='flex flex-col gap-8 mb-16'>
|
||||
<h2 className='text-center text-balance leading-snug md:leading-none text-3xl font-heading'>
|
||||
MCP Marketplace
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
<i>Coming soon...</i>
|
||||
</p>
|
||||
</section> */}
|
||||
|
||||
{/* Open source section */}
|
||||
<section className='flex flex-col items-center gap-8 max-w-2xl text-center mb-16'>
|
||||
<h2 className='text-center text-balance leading-snug md:leading-none text-3xl font-heading'>
|
||||
|
@ -242,15 +241,6 @@ export default function TheSecondBestDamnLandingPageEver() {
|
|||
<GitHubStarCounter />
|
||||
</section>
|
||||
|
||||
{/* Social proof section */}
|
||||
<section className='gap-8 mb-16'>
|
||||
<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-12 mb-16'>
|
||||
<h2 className='text-center text-balance leading-snug md:leading-none text-3xl font-heading'>
|
||||
|
|
|
@ -36,7 +36,7 @@ export default async function TheBestDamnLandingPageEver() {
|
|||
<>
|
||||
{/* Hero section */}
|
||||
<DotsSection className='mb-16'>
|
||||
<div className='flex flex-col gap-8 relative z-10'>
|
||||
<div className='flex flex-col gap-10 relative z-10'>
|
||||
<h1 className='text-center text-balance leading-snug md:leading-none text-4xl font-semibold'>
|
||||
The App Store for LLM Tools
|
||||
</h1>
|
||||
|
@ -50,10 +50,14 @@ export default async function TheBestDamnLandingPageEver() {
|
|||
</div>
|
||||
</DotsSection>
|
||||
|
||||
{/* <div className='w-[40%] h-full min-h-full' />
|
||||
|
||||
<HeroSimulation2 className='absolute! top-[-50%]! left-[30%] w-full h-[200%]!' /> */}
|
||||
|
||||
{/* How it works section */}
|
||||
<section className='flex flex-col gap-8 mb-16'>
|
||||
<h2 className='text-center text-balance leading-snug md:leading-none text-3xl font-heading'>
|
||||
LLM Tools that work everywhere
|
||||
Agentic tools work <span className='font-semibold'>everywhere</span>
|
||||
</h2>
|
||||
|
||||
<ExampleUsage
|
||||
|
@ -62,6 +66,25 @@ export default async function TheBestDamnLandingPageEver() {
|
|||
project={initialProject}
|
||||
initialCodeBlock={initialCodeBlock}
|
||||
/>
|
||||
|
||||
<div className='flex flex-col gap-4 text-sm max-w-2xl text-center'>
|
||||
<p>
|
||||
This example uses the{' '}
|
||||
<Link href='/marketplace/projects/@agentic/search' className='link'>
|
||||
@agentic/search
|
||||
</Link>{' '}
|
||||
tool to provide an LLM access to the web.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
All Agentic tools are exposed as both{' '}
|
||||
<span className='font-semibold'>MCP servers</span> as well as simple{' '}
|
||||
<span className='font-semibold'>HTTP APIs</span>. MCP is important
|
||||
for interop and future-proofing, whereas simple HTTP POST requests
|
||||
make tool use easy to debug and simplifies integration with existing
|
||||
LLM tool calling.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Marketplace section */}
|
||||
|
|
|
@ -77,7 +77,7 @@ export function SignupForm() {
|
|||
})
|
||||
|
||||
return (
|
||||
<section>
|
||||
<section className='flex-1'>
|
||||
<div className='flex-col flex-1 items-center justify-center w-full max-w-xs'>
|
||||
<form
|
||||
className={cn('flex flex-col gap-6 w-full')}
|
||||
|
|
|
@ -9,9 +9,9 @@ export function DotsSection({
|
|||
}) {
|
||||
return (
|
||||
<section className={cn('relative', className)}>
|
||||
<div className='absolute top-0 bottom-0 left-0 right-0 bg-[url(/dots.svg)] bg-repeat bg-center bg-size-[32px_auto] opacity-30 dark:opacity-100' />
|
||||
<div className='absolute top-[-50%] bottom-[-50%] left-[-50%] right-[-50%] bg-[url(/dots.svg)] bg-repeat bg-center bg-size-[32px_auto] opacity-30 dark:opacity-100' />
|
||||
|
||||
<div className='absolute top-0 bottom-0 left-0 right-0 bg-[radial-gradient(39%_50%_at_50%_50%,rgba(255,255,255,.3)_0%,rgb(255,255,255)_100%)] dark:bg-[radial-gradient(39%_50%_at_50%_50%,rgba(10,10,10,0)_0%,rgb(10,10,10)_100%)]' />
|
||||
<div className='absolute top-[-50%] bottom-[-50%] left-[-50%] right-[-50%] bg-[radial-gradient(39%_50%_at_50%_50%,rgba(255,255,255,.3)_0%,rgb(255,255,255)_100%)] dark:bg-[radial-gradient(39%_50%_at_50%_50%,rgba(10,10,10,0)_0%,rgb(10,10,10)_100%)]' />
|
||||
|
||||
{children}
|
||||
</section>
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
'use client'
|
||||
|
||||
import type { BundledLanguage } from 'shiki/bundle/web'
|
||||
import { useLocalStorage } from 'react-use'
|
||||
|
||||
import { CodeBlock } from '@/components/code-block'
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
|
||||
|
||||
import { LoadingIndicator } from './loading-indicator'
|
||||
|
||||
const formatLabels = {
|
||||
typescript: 'TypeScript',
|
||||
json: 'JSON'
|
||||
} as const
|
||||
const formats = Object.keys(formatLabels) as (keyof typeof formatLabels)[]
|
||||
type Format = (typeof formats)[number]
|
||||
|
||||
const originAdaptorLabels = {
|
||||
mcp: 'MCP',
|
||||
openapi: 'OpenAPI'
|
||||
} as const
|
||||
const originAdaptors = Object.keys(
|
||||
originAdaptorLabels
|
||||
) as (keyof typeof originAdaptorLabels)[]
|
||||
type OriginAdaptor = (typeof originAdaptors)[number]
|
||||
|
||||
type ExampleAgenticConfig = {
|
||||
format: Format
|
||||
originAdaptor: OriginAdaptor
|
||||
}
|
||||
|
||||
const defaultExampleAgenticConfig: ExampleAgenticConfig = {
|
||||
format: 'typescript',
|
||||
originAdaptor: 'mcp'
|
||||
}
|
||||
|
||||
type CodeSnippet = {
|
||||
code: string
|
||||
lang: BundledLanguage
|
||||
}
|
||||
|
||||
export function ExampleAgenticConfigs() {
|
||||
const [config, setConfig] = useLocalStorage<ExampleAgenticConfig>(
|
||||
'example-agentic-config',
|
||||
defaultExampleAgenticConfig
|
||||
)
|
||||
|
||||
if (!config) {
|
||||
return <LoadingIndicator className='w-full max-w-3xl' />
|
||||
}
|
||||
|
||||
const codeSnippet = getCodeSnippetForExampleAgenticConfig(config)
|
||||
|
||||
return (
|
||||
<Tabs
|
||||
defaultValue={config!.format}
|
||||
onValueChange={(value) =>
|
||||
setConfig({
|
||||
...defaultExampleAgenticConfig,
|
||||
...config,
|
||||
format: value as Format
|
||||
})
|
||||
}
|
||||
className='w-full max-w-3xl'
|
||||
>
|
||||
<TabsList>
|
||||
{formats.map((format) => (
|
||||
<TabsTrigger key={format} value={format} className='cursor-pointer'>
|
||||
{formatLabels[format]}
|
||||
</TabsTrigger>
|
||||
))}
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value={config.format} className='w-full'>
|
||||
<Tabs
|
||||
defaultValue={config.originAdaptor}
|
||||
onValueChange={(value) =>
|
||||
setConfig({
|
||||
...defaultExampleAgenticConfig,
|
||||
...config,
|
||||
originAdaptor: value as OriginAdaptor
|
||||
})
|
||||
}
|
||||
className='w-full'
|
||||
>
|
||||
<TabsList className='w-full h-auto flex-wrap'>
|
||||
{originAdaptors.map((originAdaptor) => (
|
||||
<TabsTrigger
|
||||
key={originAdaptor}
|
||||
value={originAdaptor}
|
||||
className='cursor-pointer text-xs!'
|
||||
>
|
||||
{originAdaptorLabels[originAdaptor]}
|
||||
</TabsTrigger>
|
||||
))}
|
||||
</TabsList>
|
||||
|
||||
{originAdaptors.map((originAdaptor) => (
|
||||
<TabsContent
|
||||
key={originAdaptor}
|
||||
value={originAdaptor}
|
||||
className='w-full'
|
||||
>
|
||||
<CodeBlock code={codeSnippet.code} lang={codeSnippet.lang} />
|
||||
</TabsContent>
|
||||
))}
|
||||
</Tabs>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
)
|
||||
}
|
||||
|
||||
function getCodeSnippetForExampleAgenticConfig(
|
||||
config: ExampleAgenticConfig
|
||||
): CodeSnippet {
|
||||
if (config.format === 'typescript') {
|
||||
if (config.originAdaptor === 'mcp') {
|
||||
return {
|
||||
code: `
|
||||
import { defineConfig } from '@agentic/platform'
|
||||
|
||||
export default defineConfig({
|
||||
name: 'mcp-example',
|
||||
// Your origin MCP server URL supporting the streamable HTTP transport
|
||||
originUrl: '<YOUR_MCP_SERVER_URL>',
|
||||
originAdapter: {
|
||||
type: 'mcp'
|
||||
}
|
||||
})`.trim(),
|
||||
lang: 'typescript'
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
code: `
|
||||
import { defineConfig } from '@agentic/platform'
|
||||
|
||||
export default defineConfig({
|
||||
name: 'openapi-example',
|
||||
originUrl: '<YOUR_OPENAPI_SERVER_BASE_URL>',
|
||||
originAdapter: {
|
||||
type: 'openapi',
|
||||
spec: '<YOUR_OPENAPI_SPEC_PATH_OR_URL>'
|
||||
}
|
||||
})`.trim(),
|
||||
lang: 'typescript'
|
||||
}
|
||||
}
|
||||
} else if (config.format === 'json') {
|
||||
if (config.originAdaptor === 'mcp') {
|
||||
return {
|
||||
code: `
|
||||
{
|
||||
"name": "mcp-example",
|
||||
"originUrl": "<YOUR_MCP_SERVER_URL>",
|
||||
"originAdapter": {
|
||||
"type": "mcp"
|
||||
}
|
||||
}`.trim(),
|
||||
lang: 'json'
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
code: `
|
||||
{
|
||||
"name": "openapi-example",
|
||||
"originUrl": "<YOUR_OPENAPI_SERVER_BASE_URL>",
|
||||
"originAdapter": {
|
||||
"type": "openapi",
|
||||
"spec": "<YOUR_OPENAPI_SPEC_PATH_OR_URL>"
|
||||
}
|
||||
}`.trim(),
|
||||
lang: 'json'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
code: '',
|
||||
lang: 'json'
|
||||
}
|
||||
}
|
|
@ -45,7 +45,7 @@ export function ExampleUsage({
|
|||
const ctx = useAgentic()
|
||||
|
||||
const [config, setConfig] = useLocalStorage<DeveloperConfig>(
|
||||
'config',
|
||||
'developer-config',
|
||||
defaultConfig
|
||||
)
|
||||
|
||||
|
@ -176,7 +176,7 @@ export function ExampleUsage({
|
|||
|
||||
<TabsContent value='typescript' className='w-full'>
|
||||
<Tabs
|
||||
defaultValue={config.tsFrameworkTarget ?? 'ai'}
|
||||
defaultValue={config.tsFrameworkTarget}
|
||||
onValueChange={(value) =>
|
||||
setConfig({
|
||||
...defaultConfig,
|
||||
|
|
|
@ -10,18 +10,18 @@ export const targetLabels = {
|
|||
python: 'Python',
|
||||
http: 'HTTP'
|
||||
} as const
|
||||
export const targets: (keyof typeof targetLabels)[] = Object.keys(
|
||||
export const targets = Object.keys(
|
||||
targetLabels
|
||||
) as any
|
||||
) as (keyof typeof targetLabels)[]
|
||||
export type Target = (typeof targets)[number]
|
||||
|
||||
export const httpTargetLabels = {
|
||||
curl: 'cURL',
|
||||
httpie: 'HTTPie'
|
||||
} as const
|
||||
export const httpTargets: (keyof typeof httpTargetLabels)[] = Object.keys(
|
||||
export const httpTargets = Object.keys(
|
||||
httpTargetLabels
|
||||
) as any
|
||||
) as (keyof typeof httpTargetLabels)[]
|
||||
export type HTTPTarget = (typeof httpTargets)[number]
|
||||
|
||||
export const mcpClientTargetLabels = {
|
||||
|
@ -34,8 +34,9 @@ export const mcpClientTargetLabels = {
|
|||
cline: 'Cline',
|
||||
goose: 'Goose'
|
||||
} as const
|
||||
export const mcpClientTargets: (keyof typeof mcpClientTargetLabels)[] =
|
||||
Object.keys(mcpClientTargetLabels) as any
|
||||
export const mcpClientTargets = Object.keys(
|
||||
mcpClientTargetLabels
|
||||
) as (keyof typeof mcpClientTargetLabels)[]
|
||||
export type MCPClientTarget = (typeof mcpClientTargets)[number]
|
||||
|
||||
export const tsFrameworkTargetLabels = {
|
||||
|
@ -48,8 +49,9 @@ export const tsFrameworkTargetLabels = {
|
|||
'firebase-genkit': 'Firebase GenKit',
|
||||
xsai: 'xsAI'
|
||||
} as const
|
||||
export const tsFrameworkTargets: (keyof typeof tsFrameworkTargetLabels)[] =
|
||||
Object.keys(tsFrameworkTargetLabels) as any
|
||||
export const tsFrameworkTargets = Object.keys(
|
||||
tsFrameworkTargetLabels
|
||||
) as (keyof typeof tsFrameworkTargetLabels)[]
|
||||
export type TsFrameworkTarget = (typeof tsFrameworkTargets)[number]
|
||||
|
||||
export const pyFrameworkTargetLabels = {
|
||||
|
@ -57,8 +59,9 @@ export const pyFrameworkTargetLabels = {
|
|||
langchain: 'LangChain',
|
||||
llamaindex: 'LlamaIndex'
|
||||
} as const
|
||||
export const pyFrameworkTargets: (keyof typeof pyFrameworkTargetLabels)[] =
|
||||
Object.keys(pyFrameworkTargetLabels) as any
|
||||
export const pyFrameworkTargets = Object.keys(
|
||||
pyFrameworkTargetLabels
|
||||
) as (keyof typeof pyFrameworkTargetLabels)[]
|
||||
export type PyFrameworkTarget = (typeof pyFrameworkTargets)[number]
|
||||
|
||||
export type DeveloperConfig = {
|
||||
|
|
Ładowanie…
Reference in New Issue