@nordsym/apiclaw 1.2.1 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.prod +1 -0
- package/AGENTS.md +50 -33
- package/README.md +22 -12
- package/SOUL.md +60 -19
- package/STATUS.md +91 -169
- package/convex/_generated/api.d.ts +6 -0
- package/convex/directCall.ts +598 -0
- package/convex/http.ts +32 -0
- package/convex/providers.ts +341 -26
- package/convex/schema.ts +87 -0
- package/convex/usage.ts +260 -0
- package/convex/waitlist.ts +55 -0
- package/data/combined-02-25.json +5602 -0
- package/data/combined-02-26.json +22102 -0
- package/data/night-batch-02-25.json +2732 -0
- package/data/night-expansion-02-25.json +2872 -0
- package/data/night-expansion-02-26-06-batch2.json +1898 -0
- package/data/night-expansion-02-26-06-batch3.json +1410 -0
- package/data/night-expansion-02-26-06.json +3146 -0
- package/data/night-expansion-02-26-full.json +9726 -0
- package/data/night-expansion-02-26-v2.json +330 -0
- package/data/night-expansion-02-26.json +171 -0
- package/dist/credentials.d.ts.map +1 -1
- package/dist/credentials.js +15 -0
- package/dist/credentials.js.map +1 -1
- package/dist/crypto.d.ts +7 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +67 -0
- package/dist/crypto.js.map +1 -0
- package/dist/execute-dynamic.d.ts +116 -0
- package/dist/execute-dynamic.d.ts.map +1 -0
- package/dist/execute-dynamic.js +456 -0
- package/dist/execute-dynamic.js.map +1 -0
- package/dist/execute.d.ts +2 -1
- package/dist/execute.d.ts.map +1 -1
- package/dist/execute.js +111 -5
- package/dist/execute.js.map +1 -1
- package/dist/index.js +35 -4
- package/dist/index.js.map +1 -1
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +1 -1
- package/dist/proxy.js.map +1 -1
- package/dist/registry/apis.json +46554 -174
- package/docs/PRD-customer-key-passthrough.md +184 -0
- package/landing/public/badges/available-on-apiclaw.svg +14 -0
- package/landing/scripts/generate-stats.js +75 -4
- package/landing/src/app/admin/page.tsx +1 -1
- package/landing/src/app/api/auth/magic-link/route.ts +9 -2
- package/landing/src/app/api/auth/session/route.ts +1 -1
- package/landing/src/app/api/auth/verify/route.ts +8 -5
- package/landing/src/app/api/og/route.tsx +5 -3
- package/landing/src/app/docs/page.tsx +23 -22
- package/landing/src/app/earn/page.tsx +20 -17
- package/landing/src/app/globals.css +16 -15
- package/landing/src/app/layout.tsx +2 -2
- package/landing/src/app/page.tsx +555 -252
- package/landing/src/app/providers/dashboard/[apiId]/actions/[actionId]/edit/page.tsx +600 -0
- package/landing/src/app/providers/dashboard/[apiId]/actions/new/page.tsx +583 -0
- package/landing/src/app/providers/dashboard/[apiId]/actions/page.tsx +301 -0
- package/landing/src/app/providers/dashboard/[apiId]/direct-call/page.tsx +659 -0
- package/landing/src/app/providers/dashboard/[apiId]/page.tsx +381 -0
- package/landing/src/app/providers/dashboard/[apiId]/test/page.tsx +418 -0
- package/landing/src/app/providers/dashboard/layout.tsx +292 -0
- package/landing/src/app/providers/dashboard/page.tsx +353 -290
- package/landing/src/app/providers/page.tsx +6 -5
- package/landing/src/app/providers/register/page.tsx +88 -11
- package/landing/src/components/AiClientDropdown.tsx +85 -0
- package/landing/src/components/ConfigHelperModal.tsx +113 -0
- package/landing/src/components/HeroTabs.tsx +187 -0
- package/landing/src/components/ShareIntegrationModal.tsx +198 -0
- package/landing/src/hooks/useDashboardData.ts +53 -1
- package/landing/src/lib/apis.json +46554 -174
- package/landing/src/lib/convex-client.ts +28 -5
- package/landing/src/lib/stats.json +4 -4
- package/landing/tsconfig.tsbuildinfo +1 -1
- package/night-expansion-02-26-06-batch2.py +368 -0
- package/night-expansion-02-26-06-batch3.py +299 -0
- package/night-expansion-02-26-06.py +756 -0
- package/package.json +2 -1
- package/scripts/bulk-add-public-apis-v2.py +418 -0
- package/scripts/merge-to-registry.py +77 -0
- package/scripts/night-batch-02-24.py +391 -0
- package/scripts/night-batch-02-25.py +479 -0
- package/scripts/night-batch-03-24-b2.py +387 -0
- package/scripts/night-batch-03-24-b3.py +284 -0
- package/scripts/night-batch-03-24.py +447 -0
- package/scripts/night-batch-06-24-b2.py +695 -0
- package/scripts/night-batch-06-24-b3.py +696 -0
- package/scripts/night-batch-06-24.py +825 -0
- package/scripts/night-expansion-02-24-02.py +708 -0
- package/scripts/night-expansion-02-25.py +668 -0
- package/scripts/night-expansion-02-26-v2.py +296 -0
- package/scripts/night-expansion-02-26.py +890 -0
- package/scripts/seed-complete-api.js +181 -0
- package/scripts/seed-demo-api.sh +44 -0
- package/src/credentials.ts +16 -0
- package/src/crypto.ts +75 -0
- package/src/execute-dynamic.ts +589 -0
- package/src/execute.ts +127 -5
- package/src/index.ts +40 -4
- package/src/proxy.ts +1 -1
- package/src/registry/apis.json +46554 -174
package/landing/src/app/page.tsx
CHANGED
|
@@ -4,16 +4,18 @@ import {
|
|
|
4
4
|
ArrowRight, Zap, Shield, Terminal, ExternalLink,
|
|
5
5
|
Github, Check, Twitter, Sparkles, Code2, Link, Sun, Moon,
|
|
6
6
|
Bot, Building2, Search, Rocket, Clock, Globe, Database,
|
|
7
|
-
Play, ChevronRight, Star, Users, Cpu, Activity
|
|
7
|
+
Play, ChevronRight, ChevronDown, Star, Users, Cpu, Activity, Copy, FileText,
|
|
8
|
+
Menu, X
|
|
8
9
|
} from "lucide-react";
|
|
9
10
|
import statsData from "@/lib/stats.json";
|
|
10
11
|
import { useState, useEffect, useRef } from "react";
|
|
12
|
+
import { HeroTabs } from "@/components/HeroTabs";
|
|
11
13
|
|
|
12
14
|
const stats = [
|
|
13
15
|
{ number: statsData.apiCount.toLocaleString(), label: "APIs Indexed", live: true },
|
|
14
|
-
{ number:
|
|
15
|
-
{ number: "
|
|
16
|
-
{ number:
|
|
16
|
+
{ number: "865", label: "Open APIs", live: true },
|
|
17
|
+
{ number: "11", label: "Direct Call", live: true },
|
|
18
|
+
{ number: statsData.categoryCount.toString(), label: "Categories", live: false },
|
|
17
19
|
];
|
|
18
20
|
|
|
19
21
|
const trustedBy = [
|
|
@@ -29,16 +31,16 @@ const howItWorks = [
|
|
|
29
31
|
{
|
|
30
32
|
step: "1",
|
|
31
33
|
title: "Agent Asks",
|
|
32
|
-
description: "Your agent queries APIClaw for a capability
|
|
34
|
+
description: "Your agent queries APIClaw for a capability. Not a product name.",
|
|
33
35
|
icon: Search,
|
|
34
36
|
codeJsx: (
|
|
35
37
|
<>
|
|
36
|
-
<span className="text-gray-500">{"//
|
|
37
|
-
<span className="text-
|
|
38
|
-
|
|
39
|
-
{"
|
|
40
|
-
|
|
41
|
-
{"
|
|
38
|
+
<span className="text-gray-500">{"// User prompt to agent:"}</span>{"\n"}
|
|
39
|
+
<span className="text-green-400">"Generate a photorealistic image</span>{"\n"}
|
|
40
|
+
<span className="text-green-400">of a sunset over mountains"</span>{"\n"}
|
|
41
|
+
{"\n"}
|
|
42
|
+
<span className="text-gray-500">{"// Agent uses discover_apis tool"}</span>{"\n"}
|
|
43
|
+
<span className="text-gray-500">{"// query: \"image generation\""}</span>
|
|
42
44
|
</>
|
|
43
45
|
),
|
|
44
46
|
},
|
|
@@ -52,10 +54,10 @@ const howItWorks = [
|
|
|
52
54
|
<span className="text-gray-500">{"// Structured response"}</span>{"\n"}
|
|
53
55
|
{"{"}{"\n"}
|
|
54
56
|
{" "}<span className="text-red-400">"matches"</span>: [{"\n"}
|
|
55
|
-
{" "}{"{ "}<span className="text-red-400">"name"</span>: <span className="text-green-400">"
|
|
56
|
-
{" "}{"{ "}<span className="text-red-400">"name"</span>: <span className="text-green-400">"
|
|
57
|
+
{" "}{"{ "}<span className="text-red-400">"name"</span>: <span className="text-green-400">"Replicate"</span>, <span className="text-red-400">"models"</span>: <span className="text-yellow-400">"1000+"</span>{" },"}{"\n"}
|
|
58
|
+
{" "}{"{ "}<span className="text-red-400">"name"</span>: <span className="text-green-400">"OpenRouter"</span>, <span className="text-red-400">"models"</span>: <span className="text-yellow-400">"100+"</span>{" }"}{"\n"}
|
|
57
59
|
{" "}],{"\n"}
|
|
58
|
-
{" "}<span className="text-red-400">"bestMatch"</span>: <span className="text-green-400">"
|
|
60
|
+
{" "}<span className="text-red-400">"bestMatch"</span>: <span className="text-green-400">"Replicate"</span>{"\n"}
|
|
59
61
|
{"}"}
|
|
60
62
|
</>
|
|
61
63
|
),
|
|
@@ -63,16 +65,17 @@ const howItWorks = [
|
|
|
63
65
|
{
|
|
64
66
|
step: "3",
|
|
65
67
|
title: "Agent Integrates",
|
|
66
|
-
description: "Full specs, auth details, endpoints—
|
|
68
|
+
description: "Full specs, auth details, endpoints. Or use Direct Call — no keys needed.",
|
|
67
69
|
icon: Rocket,
|
|
68
70
|
codeJsx: (
|
|
69
71
|
<>
|
|
70
|
-
<span className="text-gray-500">{"//
|
|
71
|
-
|
|
72
|
-
{" "}<span className="text-red-400">
|
|
73
|
-
{" "}<span className="text-red-400">
|
|
74
|
-
{"}"}
|
|
75
|
-
|
|
72
|
+
<span className="text-gray-500">{"// Agent uses call_api tool"}</span>{"\n"}
|
|
73
|
+
{"{"}{"\n"}
|
|
74
|
+
{" "}<span className="text-red-400">"provider"</span>: <span className="text-green-400">"replicate"</span>,{"\n"}
|
|
75
|
+
{" "}<span className="text-red-400">"action"</span>: <span className="text-green-400">"flux-schnell"</span>,{"\n"}
|
|
76
|
+
{" "}<span className="text-red-400">"params"</span>: {"{ "}<span className="text-red-400">"prompt"</span>: <span className="text-green-400">"..."</span>{" }"}{"\n"}
|
|
77
|
+
{"}"}{"\n"}
|
|
78
|
+
<span className="text-gray-500">{"// → image URL, no API key needed"}</span>
|
|
76
79
|
</>
|
|
77
80
|
),
|
|
78
81
|
},
|
|
@@ -92,7 +95,7 @@ const agentBenefits = [
|
|
|
92
95
|
{
|
|
93
96
|
icon: Database,
|
|
94
97
|
title: "Structured Data",
|
|
95
|
-
description: "JSON responses with pricing, limits, regions, auth
|
|
98
|
+
description: "JSON responses with pricing, limits, regions, auth. Everything an agent needs.",
|
|
96
99
|
},
|
|
97
100
|
{
|
|
98
101
|
icon: Shield,
|
|
@@ -105,7 +108,7 @@ const providerBenefits = [
|
|
|
105
108
|
{
|
|
106
109
|
icon: Users,
|
|
107
110
|
title: "Reach AI Agents",
|
|
108
|
-
description: "Get discovered by
|
|
111
|
+
description: "Get discovered by AI agents searching for APIs like yours.",
|
|
109
112
|
},
|
|
110
113
|
{
|
|
111
114
|
icon: Globe,
|
|
@@ -127,7 +130,7 @@ const providerBenefits = [
|
|
|
127
130
|
const terminalLines = [
|
|
128
131
|
{ type: "prompt", text: "npx @nordsym/apiclaw" },
|
|
129
132
|
{ type: "output", text: "", delay: 500 },
|
|
130
|
-
{ type: "output", text: "🦞 APIClaw v1.
|
|
133
|
+
{ type: "output", text: "🦞 APIClaw v1.2.2", delay: 100 },
|
|
131
134
|
{ type: "output", text: "", delay: 50 },
|
|
132
135
|
{ type: "success", text: "✓ Connecting to registry...", delay: 300 },
|
|
133
136
|
{ type: "success", text: `✓ ${statsData.apiCount.toLocaleString()} APIs loaded`, delay: 200 },
|
|
@@ -137,17 +140,95 @@ const terminalLines = [
|
|
|
137
140
|
{ type: "accent", text: "→ Add to Claude Desktop: Settings → MCP → Add Server", delay: 0 },
|
|
138
141
|
];
|
|
139
142
|
|
|
143
|
+
const directCallProviders = [
|
|
144
|
+
{ name: "Replicate", desc: "1000+ ML models" },
|
|
145
|
+
{ name: "OpenRouter", desc: "100+ LLMs" },
|
|
146
|
+
{ name: "Firecrawl", desc: "Web scraping" },
|
|
147
|
+
{ name: "E2B", desc: "Code sandbox" },
|
|
148
|
+
{ name: "GitHub", desc: "Repos & Issues" },
|
|
149
|
+
{ name: "ElevenLabs", desc: "Text-to-speech" },
|
|
150
|
+
{ name: "Brave Search", desc: "Web search" },
|
|
151
|
+
{ name: "Resend", desc: "Email" },
|
|
152
|
+
{ name: "46elks", desc: "SMS (Nordic)" },
|
|
153
|
+
];
|
|
154
|
+
|
|
140
155
|
export default function Home() {
|
|
141
156
|
const [isDark, setIsDark] = useState(true);
|
|
142
|
-
const [
|
|
143
|
-
const [
|
|
144
|
-
const [currentLineIndex, setCurrentLineIndex] = useState(0);
|
|
157
|
+
const [showCopied, setShowCopied] = useState(false);
|
|
158
|
+
const [showContextCopied, setShowContextCopied] = useState(false);
|
|
145
159
|
const [activeSection, setActiveSection] = useState<string>("");
|
|
146
|
-
const
|
|
160
|
+
const [showProvidersModal, setShowProvidersModal] = useState(false);
|
|
161
|
+
const [showDirectCallModal, setShowDirectCallModal] = useState(false);
|
|
162
|
+
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
|
163
|
+
const [openFaq, setOpenFaq] = useState<number | null>(null);
|
|
164
|
+
const [waitlistEmail, setWaitlistEmail] = useState("");
|
|
165
|
+
const [waitlistStatus, setWaitlistStatus] = useState<"idle" | "loading" | "success" | "error">("idle");
|
|
166
|
+
|
|
167
|
+
const directCallProviders = [
|
|
168
|
+
{ name: "Replicate", desc: "Whisper, Stable Diffusion, 1000+ ML models", category: "AI & LLM" },
|
|
169
|
+
{ name: "OpenRouter", desc: "GPT-4, Claude, Llama, 100+ LLMs", category: "AI & LLM" },
|
|
170
|
+
{ name: "ElevenLabs", desc: "Text-to-speech in 29 languages", category: "Voice & TTS" },
|
|
171
|
+
{ name: "46elks", desc: "SMS in Sweden and globally", category: "SMS & Messaging" },
|
|
172
|
+
{ name: "Twilio", desc: "Enterprise SMS and voice", category: "SMS & Messaging" },
|
|
173
|
+
{ name: "Resend", desc: "Modern email API for developers", category: "Email" },
|
|
174
|
+
{ name: "Brave Search", desc: "Privacy-focused web search", category: "Search" },
|
|
175
|
+
{ name: "Firecrawl", desc: "Web scraping to LLM-ready markdown", category: "Search" },
|
|
176
|
+
{ name: "E2B", desc: "Secure cloud sandboxes for code execution", category: "AI & LLM" },
|
|
177
|
+
{ name: "GitHub", desc: "Repos, issues, PRs, and more", category: "Other" },
|
|
178
|
+
{ name: "CoinGecko", desc: "Crypto prices and market data", category: "Crypto" },
|
|
179
|
+
];
|
|
180
|
+
|
|
181
|
+
const copyToClipboard = () => {
|
|
182
|
+
navigator.clipboard.writeText('npx @nordsym/apiclaw');
|
|
183
|
+
setShowCopied(true);
|
|
184
|
+
setTimeout(() => setShowCopied(false), 2000);
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const copyContextToClipboard = () => {
|
|
188
|
+
const context = `APIClaw is the API layer for AI agents. It's an MCP server with ${statsData.apiCount.toLocaleString()}+ APIs.
|
|
189
|
+
|
|
190
|
+
Your agent can use these tools:
|
|
191
|
+
• discover_apis - Search APIs by capability (not keywords)
|
|
192
|
+
• get_api_details - Get full specs, pricing, and metadata
|
|
193
|
+
• call_api - Direct Call: use APIs without managing keys
|
|
194
|
+
• list_connected - See 11 available providers (Replicate, OpenRouter, ElevenLabs, etc.)
|
|
195
|
+
|
|
196
|
+
Install: npx @nordsym/apiclaw
|
|
197
|
+
Docs: https://apiclaw.nordsym.com/docs
|
|
198
|
+
Website: https://apiclaw.nordsym.com`;
|
|
199
|
+
navigator.clipboard.writeText(context);
|
|
200
|
+
setShowContextCopied(true);
|
|
201
|
+
setTimeout(() => setShowContextCopied(false), 2500);
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
const submitWaitlist = async (e: React.FormEvent) => {
|
|
205
|
+
e.preventDefault();
|
|
206
|
+
if (!waitlistEmail || waitlistStatus === "loading") return;
|
|
207
|
+
|
|
208
|
+
setWaitlistStatus("loading");
|
|
209
|
+
try {
|
|
210
|
+
const res = await fetch("https://adventurous-avocet-799.convex.cloud/api/mutation", {
|
|
211
|
+
method: "POST",
|
|
212
|
+
headers: { "Content-Type": "application/json" },
|
|
213
|
+
body: JSON.stringify({
|
|
214
|
+
path: "waitlist:join",
|
|
215
|
+
args: { email: waitlistEmail, type: "provider", source: "landing" }
|
|
216
|
+
})
|
|
217
|
+
});
|
|
218
|
+
if (res.ok) {
|
|
219
|
+
setWaitlistStatus("success");
|
|
220
|
+
setWaitlistEmail("");
|
|
221
|
+
} else {
|
|
222
|
+
setWaitlistStatus("error");
|
|
223
|
+
}
|
|
224
|
+
} catch {
|
|
225
|
+
setWaitlistStatus("error");
|
|
226
|
+
}
|
|
227
|
+
};
|
|
147
228
|
|
|
148
229
|
// Scroll-based active section detection using Intersection Observer
|
|
149
230
|
useEffect(() => {
|
|
150
|
-
const sections = ["how-it-works", "for-agents", "for-providers", "
|
|
231
|
+
const sections = ["how-it-works", "for-agents", "for-providers", "get-started", "faq"];
|
|
151
232
|
|
|
152
233
|
const observerOptions = {
|
|
153
234
|
root: null,
|
|
@@ -182,28 +263,6 @@ export default function Home() {
|
|
|
182
263
|
document.documentElement.classList.toggle('dark', prefersDark);
|
|
183
264
|
}, []);
|
|
184
265
|
|
|
185
|
-
// Terminal animation with auto-loop
|
|
186
|
-
useEffect(() => {
|
|
187
|
-
if (currentLineIndex >= terminalLines.length) {
|
|
188
|
-
setIsTyping(false);
|
|
189
|
-
// Auto-restart after 3 seconds
|
|
190
|
-
const restartTimeout = setTimeout(() => {
|
|
191
|
-
setTerminalOutput([]);
|
|
192
|
-
setCurrentLineIndex(0);
|
|
193
|
-
setIsTyping(true);
|
|
194
|
-
}, 3000);
|
|
195
|
-
return () => clearTimeout(restartTimeout);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const line = terminalLines[currentLineIndex];
|
|
199
|
-
const timeout = setTimeout(() => {
|
|
200
|
-
setTerminalOutput(prev => [...prev, line]);
|
|
201
|
-
setCurrentLineIndex(prev => prev + 1);
|
|
202
|
-
}, line.delay);
|
|
203
|
-
|
|
204
|
-
return () => clearTimeout(timeout);
|
|
205
|
-
}, [currentLineIndex]);
|
|
206
|
-
|
|
207
266
|
const toggleTheme = () => {
|
|
208
267
|
const newTheme = !isDark;
|
|
209
268
|
setIsDark(newTheme);
|
|
@@ -211,23 +270,19 @@ export default function Home() {
|
|
|
211
270
|
localStorage.setItem('theme', newTheme ? 'dark' : 'light');
|
|
212
271
|
};
|
|
213
272
|
|
|
214
|
-
const restartTerminal = () => {
|
|
215
|
-
setTerminalOutput([]);
|
|
216
|
-
setCurrentLineIndex(0);
|
|
217
|
-
setIsTyping(true);
|
|
218
|
-
};
|
|
219
|
-
|
|
220
273
|
return (
|
|
221
274
|
<main className="min-h-screen overflow-x-hidden">
|
|
222
275
|
{/* Header */}
|
|
223
276
|
<header className="fixed top-0 w-full z-50 bg-background/80 backdrop-blur-xl border-b border-border-subtle">
|
|
224
|
-
<div className="max-w-6xl mx-auto px-6 py-4 flex items-center justify-between">
|
|
225
|
-
<div className="flex items-center gap-3">
|
|
226
|
-
<div className="w-10 h-10 rounded-xl bg-accent/20 flex items-center justify-center text-2xl logo-float">
|
|
277
|
+
<div className="max-w-6xl mx-auto px-4 sm:px-6 py-3 sm:py-4 flex items-center justify-between">
|
|
278
|
+
<div className="flex items-center gap-2 sm:gap-3">
|
|
279
|
+
<div className="w-8 h-8 sm:w-10 sm:h-10 rounded-xl bg-accent/20 flex items-center justify-center text-xl sm:text-2xl logo-float">
|
|
227
280
|
🦞
|
|
228
281
|
</div>
|
|
229
|
-
<span className="font-bold text-xl tracking-tight">APIClaw</span>
|
|
282
|
+
<span className="font-bold text-lg sm:text-xl tracking-tight">APIClaw</span>
|
|
230
283
|
</div>
|
|
284
|
+
|
|
285
|
+
{/* Desktop nav */}
|
|
231
286
|
<nav className="hidden md:flex items-center gap-8 text-sm text-text-muted">
|
|
232
287
|
<a
|
|
233
288
|
href="#how-it-works"
|
|
@@ -248,13 +303,34 @@ export default function Home() {
|
|
|
248
303
|
For Providers
|
|
249
304
|
</a>
|
|
250
305
|
<a
|
|
251
|
-
href="
|
|
252
|
-
className=
|
|
306
|
+
href="/docs"
|
|
307
|
+
className="transition hover:text-text-primary"
|
|
308
|
+
>
|
|
309
|
+
Docs
|
|
310
|
+
</a>
|
|
311
|
+
<a
|
|
312
|
+
href="/earn"
|
|
313
|
+
className="transition hover:text-text-primary"
|
|
253
314
|
>
|
|
254
|
-
|
|
315
|
+
Earn
|
|
316
|
+
</a>
|
|
317
|
+
<a
|
|
318
|
+
href="#faq"
|
|
319
|
+
className={`transition ${activeSection === "faq" ? "text-accent font-medium" : "hover:text-text-primary"}`}
|
|
320
|
+
>
|
|
321
|
+
FAQ
|
|
255
322
|
</a>
|
|
256
323
|
</nav>
|
|
257
|
-
|
|
324
|
+
|
|
325
|
+
{/* Desktop actions */}
|
|
326
|
+
<div className="hidden md:flex items-center gap-3">
|
|
327
|
+
<a
|
|
328
|
+
href="/providers/dashboard"
|
|
329
|
+
className="text-sm text-text-muted hover:text-accent transition flex items-center gap-1"
|
|
330
|
+
>
|
|
331
|
+
<FileText className="w-4 h-4" />
|
|
332
|
+
Add Your API
|
|
333
|
+
</a>
|
|
258
334
|
<button
|
|
259
335
|
onClick={toggleTheme}
|
|
260
336
|
className="p-2.5 rounded-lg hover:bg-surface transition"
|
|
@@ -266,19 +342,93 @@ export default function Home() {
|
|
|
266
342
|
href="https://github.com/nordsym/apiclaw"
|
|
267
343
|
target="_blank"
|
|
268
344
|
rel="noopener noreferrer"
|
|
269
|
-
className="btn-ghost
|
|
345
|
+
className="btn-ghost"
|
|
270
346
|
>
|
|
271
347
|
<Github className="w-4 h-4" />
|
|
272
348
|
<span>GitHub</span>
|
|
273
349
|
</a>
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
350
|
+
</div>
|
|
351
|
+
|
|
352
|
+
{/* Mobile actions */}
|
|
353
|
+
<div className="flex md:hidden items-center gap-2">
|
|
354
|
+
<button
|
|
355
|
+
onClick={toggleTheme}
|
|
356
|
+
className="p-2 rounded-lg hover:bg-surface transition"
|
|
357
|
+
aria-label="Toggle theme"
|
|
277
358
|
>
|
|
278
|
-
|
|
279
|
-
</
|
|
359
|
+
{isDark ? <Sun className="w-5 h-5" /> : <Moon className="w-5 h-5" />}
|
|
360
|
+
</button>
|
|
361
|
+
<button
|
|
362
|
+
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
|
363
|
+
className="p-2 rounded-lg hover:bg-surface transition"
|
|
364
|
+
aria-label="Toggle menu"
|
|
365
|
+
>
|
|
366
|
+
{mobileMenuOpen ? <X className="w-5 h-5" /> : <Menu className="w-5 h-5" />}
|
|
367
|
+
</button>
|
|
280
368
|
</div>
|
|
281
369
|
</div>
|
|
370
|
+
|
|
371
|
+
{/* Mobile menu */}
|
|
372
|
+
{mobileMenuOpen && (
|
|
373
|
+
<div className="md:hidden bg-background border-t border-border">
|
|
374
|
+
<nav className="flex flex-col px-4 py-4 space-y-3 text-sm">
|
|
375
|
+
<a
|
|
376
|
+
href="#how-it-works"
|
|
377
|
+
onClick={() => setMobileMenuOpen(false)}
|
|
378
|
+
className="py-2 text-text-muted hover:text-text-primary transition"
|
|
379
|
+
>
|
|
380
|
+
How It Works
|
|
381
|
+
</a>
|
|
382
|
+
<a
|
|
383
|
+
href="#for-agents"
|
|
384
|
+
onClick={() => setMobileMenuOpen(false)}
|
|
385
|
+
className="py-2 text-text-muted hover:text-text-primary transition"
|
|
386
|
+
>
|
|
387
|
+
For Agents
|
|
388
|
+
</a>
|
|
389
|
+
<a
|
|
390
|
+
href="#for-providers"
|
|
391
|
+
onClick={() => setMobileMenuOpen(false)}
|
|
392
|
+
className="py-2 text-text-muted hover:text-text-primary transition"
|
|
393
|
+
>
|
|
394
|
+
For Providers
|
|
395
|
+
</a>
|
|
396
|
+
<a
|
|
397
|
+
href="#get-started"
|
|
398
|
+
onClick={() => setMobileMenuOpen(false)}
|
|
399
|
+
className="py-2 text-text-muted hover:text-text-primary transition"
|
|
400
|
+
>
|
|
401
|
+
Get Started
|
|
402
|
+
</a>
|
|
403
|
+
<a
|
|
404
|
+
href="#faq"
|
|
405
|
+
onClick={() => setMobileMenuOpen(false)}
|
|
406
|
+
className="py-2 text-text-muted hover:text-text-primary transition"
|
|
407
|
+
>
|
|
408
|
+
FAQ
|
|
409
|
+
</a>
|
|
410
|
+
<div className="border-t border-border pt-3 mt-1 flex flex-col space-y-3">
|
|
411
|
+
<a
|
|
412
|
+
href="/providers/dashboard"
|
|
413
|
+
onClick={() => setMobileMenuOpen(false)}
|
|
414
|
+
className="py-2 text-accent font-medium flex items-center gap-2"
|
|
415
|
+
>
|
|
416
|
+
<FileText className="w-4 h-4" />
|
|
417
|
+
Add Your API
|
|
418
|
+
</a>
|
|
419
|
+
<a
|
|
420
|
+
href="https://github.com/nordsym/apiclaw"
|
|
421
|
+
target="_blank"
|
|
422
|
+
rel="noopener noreferrer"
|
|
423
|
+
className="py-2 text-text-muted hover:text-text-primary transition flex items-center gap-2"
|
|
424
|
+
>
|
|
425
|
+
<Github className="w-4 h-4" />
|
|
426
|
+
GitHub
|
|
427
|
+
</a>
|
|
428
|
+
</div>
|
|
429
|
+
</nav>
|
|
430
|
+
</div>
|
|
431
|
+
)}
|
|
282
432
|
</header>
|
|
283
433
|
|
|
284
434
|
{/* Hero */}
|
|
@@ -286,11 +436,19 @@ export default function Home() {
|
|
|
286
436
|
<div className="hero-glow" />
|
|
287
437
|
|
|
288
438
|
<div className="max-w-6xl mx-auto relative z-10">
|
|
289
|
-
<div className="grid lg:grid-cols-2 gap-12 lg:gap-16 items-
|
|
439
|
+
<div className="grid lg:grid-cols-2 gap-12 lg:gap-16 items-start">
|
|
290
440
|
{/* Left: Copy */}
|
|
291
441
|
<div className="text-center lg:text-left">
|
|
292
|
-
<div className="
|
|
293
|
-
<
|
|
442
|
+
<div className="flex flex-wrap items-center justify-center lg:justify-start gap-3 mb-6">
|
|
443
|
+
<div className="badge badge-live inline-flex">
|
|
444
|
+
<span className="flex items-center gap-2"><span className="w-2 h-2 bg-green-500 rounded-full animate-pulse" />Live • {statsData.apiCount.toLocaleString()} APIs</span>
|
|
445
|
+
</div>
|
|
446
|
+
<button
|
|
447
|
+
onClick={() => setShowProvidersModal(true)}
|
|
448
|
+
className="badge inline-flex bg-accent/10 border-accent/30 text-accent hover:bg-accent/20 transition-colors cursor-pointer"
|
|
449
|
+
>
|
|
450
|
+
<span className="flex items-center gap-2"><Zap className="w-3 h-3" />Direct Call: AI Models, Web Scraping, Code Execution & more</span>
|
|
451
|
+
</button>
|
|
294
452
|
</div>
|
|
295
453
|
|
|
296
454
|
<h1 className="text-5xl md:text-6xl lg:text-7xl font-black mb-6 leading-[1.05] tracking-tighter">
|
|
@@ -303,77 +461,36 @@ export default function Home() {
|
|
|
303
461
|
Find, evaluate, and integrate APIs in milliseconds.
|
|
304
462
|
</p>
|
|
305
463
|
|
|
306
|
-
<p className="text-text-muted mb-
|
|
464
|
+
<p className="text-text-muted mb-6 max-w-lg mx-auto lg:mx-0">
|
|
307
465
|
Structured data. Ranked results. Sub-200ms responses.
|
|
308
466
|
Built for the agentic era.
|
|
309
467
|
</p>
|
|
310
|
-
|
|
311
|
-
<div className="flex flex-col sm:flex-row items-center justify-center lg:justify-start gap-4 mb-8">
|
|
312
|
-
<button
|
|
313
|
-
onClick={() => {
|
|
314
|
-
navigator.clipboard.writeText('npx @nordsym/apiclaw');
|
|
315
|
-
alert('Copied: npx @nordsym/apiclaw');
|
|
316
|
-
}}
|
|
317
|
-
className="btn-primary glow-pulse"
|
|
318
|
-
>
|
|
319
|
-
<Terminal className="w-5 h-5" />
|
|
320
|
-
<code className="font-mono">npx @nordsym/apiclaw</code>
|
|
321
|
-
<span className="text-xs opacity-70">copy</span>
|
|
322
|
-
</button>
|
|
323
|
-
<a
|
|
324
|
-
href="https://github.com/nordsym/apiclaw"
|
|
325
|
-
target="_blank"
|
|
326
|
-
rel="noopener noreferrer"
|
|
327
|
-
className="btn-secondary"
|
|
328
|
-
>
|
|
329
|
-
<Github className="w-5 h-5" />
|
|
330
|
-
View on GitHub
|
|
331
|
-
</a>
|
|
332
|
-
</div>
|
|
333
|
-
|
|
334
|
-
{/* Social proof */}
|
|
335
|
-
<p className="text-sm text-text-muted mt-4 flex items-center gap-2">
|
|
336
|
-
<Users className="w-4 h-4" />
|
|
337
|
-
<span>The API layer agent builders are switching to</span>
|
|
338
|
-
</p>
|
|
339
|
-
|
|
340
|
-
</div>
|
|
341
468
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
<span className="
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
{line.type === 'success' && (
|
|
364
|
-
<span className="terminal-success">{line.text}</span>
|
|
365
|
-
)}
|
|
366
|
-
{line.type === 'accent' && (
|
|
367
|
-
<span className="terminal-accent">{line.text}</span>
|
|
368
|
-
)}
|
|
369
|
-
</div>
|
|
370
|
-
))}
|
|
371
|
-
{isTyping && <span className="typing-cursor" />}
|
|
372
|
-
</div>
|
|
373
|
-
</div>
|
|
374
|
-
|
|
375
|
-
{/* Auto-loops - no replay button needed */}
|
|
469
|
+
{/* Copy Context Button */}
|
|
470
|
+
<button
|
|
471
|
+
onClick={copyContextToClipboard}
|
|
472
|
+
className="group relative inline-flex items-center gap-3 px-6 py-4 bg-gradient-to-r from-accent to-accent/80 hover:from-accent/90 hover:to-accent/70 text-white font-bold rounded-2xl shadow-lg shadow-accent/25 hover:shadow-xl hover:shadow-accent/30 transition-all duration-300 hover:scale-[1.02]"
|
|
473
|
+
>
|
|
474
|
+
<Sparkles className="w-6 h-6" />
|
|
475
|
+
<span className="flex flex-col items-start">
|
|
476
|
+
<span className="text-base">{showContextCopied ? "Copied!" : "Explain to your AI"}</span>
|
|
477
|
+
<span className="text-xs opacity-80 font-normal">Copy context for your agent</span>
|
|
478
|
+
</span>
|
|
479
|
+
{showContextCopied ? (
|
|
480
|
+
<Check className="w-5 h-5" />
|
|
481
|
+
) : (
|
|
482
|
+
<Copy className="w-5 h-5 group-hover:scale-110 transition-transform" />
|
|
483
|
+
)}
|
|
484
|
+
{showContextCopied && (
|
|
485
|
+
<span className="absolute -top-12 left-1/2 -translate-x-1/2 bg-black text-white text-sm px-4 py-2 rounded-lg whitespace-nowrap shadow-lg">
|
|
486
|
+
✓ Paste this to your AI agent!
|
|
487
|
+
</span>
|
|
488
|
+
)}
|
|
489
|
+
</button>
|
|
376
490
|
</div>
|
|
491
|
+
|
|
492
|
+
{/* Right: HeroTabs */}
|
|
493
|
+
<HeroTabs />
|
|
377
494
|
</div>
|
|
378
495
|
</div>
|
|
379
496
|
</section>
|
|
@@ -383,7 +500,11 @@ export default function Home() {
|
|
|
383
500
|
<div className="max-w-5xl mx-auto">
|
|
384
501
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-6">
|
|
385
502
|
{stats.map((stat, i) => (
|
|
386
|
-
<div
|
|
503
|
+
<div
|
|
504
|
+
key={i}
|
|
505
|
+
className={`stat-card relative ${stat.label === "Direct Call" ? "cursor-pointer hover:border-accent/50 transition-colors" : ""}`}
|
|
506
|
+
onClick={stat.label === "Direct Call" ? () => setShowDirectCallModal(true) : undefined}
|
|
507
|
+
>
|
|
387
508
|
{stat.live && (
|
|
388
509
|
<div className="absolute top-2 right-2 flex items-center gap-1">
|
|
389
510
|
<span className="w-2 h-2 bg-green-500 rounded-full animate-pulse" />
|
|
@@ -392,12 +513,42 @@ export default function Home() {
|
|
|
392
513
|
)}
|
|
393
514
|
<div className="stat-number">{stat.number}</div>
|
|
394
515
|
<div className="stat-label">{stat.label}</div>
|
|
516
|
+
{stat.label === "Direct Call" && (
|
|
517
|
+
<div className="text-xs text-text-muted mt-1">Click to see all →</div>
|
|
518
|
+
)}
|
|
395
519
|
</div>
|
|
396
520
|
))}
|
|
397
521
|
</div>
|
|
398
522
|
</div>
|
|
399
523
|
</section>
|
|
400
524
|
|
|
525
|
+
{/* Direct Call Modal */}
|
|
526
|
+
{showDirectCallModal && (
|
|
527
|
+
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/80 backdrop-blur-sm" onClick={() => setShowDirectCallModal(false)}>
|
|
528
|
+
<div className="bg-surface-elevated border border-border rounded-2xl p-6 max-w-lg w-full max-h-[80vh] overflow-y-auto" onClick={e => e.stopPropagation()}>
|
|
529
|
+
<div className="flex items-center justify-between mb-6">
|
|
530
|
+
<h3 className="text-xl font-bold">⚡ Direct Call Providers</h3>
|
|
531
|
+
<button onClick={() => setShowDirectCallModal(false)} className="p-2 hover:bg-surface rounded-lg transition">
|
|
532
|
+
<X className="w-5 h-5" />
|
|
533
|
+
</button>
|
|
534
|
+
</div>
|
|
535
|
+
<p className="text-text-muted mb-4">These APIs work through APIClaw's proxy. Your agent calls them without needing API keys.</p>
|
|
536
|
+
<div className="space-y-3">
|
|
537
|
+
{directCallProviders.map((provider, i) => (
|
|
538
|
+
<div key={i} className="flex items-center justify-between p-3 rounded-xl bg-surface border border-border">
|
|
539
|
+
<div>
|
|
540
|
+
<div className="font-medium">{provider.name}</div>
|
|
541
|
+
<div className="text-sm text-text-muted">{provider.desc}</div>
|
|
542
|
+
</div>
|
|
543
|
+
<span className="text-xs px-2 py-1 rounded-full bg-accent/20 text-accent">{provider.category}</span>
|
|
544
|
+
</div>
|
|
545
|
+
))}
|
|
546
|
+
</div>
|
|
547
|
+
<p className="text-sm text-text-muted mt-4 text-center">New providers added weekly</p>
|
|
548
|
+
</div>
|
|
549
|
+
</div>
|
|
550
|
+
)}
|
|
551
|
+
|
|
401
552
|
{/* Before/After */}
|
|
402
553
|
<section className="py-12 px-6">
|
|
403
554
|
<div className="max-w-4xl mx-auto">
|
|
@@ -432,7 +583,7 @@ export default function Home() {
|
|
|
432
583
|
<ul className="space-y-3 text-text-secondary">
|
|
433
584
|
<li className="flex items-start gap-2">
|
|
434
585
|
<span className="text-green-400 mt-1">✓</span>
|
|
435
|
-
<span><strong
|
|
586
|
+
<span><strong>∞ hours saved</strong> per integration</span>
|
|
436
587
|
</li>
|
|
437
588
|
<li className="flex items-start gap-2">
|
|
438
589
|
<span className="text-green-400 mt-1">✓</span>
|
|
@@ -440,7 +591,7 @@ export default function Home() {
|
|
|
440
591
|
</li>
|
|
441
592
|
<li className="flex items-start gap-2">
|
|
442
593
|
<span className="text-green-400 mt-1">✓</span>
|
|
443
|
-
<span>Direct Call:
|
|
594
|
+
<span>Direct Call: AI, Scraping, Code & more</span>
|
|
444
595
|
</li>
|
|
445
596
|
<li className="flex items-start gap-2">
|
|
446
597
|
<span className="text-green-400 mt-1">✓</span>
|
|
@@ -449,6 +600,95 @@ export default function Home() {
|
|
|
449
600
|
</ul>
|
|
450
601
|
</div>
|
|
451
602
|
</div>
|
|
603
|
+
<p className="text-center text-sm text-text-muted mt-8">
|
|
604
|
+
<Sparkles className="w-4 h-4 inline mr-1" />
|
|
605
|
+
API providers: White-glove onboarding available. Limited spots.
|
|
606
|
+
</p>
|
|
607
|
+
|
|
608
|
+
{/* Waitlist Form */}
|
|
609
|
+
<div className="max-w-md mx-auto mt-6">
|
|
610
|
+
{waitlistStatus === "success" ? (
|
|
611
|
+
<div className="flex items-center justify-center gap-2 text-green-500 bg-green-500/10 rounded-xl px-4 py-3">
|
|
612
|
+
<Check className="w-5 h-5" />
|
|
613
|
+
<span>You're on the list! We'll reach out soon.</span>
|
|
614
|
+
</div>
|
|
615
|
+
) : (
|
|
616
|
+
<form onSubmit={submitWaitlist} className="flex gap-2">
|
|
617
|
+
<input
|
|
618
|
+
type="email"
|
|
619
|
+
placeholder="your@email.com"
|
|
620
|
+
value={waitlistEmail}
|
|
621
|
+
onChange={(e) => setWaitlistEmail(e.target.value)}
|
|
622
|
+
required
|
|
623
|
+
className="flex-1 px-4 py-3 rounded-xl bg-surface border border-border focus:border-accent focus:outline-none text-sm"
|
|
624
|
+
/>
|
|
625
|
+
<button
|
|
626
|
+
type="submit"
|
|
627
|
+
disabled={waitlistStatus === "loading"}
|
|
628
|
+
className="px-6 py-3 bg-accent hover:bg-accent/90 text-white font-medium rounded-xl transition-colors disabled:opacity-50"
|
|
629
|
+
>
|
|
630
|
+
{waitlistStatus === "loading" ? "..." : "Join Waitlist"}
|
|
631
|
+
</button>
|
|
632
|
+
</form>
|
|
633
|
+
)}
|
|
634
|
+
{waitlistStatus === "error" && (
|
|
635
|
+
<p className="text-red-500 text-sm text-center mt-2">Something went wrong. Try again.</p>
|
|
636
|
+
)}
|
|
637
|
+
</div>
|
|
638
|
+
</div>
|
|
639
|
+
</section>
|
|
640
|
+
|
|
641
|
+
{/* Quick Start */}
|
|
642
|
+
<section className="py-16 px-6 bg-surface/50">
|
|
643
|
+
<div className="max-w-3xl mx-auto">
|
|
644
|
+
<div className="text-center mb-8">
|
|
645
|
+
<h2 className="text-2xl md:text-3xl font-bold flex items-center justify-center gap-3">
|
|
646
|
+
<Zap className="w-6 h-6 text-accent" />
|
|
647
|
+
Quick Start
|
|
648
|
+
</h2>
|
|
649
|
+
<p className="text-text-secondary mt-2">Get running in 30 seconds</p>
|
|
650
|
+
</div>
|
|
651
|
+
|
|
652
|
+
<div className="grid md:grid-cols-2 gap-6">
|
|
653
|
+
{/* Install */}
|
|
654
|
+
<div className="code-preview">
|
|
655
|
+
<div className="code-preview-header">
|
|
656
|
+
terminal
|
|
657
|
+
</div>
|
|
658
|
+
<div className="code-preview-body">
|
|
659
|
+
<pre className="text-sm whitespace-pre-wrap">
|
|
660
|
+
<span className="text-gray-500"># Run directly with npx</span>{"\n"}
|
|
661
|
+
<span className="text-green-400">$</span> <span className="text-blue-400">npx</span> @nordsym/apiclaw{"\n\n"}
|
|
662
|
+
<span className="text-gray-500"># Or install globally</span>{"\n"}
|
|
663
|
+
<span className="text-green-400">$</span> <span className="text-blue-400">npm</span> install -g @nordsym/apiclaw{"\n"}
|
|
664
|
+
<span className="text-green-400">$</span> apiclaw
|
|
665
|
+
</pre>
|
|
666
|
+
</div>
|
|
667
|
+
</div>
|
|
668
|
+
|
|
669
|
+
{/* MCP Config */}
|
|
670
|
+
<div className="code-preview">
|
|
671
|
+
<div className="code-preview-header">
|
|
672
|
+
claude_desktop_config.json
|
|
673
|
+
</div>
|
|
674
|
+
<div className="code-preview-body">
|
|
675
|
+
<pre className="text-sm whitespace-pre-wrap">
|
|
676
|
+
<span className="text-gray-500">{"{"}</span>{"\n"}
|
|
677
|
+
{" "}<span className="text-red-400">"mcpServers"</span>: <span className="text-gray-500">{"{"}</span>{"\n"}
|
|
678
|
+
{" "}<span className="text-red-400">"apiclaw"</span>: <span className="text-gray-500">{"{"}</span>{"\n"}
|
|
679
|
+
{" "}<span className="text-red-400">"command"</span>: <span className="text-green-400">"npx"</span>,{"\n"}
|
|
680
|
+
{" "}<span className="text-red-400">"args"</span>: [<span className="text-green-400">"@nordsym/apiclaw"</span>]{"\n"}
|
|
681
|
+
{" "}<span className="text-gray-500">{"}"}</span>{"\n"}
|
|
682
|
+
{" "}<span className="text-gray-500">{"}"}</span>{"\n"}
|
|
683
|
+
<span className="text-gray-500">{"}"}</span>
|
|
684
|
+
</pre>
|
|
685
|
+
</div>
|
|
686
|
+
</div>
|
|
687
|
+
</div>
|
|
688
|
+
|
|
689
|
+
<p className="text-center text-sm text-text-muted mt-6">
|
|
690
|
+
Works with Claude Desktop, Cursor, and any MCP-compatible client
|
|
691
|
+
</p>
|
|
452
692
|
</div>
|
|
453
693
|
</section>
|
|
454
694
|
|
|
@@ -458,13 +698,13 @@ export default function Home() {
|
|
|
458
698
|
<section id="how-it-works" className="py-24 px-6">
|
|
459
699
|
<div className="max-w-6xl mx-auto">
|
|
460
700
|
<div className="text-center mb-16">
|
|
461
|
-
<span className="section-label">
|
|
701
|
+
<span className="section-label">DIRECT CALL</span>
|
|
462
702
|
<h2 className="text-3xl md:text-5xl font-bold mt-4 tracking-tight">
|
|
463
|
-
Three steps.
|
|
703
|
+
Three steps. No API keys.
|
|
464
704
|
</h2>
|
|
465
705
|
<p className="text-text-secondary text-lg mt-4 max-w-2xl mx-auto">
|
|
466
|
-
Your agent asks
|
|
467
|
-
|
|
706
|
+
Your agent asks, APIClaw matches, and calls the API directly —
|
|
707
|
+
no keys needed.
|
|
468
708
|
</p>
|
|
469
709
|
</div>
|
|
470
710
|
|
|
@@ -542,33 +782,27 @@ export default function Home() {
|
|
|
542
782
|
|
|
543
783
|
<div className="code-preview">
|
|
544
784
|
<div className="code-preview-header">
|
|
545
|
-
|
|
785
|
+
mcp-config.json
|
|
546
786
|
</div>
|
|
547
787
|
<div className="code-preview-body">
|
|
548
788
|
<pre className="text-sm">
|
|
549
|
-
<span className="text-gray-500">{"//
|
|
550
|
-
|
|
551
|
-
{" "}<span className="text-red-400">
|
|
552
|
-
{"
|
|
553
|
-
{"
|
|
554
|
-
{"}"
|
|
555
|
-
{"\n"}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
<span className="text-gray-500">{"// ["}</span>{"\n"}
|
|
559
|
-
<span className="text-gray-500">{"// { "}<span className="text-red-400">name</span>: <span className="text-green-400">"OneSignal"</span>, <span className="text-red-400">price</span>: <span className="text-yellow-400">"$0.0005"</span>{" }"}</span>{"\n"}
|
|
560
|
-
<span className="text-gray-500">{"// { "}<span className="text-red-400">name</span>: <span className="text-green-400">"Firebase"</span>, <span className="text-red-400">price</span>: <span className="text-yellow-400">"free"</span>{" }"}</span>{"\n"}
|
|
561
|
-
<span className="text-gray-500">{"// { "}<span className="text-red-400">name</span>: <span className="text-green-400">"Pusher"</span>, <span className="text-red-400">price</span>: <span className="text-yellow-400">"$0.001"</span>{" }"}</span>{"\n"}
|
|
562
|
-
<span className="text-gray-500">{"// ]"}</span>{"\n"}
|
|
789
|
+
<span className="text-gray-500">{"// Add to your MCP settings"}</span>{"\n"}
|
|
790
|
+
{"{"}{"\n"}
|
|
791
|
+
{" "}<span className="text-red-400">"mcpServers"</span>: {"{"}{"\n"}
|
|
792
|
+
{" "}<span className="text-red-400">"apiclaw"</span>: {"{"}{"\n"}
|
|
793
|
+
{" "}<span className="text-red-400">"command"</span>: <span className="text-green-400">"npx"</span>,{"\n"}
|
|
794
|
+
{" "}<span className="text-red-400">"args"</span>: [<span className="text-green-400">"@nordsym/apiclaw"</span>]{"\n"}
|
|
795
|
+
{" "}{"}"}{"\n"}
|
|
796
|
+
{" "}{"}"}{"\n"}
|
|
797
|
+
{"}"}{"\n"}
|
|
563
798
|
{"\n"}
|
|
564
|
-
<span className="text-gray-500">{"//
|
|
565
|
-
<span className="text-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
{"
|
|
799
|
+
<span className="text-gray-500">{"// That's it. Your agent now has access to:"}</span>{"\n"}
|
|
800
|
+
<span className="text-gray-500">{"// • discover_apis - Find APIs by capability"}</span>{"\n"}
|
|
801
|
+
<span className="text-gray-500">{"// • get_api_details - Full specs & pricing"}</span>{"\n"}
|
|
802
|
+
<span className="text-gray-500">{"// • call_api - Direct Call (no keys needed)"}</span>{"\n"}
|
|
803
|
+
<span className="text-gray-500">{"// • list_connected - See available providers"}</span>{"\n"}
|
|
569
804
|
{"\n"}
|
|
570
|
-
<span className="text-gray-500">{"//
|
|
571
|
-
<span className="text-gray-500">{"// Your agent can now integrate dynamically! 🚀"}</span>
|
|
805
|
+
<span className="text-gray-500">{"// Works with Claude, Cursor, and any MCP client 🦞"}</span>
|
|
572
806
|
</pre>
|
|
573
807
|
</div>
|
|
574
808
|
</div>
|
|
@@ -639,7 +873,7 @@ export default function Home() {
|
|
|
639
873
|
</h2>
|
|
640
874
|
|
|
641
875
|
<p className="text-text-secondary text-lg mb-8 leading-relaxed">
|
|
642
|
-
AI agents are the new developers. They don't browse landing pages
|
|
876
|
+
AI agents are the new developers. They don't browse landing pages.
|
|
643
877
|
they query capabilities. Get your API in front of them.
|
|
644
878
|
</p>
|
|
645
879
|
|
|
@@ -663,30 +897,27 @@ export default function Home() {
|
|
|
663
897
|
|
|
664
898
|
<div className="divider" />
|
|
665
899
|
|
|
666
|
-
{/*
|
|
667
|
-
<section id="
|
|
900
|
+
{/* Get Started */}
|
|
901
|
+
<section id="get-started" className="py-24 px-6 bg-surface/30">
|
|
668
902
|
<div className="max-w-4xl mx-auto">
|
|
669
903
|
<div className="text-center mb-16">
|
|
670
|
-
<span className="section-label">
|
|
904
|
+
<span className="section-label">GET STARTED</span>
|
|
671
905
|
<h2 className="text-3xl md:text-4xl font-bold mt-4 tracking-tight">
|
|
672
906
|
Simple. Free. Forever.
|
|
673
907
|
</h2>
|
|
674
908
|
<p className="text-text-secondary text-lg mt-4">
|
|
675
|
-
API discovery should be free. We're building the
|
|
909
|
+
API discovery should be free. We're building the API layer for AI agents.
|
|
676
910
|
</p>
|
|
677
911
|
</div>
|
|
678
912
|
|
|
679
913
|
<div className="grid md:grid-cols-2 gap-8">
|
|
680
|
-
{/*
|
|
914
|
+
{/* For Agents */}
|
|
681
915
|
<div className="rounded-2xl bg-surface-elevated border-2 border-accent p-8 relative glow">
|
|
682
916
|
<div className="absolute -top-3 left-1/2 -translate-x-1/2 px-4 py-1 bg-accent text-white text-xs font-bold tracking-wide rounded-full uppercase">
|
|
683
|
-
|
|
684
|
-
</div>
|
|
685
|
-
<h3 className="text-2xl font-bold mb-2">Discovery</h3>
|
|
686
|
-
<p className="text-text-secondary mb-6">Full API discovery and evaluation</p>
|
|
687
|
-
<div className="text-5xl font-black mb-6">
|
|
688
|
-
$0<span className="text-lg text-text-muted font-normal">/forever</span>
|
|
917
|
+
Live Now
|
|
689
918
|
</div>
|
|
919
|
+
<h3 className="text-2xl font-bold mb-2">For Agents</h3>
|
|
920
|
+
<p className="text-text-secondary mb-8">Discovery + Direct Call</p>
|
|
690
921
|
<ul className="space-y-4 mb-8">
|
|
691
922
|
<li className="flex items-center gap-3 text-text-secondary">
|
|
692
923
|
<Check className="w-5 h-5 text-accent flex-shrink-0" />
|
|
@@ -694,106 +925,122 @@ export default function Home() {
|
|
|
694
925
|
</li>
|
|
695
926
|
<li className="flex items-center gap-3 text-text-secondary">
|
|
696
927
|
<Check className="w-5 h-5 text-accent flex-shrink-0" />
|
|
697
|
-
|
|
928
|
+
Direct Call: Use APIs without keys
|
|
698
929
|
</li>
|
|
699
930
|
<li className="flex items-center gap-3 text-text-secondary">
|
|
700
931
|
<Check className="w-5 h-5 text-accent flex-shrink-0" />
|
|
701
|
-
|
|
932
|
+
10+ providers (AI Models, Scraping, Code, Search)
|
|
702
933
|
</li>
|
|
703
934
|
<li className="flex items-center gap-3 text-text-secondary">
|
|
704
935
|
<Check className="w-5 h-5 text-accent flex-shrink-0" />
|
|
705
|
-
|
|
936
|
+
Structured JSON responses
|
|
706
937
|
</li>
|
|
707
938
|
<li className="flex items-center gap-3 text-text-secondary">
|
|
708
939
|
<Check className="w-5 h-5 text-accent flex-shrink-0" />
|
|
709
|
-
|
|
940
|
+
MCP native
|
|
710
941
|
</li>
|
|
711
942
|
</ul>
|
|
712
|
-
<a href="
|
|
943
|
+
<a href="/docs" className="btn-primary w-full justify-center">
|
|
713
944
|
Get Started Free
|
|
714
945
|
</a>
|
|
715
946
|
</div>
|
|
716
947
|
|
|
717
|
-
{/*
|
|
718
|
-
<div className="rounded-2xl bg-surface-elevated border border-
|
|
719
|
-
<div className="absolute -top-3 left-1/2 -translate-x-1/2 px-4 py-1 bg-
|
|
720
|
-
|
|
721
|
-
</div>
|
|
722
|
-
<h3 className="text-2xl font-bold mb-2">Provisioning</h3>
|
|
723
|
-
<p className="text-text-secondary mb-6">Agent-native credential management</p>
|
|
724
|
-
<div className="text-3xl font-bold mb-2 text-text-muted">
|
|
725
|
-
Free Beta
|
|
948
|
+
{/* For Providers */}
|
|
949
|
+
<div className="rounded-2xl bg-surface-elevated border-2 border-accent p-8 relative glow">
|
|
950
|
+
<div className="absolute -top-3 left-1/2 -translate-x-1/2 px-4 py-1 bg-accent text-white text-xs font-bold tracking-wide rounded-full uppercase">
|
|
951
|
+
Live Now
|
|
726
952
|
</div>
|
|
727
|
-
<
|
|
953
|
+
<h3 className="text-2xl font-bold mb-2">For Providers</h3>
|
|
954
|
+
<p className="text-text-secondary mb-8">Get discovered by AI agents</p>
|
|
728
955
|
<ul className="space-y-4 mb-8">
|
|
729
|
-
<li className="flex items-center gap-3 text-text-
|
|
730
|
-
<Check className="w-5 h-5 flex-shrink-0" />
|
|
731
|
-
|
|
956
|
+
<li className="flex items-center gap-3 text-text-secondary">
|
|
957
|
+
<Check className="w-5 h-5 text-accent flex-shrink-0" />
|
|
958
|
+
Get discovered by AI agents
|
|
732
959
|
</li>
|
|
733
|
-
<li className="flex items-center gap-3 text-text-
|
|
734
|
-
<Check className="w-5 h-5 flex-shrink-0" />
|
|
735
|
-
|
|
960
|
+
<li className="flex items-center gap-3 text-text-secondary">
|
|
961
|
+
<Check className="w-5 h-5 text-accent flex-shrink-0" />
|
|
962
|
+
Become a Direct Call partner
|
|
736
963
|
</li>
|
|
737
|
-
<li className="flex items-center gap-3 text-text-
|
|
738
|
-
<Check className="w-5 h-5 flex-shrink-0" />
|
|
739
|
-
|
|
964
|
+
<li className="flex items-center gap-3 text-text-secondary">
|
|
965
|
+
<Check className="w-5 h-5 text-accent flex-shrink-0" />
|
|
966
|
+
Self-service onboarding
|
|
740
967
|
</li>
|
|
741
|
-
<li className="flex items-center gap-3 text-text-
|
|
742
|
-
<Check className="w-5 h-5 flex-shrink-0" />
|
|
743
|
-
|
|
968
|
+
<li className="flex items-center gap-3 text-text-secondary">
|
|
969
|
+
<Check className="w-5 h-5 text-accent flex-shrink-0" />
|
|
970
|
+
Analytics & usage insights
|
|
744
971
|
</li>
|
|
745
|
-
<li className="flex items-center gap-3 text-text-
|
|
746
|
-
<Check className="w-5 h-5 flex-shrink-0" />
|
|
747
|
-
|
|
972
|
+
<li className="flex items-center gap-3 text-text-secondary">
|
|
973
|
+
<Check className="w-5 h-5 text-accent flex-shrink-0" />
|
|
974
|
+
Zero integration work
|
|
748
975
|
</li>
|
|
749
976
|
</ul>
|
|
750
|
-
<a
|
|
751
|
-
|
|
752
|
-
target="_blank"
|
|
753
|
-
rel="noopener noreferrer"
|
|
754
|
-
className="btn-secondary w-full justify-center hover:bg-surface-elevated transition-colors"
|
|
755
|
-
>
|
|
756
|
-
Join Waitlist
|
|
977
|
+
<a href="/providers/dashboard" className="btn-primary w-full justify-center">
|
|
978
|
+
Add Your API
|
|
757
979
|
</a>
|
|
758
980
|
</div>
|
|
759
981
|
</div>
|
|
760
982
|
</div>
|
|
761
983
|
</section>
|
|
762
984
|
|
|
763
|
-
|
|
764
|
-
|
|
985
|
+
<div className="divider" />
|
|
986
|
+
|
|
987
|
+
{/* FAQ */}
|
|
988
|
+
<section id="faq" className="py-24 px-6">
|
|
765
989
|
<div className="max-w-3xl mx-auto">
|
|
766
|
-
<div className="
|
|
767
|
-
<
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
<h2 className="text-3xl md:text-4xl font-bold mb-4 tracking-tight">
|
|
771
|
-
Ready to go agent-native?
|
|
990
|
+
<div className="text-center mb-16">
|
|
991
|
+
<span className="section-label">FAQ</span>
|
|
992
|
+
<h2 className="text-3xl md:text-4xl font-bold mt-4 tracking-tight">
|
|
993
|
+
Common Questions
|
|
772
994
|
</h2>
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
995
|
+
</div>
|
|
996
|
+
|
|
997
|
+
<div className="space-y-4">
|
|
998
|
+
{[
|
|
999
|
+
{
|
|
1000
|
+
q: "What is APIClaw?",
|
|
1001
|
+
a: `APIClaw is the API layer for AI agents. Your agent queries by capability ("I need image generation"), gets ranked matches with metadata and pricing, and can call APIs directly through us — no keys needed.`
|
|
1002
|
+
},
|
|
1003
|
+
{
|
|
1004
|
+
q: "How does Direct Call work?",
|
|
1005
|
+
a: "Direct Call lets your agent use APIs without managing API keys. APIClaw handles authentication — your agent just calls the API through us. Currently available for 10+ providers including Replicate (1000+ ML models), OpenRouter (100+ LLMs), Firecrawl (web scraping), E2B (code sandbox), and more."
|
|
1006
|
+
},
|
|
1007
|
+
{
|
|
1008
|
+
q: "How are API credentials secured?",
|
|
1009
|
+
a: "All credentials are encrypted with AES-256-GCM before storage. Keys are never logged or exposed in responses. Direct Call requests are proxied server-side — your credentials never touch the agent. We take security seriously."
|
|
1010
|
+
},
|
|
1011
|
+
{
|
|
1012
|
+
q: "What does it cost?",
|
|
1013
|
+
a: `Search ${statsData.apiCount.toLocaleString()}+ APIs free forever. Direct Call is free during beta; pay-per-use pricing coming later. For providers, listing your API is always free.`
|
|
1014
|
+
},
|
|
1015
|
+
{
|
|
1016
|
+
q: "How do I add my API?",
|
|
1017
|
+
a: "Go to the Provider Dashboard, sign up with your email, and follow the self-service onboarding. Your API will be discoverable by AI agents immediately. Want to become a Direct Call partner? Set that up in the dashboard too."
|
|
1018
|
+
},
|
|
1019
|
+
{
|
|
1020
|
+
q: "What's MCP?",
|
|
1021
|
+
a: "MCP (Model Context Protocol) is the open standard for connecting AI agents to external tools. APIClaw is an MCP server — add one line to your config and your agent can discover and call any API in our registry. Works with Claude Desktop, Cursor, and any MCP-compatible client."
|
|
1022
|
+
}
|
|
1023
|
+
].map((faq, i) => (
|
|
1024
|
+
<div
|
|
1025
|
+
key={i}
|
|
1026
|
+
className="rounded-2xl bg-surface-elevated border border-border overflow-hidden"
|
|
792
1027
|
>
|
|
793
|
-
<
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
1028
|
+
<button
|
|
1029
|
+
onClick={() => setOpenFaq(openFaq === i ? null : i)}
|
|
1030
|
+
className="w-full p-6 flex items-center justify-between text-left hover:bg-surface/50 transition-colors"
|
|
1031
|
+
>
|
|
1032
|
+
<h3 className="font-bold text-lg">{faq.q}</h3>
|
|
1033
|
+
<ChevronDown
|
|
1034
|
+
className={`w-5 h-5 text-text-muted transition-transform ${openFaq === i ? 'rotate-180' : ''}`}
|
|
1035
|
+
/>
|
|
1036
|
+
</button>
|
|
1037
|
+
{openFaq === i && (
|
|
1038
|
+
<div className="px-6 pb-6">
|
|
1039
|
+
<p className="text-text-secondary leading-relaxed">{faq.a}</p>
|
|
1040
|
+
</div>
|
|
1041
|
+
)}
|
|
1042
|
+
</div>
|
|
1043
|
+
))}
|
|
797
1044
|
</div>
|
|
798
1045
|
</div>
|
|
799
1046
|
</section>
|
|
@@ -811,7 +1058,7 @@ export default function Home() {
|
|
|
811
1058
|
<span className="font-bold text-xl tracking-tight">APIClaw</span>
|
|
812
1059
|
</div>
|
|
813
1060
|
<p className="text-text-muted mb-6 max-w-sm leading-relaxed">
|
|
814
|
-
The API
|
|
1061
|
+
The API layer for AI agents.
|
|
815
1062
|
Find, evaluate, and integrate APIs in milliseconds.
|
|
816
1063
|
</p>
|
|
817
1064
|
<div className="flex items-center gap-3">
|
|
@@ -842,7 +1089,8 @@ export default function Home() {
|
|
|
842
1089
|
<li><a href="#for-agents" className="hover:text-text-primary transition">For Agents</a></li>
|
|
843
1090
|
<li><a href="#for-providers" className="hover:text-text-primary transition">For Providers</a></li>
|
|
844
1091
|
<li><a href="/providers/dashboard" className="hover:text-text-primary transition">Provider Dashboard</a></li>
|
|
845
|
-
<li><a href="#
|
|
1092
|
+
<li><a href="#get-started" className="hover:text-text-primary transition">Get Started</a></li>
|
|
1093
|
+
<li><a href="#faq" className="hover:text-text-primary transition">FAQ</a></li>
|
|
846
1094
|
<li><a href="/docs" className="hover:text-text-primary transition">Documentation</a></li>
|
|
847
1095
|
</ul>
|
|
848
1096
|
</div>
|
|
@@ -859,7 +1107,7 @@ export default function Home() {
|
|
|
859
1107
|
|
|
860
1108
|
<div className="pt-8 border-t border-border flex flex-col md:flex-row items-center justify-between gap-4">
|
|
861
1109
|
<p className="text-text-muted text-sm">
|
|
862
|
-
© 2026 NordSym.
|
|
1110
|
+
© 2026 NordSym. Get in front of every AI agent. White-glove onboarding available.
|
|
863
1111
|
</p>
|
|
864
1112
|
<div className="flex items-center gap-4">
|
|
865
1113
|
<div className="badge">
|
|
@@ -889,6 +1137,61 @@ export default function Home() {
|
|
|
889
1137
|
<span className="text-text-primary font-medium">Talk to the Clawdbot building this</span>
|
|
890
1138
|
</div>
|
|
891
1139
|
</a>
|
|
1140
|
+
|
|
1141
|
+
{/* Direct Call Providers Modal */}
|
|
1142
|
+
{showProvidersModal && (
|
|
1143
|
+
<div
|
|
1144
|
+
className="fixed inset-0 z-[100] flex items-center justify-center p-4 bg-black/60 backdrop-blur-sm"
|
|
1145
|
+
onClick={() => setShowProvidersModal(false)}
|
|
1146
|
+
>
|
|
1147
|
+
<div
|
|
1148
|
+
className="bg-background border border-border rounded-2xl shadow-2xl max-w-md w-full max-h-[80vh] overflow-hidden"
|
|
1149
|
+
onClick={(e) => e.stopPropagation()}
|
|
1150
|
+
>
|
|
1151
|
+
<div className="p-6 border-b border-border">
|
|
1152
|
+
<div className="flex items-center justify-between">
|
|
1153
|
+
<h3 className="text-xl font-bold flex items-center gap-2">
|
|
1154
|
+
<Zap className="w-5 h-5 text-accent" />
|
|
1155
|
+
Direct Call Providers
|
|
1156
|
+
</h3>
|
|
1157
|
+
<button
|
|
1158
|
+
onClick={() => setShowProvidersModal(false)}
|
|
1159
|
+
className="p-2 hover:bg-surface rounded-lg transition-colors"
|
|
1160
|
+
>
|
|
1161
|
+
<span className="text-xl">×</span>
|
|
1162
|
+
</button>
|
|
1163
|
+
</div>
|
|
1164
|
+
<p className="text-sm text-text-muted mt-1">No API keys needed. Call directly through APIClaw.</p>
|
|
1165
|
+
</div>
|
|
1166
|
+
|
|
1167
|
+
<div className="p-4 max-h-[40vh] overflow-y-auto">
|
|
1168
|
+
<div className="grid grid-cols-2 gap-3">
|
|
1169
|
+
{directCallProviders.map((provider, i) => (
|
|
1170
|
+
<div key={i} className="p-3 rounded-xl bg-surface border border-border">
|
|
1171
|
+
<div className="font-medium text-sm">{provider.name}</div>
|
|
1172
|
+
<div className="text-xs text-text-muted">{provider.desc}</div>
|
|
1173
|
+
</div>
|
|
1174
|
+
))}
|
|
1175
|
+
</div>
|
|
1176
|
+
</div>
|
|
1177
|
+
|
|
1178
|
+
<div className="p-6 border-t border-border bg-surface/50">
|
|
1179
|
+
<p className="text-sm text-text-secondary mb-4 text-center">
|
|
1180
|
+
Want your API here? Get discovered by AI agents worldwide.
|
|
1181
|
+
</p>
|
|
1182
|
+
<a
|
|
1183
|
+
href="https://nordsym.github.io/NordSym-Scheduler/"
|
|
1184
|
+
target="_blank"
|
|
1185
|
+
rel="noopener noreferrer"
|
|
1186
|
+
className="btn-primary w-full justify-center"
|
|
1187
|
+
>
|
|
1188
|
+
<span>Book a Call</span>
|
|
1189
|
+
<ArrowRight className="w-4 h-4" />
|
|
1190
|
+
</a>
|
|
1191
|
+
</div>
|
|
1192
|
+
</div>
|
|
1193
|
+
</div>
|
|
1194
|
+
)}
|
|
892
1195
|
</main>
|
|
893
1196
|
);
|
|
894
1197
|
}
|