diff --git a/apps/web/src/app/docs/api/page.tsx b/apps/web/src/app/docs/api/page.tsx new file mode 100644 index 0000000..7e56d95 --- /dev/null +++ b/apps/web/src/app/docs/api/page.tsx @@ -0,0 +1,969 @@ +'use client'; + +import { Badge } from '@tpmjs/ui/Badge/Badge'; +import { Button } from '@tpmjs/ui/Button/Button'; +import { CodeBlock } from '@tpmjs/ui/CodeBlock/CodeBlock'; +import Link from 'next/link'; +import { useEffect, useState } from 'react'; +import { AppHeader } from '~/components/AppHeader'; + +const NAV_SECTIONS = [ + { + title: 'Getting Started', + items: [ + { id: 'overview', label: 'Overview' }, + { id: 'quick-start', label: 'Quick Start' }, + { id: 'authentication', label: 'Authentication' }, + ], + }, + { + title: 'Public Endpoints', + items: [ + { id: 'tools', label: 'Tools' }, + { id: 'search', label: 'Search' }, + { id: 'collections', label: 'Collections' }, + { id: 'agents', label: 'Agents' }, + { id: 'stats', label: 'Stats' }, + ], + }, + { + title: 'MCP Protocol', + items: [ + { id: 'mcp-overview', label: 'Overview' }, + { id: 'mcp-initialize', label: 'Initialize' }, + { id: 'mcp-tools-list', label: 'Tools List' }, + { id: 'mcp-tools-call', label: 'Tools Call' }, + ], + }, + { + title: 'Execution', + items: [ + { id: 'execute-tool', label: 'Execute Tool' }, + { id: 'streaming', label: 'Streaming' }, + ], + }, + { + title: 'Response Format', + items: [ + { id: 'success', label: 'Success Response' }, + { id: 'errors', label: 'Error Handling' }, + { id: 'pagination', label: 'Pagination' }, + ], + }, +]; + +function SidebarNav({ + activeSection, + onSectionClick, +}: { + activeSection: string; + onSectionClick: (id: string) => void; +}) { + return ( + + ); +} + +function DocSection({ + id, + title, + children, +}: { + id: string; + title: string; + children: React.ReactNode; +}) { + return ( +
+

+ {title} +

+ {children} +
+ ); +} + +function EndpointCard({ + method, + path, + description, + children, +}: { + method: 'GET' | 'POST' | 'PUT' | 'DELETE'; + path: string; + description: string; + children?: React.ReactNode; +}) { + const methodColors = { + GET: 'bg-green-500/10 text-green-500 border-green-500/30', + POST: 'bg-blue-500/10 text-blue-500 border-blue-500/30', + PUT: 'bg-yellow-500/10 text-yellow-500 border-yellow-500/30', + DELETE: 'bg-red-500/10 text-red-500 border-red-500/30', + }; + + return ( +
+
+
+ + {method} + + {path} +
+

{description}

+
+ {children &&
{children}
} +
+ ); +} + +function ParamTable({ + params, +}: { + params: { name: string; type: string; required: boolean; description: string }[]; +}) { + return ( +
+ + + + + + + + + + + {params.map((param, i) => ( + + + + + + + ))} + +
ParameterTypeRequiredDescription
{param.name}{param.type} + {param.required ? ( + + Yes + + ) : ( + No + )} + {param.description}
+
+ ); +} + +export default function APIDocsPage(): React.ReactElement { + const [activeSection, setActiveSection] = useState('overview'); + const [mobileNavOpen, setMobileNavOpen] = useState(false); + + useEffect(() => { + const observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + setActiveSection(entry.target.id); + } + }); + }, + { rootMargin: '-100px 0px -66%' } + ); + + NAV_SECTIONS.forEach((section) => { + section.items.forEach((item) => { + const element = document.getElementById(item.id); + if (element) observer.observe(element); + }); + }); + + return () => observer.disconnect(); + }, []); + + const scrollToSection = (id: string) => { + const element = document.getElementById(id); + if (element) { + element.scrollIntoView({ behavior: 'smooth' }); + setMobileNavOpen(false); + } + }; + + return ( +
+ + +
+ {/* Mobile Navigation Toggle */} +
+ + {mobileNavOpen && ( +
+ +
+ )} +
+ + {/* Desktop Sidebar */} + + + {/* Main Content */} +
+
+ {/* Hero */} +
+
+ API + v1.0 +
+

+ TPMJS API Reference +

+

+ REST API and MCP protocol for accessing tools, collections, and agents. +

+
+

+ Base URL:{' '} + https://tpmjs.com/api +

+
+
+ + {/* ==================== GETTING STARTED ==================== */} + +

+ The TPMJS API provides programmatic access to the tool registry, collections, and + agents. There are two ways to interact with the API: +

+
+
+

REST API

+

+ Standard REST endpoints for listing tools, searching, and executing. No + authentication required for public endpoints. +

+
+
+

MCP Protocol

+

+ JSON-RPC 2.0 over HTTP for AI clients like Claude Desktop, Cursor, and others + that support Model Context Protocol. +

+
+
+
+ + +

+ Try these examples to get started immediately. All public endpoints work without + authentication. +

+ +
+
+

1. List Tools

+ +
+ +
+

2. Search Tools

+ +
+ +
+

+ 3. Get Tool Details +

+ +
+ +
+

+ 4. MCP Tools List (Collection) +

+ +
+
+
+ + +

+ Most public endpoints don't require authentication. Private endpoints (creating + collections, managing agents) require a session cookie from signing in. +

+ +
+
+

Public (No Auth)

+
    +
  • GET /api/tools - List and search tools
  • +
  • GET /api/public/collections - List public collections
  • +
  • GET /api/public/agents - List public agents
  • +
  • POST /api/mcp/[user]/[slug]/http - MCP protocol for public collections
  • +
  • GET /api/stats - Platform statistics
  • +
+
+ +
+

Authenticated

+
    +
  • POST /api/collections - Create collection
  • +
  • POST /api/agents - Create agent
  • +
  • PUT /api/collections/[id] - Update collection
  • +
  • DELETE /api/agents/[id] - Delete agent
  • +
+
+
+
+ + {/* ==================== PUBLIC ENDPOINTS ==================== */} + + + +
+ +
+
+ + + +
+

Response

+ +
+
+
+ + + + +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Response

+ +
+
+
+ + {/* ==================== MCP PROTOCOL ==================== */} + +

+ TPMJS implements the Model Context Protocol (MCP) for AI clients. Each public + collection exposes an MCP endpoint that can be connected to Claude Desktop, Cursor, + or any MCP-compatible client. +

+ +
+

Endpoint Format

+ + POST https://tpmjs.com/api/mcp/[username]/[collection-slug]/http + +
+ +
+
+

Request Headers

+ + Content-Type: application/json + +
+
+

Protocol

+

+ JSON-RPC 2.0 with MCP methods: initialize,{' '} + tools/list,{' '} + tools/call +

+
+
+
+ + + +

Request

+ +

Response

+ +
+
+ + + +

Request

+ +

Response

+ +
+
+ + + +

Request

+ +

Response

+ +
+ +
+

Full cURL Example

+ +
+
+ + {/* ==================== EXECUTION ==================== */} + + + +
+ +
+
+
+ + +

+ The execute endpoint returns Server-Sent Events (SSE) for real-time streaming. +

+ +
+
+ event: chunk +

+ Streaming text from the AI agent +

+
+
+ event: tokens +

Token usage updates

+
+
+ event: complete +

+ Final result with output and timing +

+
+
+ event: error +

Error if execution fails

+
+
+ +

JavaScript Example

+ +
+ + {/* ==================== RESPONSE FORMAT ==================== */} + +

+ All API endpoints return a consistent JSON response format. +

+ +
+ + +

+ Errors include a code and message for debugging. +

+ +
+

HTTP Status Codes

+
+
+ 200 + Success +
+
+ 400 + + Bad request / validation error + +
+
+ 401 + Authentication required +
+
+ 404 + Resource not found +
+
+ 429 + Rate limit exceeded +
+
+ 500 + Internal server error +
+
+
+
+ + +

+ List endpoints support limit/offset pagination. +

+ +
+ +
+
+ + {/* CTA */} +
+

Need More Help?

+

+ Check out the full documentation or try the interactive playground. +

+
+ + + + + + + + + +
+
+
+
+
+
+ ); +}