Build and deploy your first SperaxOS plugin in under 10 minutes.
- Bun or Node.js 18+
- A code editor (VS Code recommended)
- Basic TypeScript knowledge
| I want to... | Use this type | Template |
|---|---|---|
| Return data for AI to explain | Default | templates/default |
| Show formatted text/tables | Markdown | templates/markdown |
| Build interactive UI | Standalone | templates/standalone |
| Use existing OpenAPI spec | OpenAPI | templates/openapi |
# Clone the plugins repo
git clone https://github.com/nirholas/plugin.delivery.git
cd plugins
# Copy a template
cp -r templates/default my-plugin
cd my-plugin
# Install dependencies
bun installmkdir my-plugin && cd my-plugin
bun init -y
bun add @sperax/plugin-sdkEvery plugin needs a manifest.json:
{
"$schema": "https://plugin.delivery/schema.json",
"identifier": "my-plugin",
"api": [
{
"name": "myFunction",
"description": "What this function does - be descriptive for the AI",
"url": "https://my-plugin.vercel.app/api/endpoint",
"parameters": {
"type": "object",
"properties": {
"param1": {
"type": "string",
"description": "Description of param1"
}
},
"required": ["param1"]
}
}
],
"meta": {
"title": "My Plugin",
"description": "A brief description shown in the plugin store",
"avatar": "🔌",
"tags": ["utility"]
}
}| Field | Purpose |
|---|---|
identifier |
Unique plugin ID (lowercase, hyphens allowed) |
api[].name |
Function name the AI will call |
api[].description |
Critical - AI uses this to decide when to call |
api[].url |
Your API endpoint URL |
api[].parameters |
JSON Schema for function arguments |
meta.title |
Display name in plugin store |
meta.description |
Short description (under 200 chars) |
Create api/endpoint.ts:
export const config = {
runtime: 'edge',
};
export default async function handler(req: Request) {
// Parse the request body
const body = await req.json();
const { param1 } = body;
// Your logic here
const result = await doSomething(param1);
// Return JSON response
return Response.json({
success: true,
data: result,
});
}
async function doSomething(input: string) {
// Your implementation
return `Processed: ${input}`;
}For Default plugins, return JSON that the AI will summarize:
{
"price": 3450.00,
"change24h": "+2.5%",
"volume": "1.2B"
}For Markdown plugins, return formatted text:
{
"markdown": "## Results\n\n| Token | Price |\n|-------|-------|\n| ETH | $3,450 |"
}bun dev
# Server runs at http://localhost:3400curl -X POST http://localhost:3400/api/endpoint \
-H "Content-Type: application/json" \
-d '{"param1": "test"}'- Open SperaxOS
- Go to Plugin Settings → Add Custom Plugin
- Enter:
http://localhost:3400/manifest.json - Enable the plugin
- Chat: "Use my-plugin to..."
# Install Vercel CLI
npm i -g vercel
# Deploy
vercel --prodAfter deployment, update manifest.json with production URLs:
{
"api": [
{
"url": "https://my-plugin.vercel.app/api/endpoint"
}
]
}- Go to github.com/nirholas/plugins/issues
- Click "New Issue" → "Plugin Submission"
- Fill in your plugin details
-
Add your plugin to
src/my-plugin.json:
{
"identifier": "my-plugin",
"author": "your-github-username",
"createdAt": "2025-01-01",
"manifest": "https://my-plugin.vercel.app/manifest.json",
"meta": {
"avatar": "🔌",
"title": "My Plugin",
"description": "What it does",
"tags": ["utility"],
"category": "tools"
}
}⚠️ REQUIRED: Create locale filelocales/my-plugin.en-US.json:
{
"meta": {
"title": "My Plugin",
"description": "What it does",
"tags": ["utility"]
}
}-
Run
bun run formatto generate all translations (requiresOPENAI_API_KEY) -
Submit PR with both
src/my-plugin.jsonandlocales/my-plugin.*.jsonfiles
// api/price.ts
export default async function handler(req: Request) {
const { coin } = await req.json();
const res = await fetch(
`https://api.coingecko.com/api/v3/simple/price?ids=${coin}&vs_currencies=usd&include_24hr_change=true`
);
const data = await res.json();
return Response.json({
coin,
price: data[coin]?.usd,
change24h: data[coin]?.usd_24h_change?.toFixed(2) + '%',
});
}// api/weather.ts
export default async function handler(req: Request) {
const { city } = await req.json();
const weather = await getWeather(city);
return Response.json({
markdown: `
## Weather in ${city}
🌡️ **Temperature:** ${weather.temp}°C
💨 **Wind:** ${weather.wind} km/h
💧 **Humidity:** ${weather.humidity}%
`.trim()
});
}- Check manifest URL is accessible (try opening in browser)
- Verify JSON is valid (use jsonlint.com)
- Ensure
identifieris unique
- Improve
api[].description- be specific about when to use - Check parameter descriptions
- Test endpoint directly with curl
Add to your API:
export default async function handler(req: Request) {
if (req.method === 'OPTIONS') {
return new Response(null, {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
},
});
}
// ... rest of handler
return Response.json(data, {
headers: {
'Access-Control-Allow-Origin': '*',
},
});
}- 📖 Full Plugin Development Guide
- 🎨 Plugin Types Deep Dive
- 📋 Manifest Reference
- 💬 Communication Guide (for Standalone plugins)
- GitHub Issues: github.com/nirholas/plugins/issues
- Twitter/X: @nichxbt
In addition to the templates provided in this repository, you can learn about plugin development based on these reference implementations:
| Template | Type | Description | Location |
|---|---|---|---|
| Default | default |
Standard plugin with backend API | templates/default/ |
| Markdown | markdown |
Returns formatted Markdown | templates/markdown/ |
| Standalone | standalone |
Interactive React application | templates/standalone/ |
| OpenAPI | default |
Uses OpenAPI specification | templates/openapi/ |
| Basic | default |
Minimal starter template | templates/basic/ |
| Settings | default |
Plugin with user settings | templates/settings/ |
| Plugin | Type | Description | Location |
|---|---|---|---|
| CoinGecko | OpenAPI | Cryptocurrency price data | public/openai/coingecko/ |
| DeFiLlama | OpenAPI | DeFi protocol analytics | public/defillama/ |
The plugin system supports any frontend framework. Here are examples using different approaches:
Vercel Edge Runtime (Recommended):
- Fast, global edge network
- TypeScript support
- See:
templates/openapi/
Vercel Node.js Runtime:
- Full Node.js APIs available
- Useful for complex server-side logic
- See:
api/folder examples
Next.js Pages Router:
- Full React framework
- SSR and API routes
- See:
templates/standalone/
Pure Frontend (Standalone):
- No backend required
- Client-side only
- See:
templates/standalone/
We welcome contributions of plugin templates for more frameworks and languages:
- Python/Flask - FastAPI or Flask server template
- Go - Gin or Echo server template
- Rust - Actix or Axum server template
- Vue.js - Vue-based standalone plugin
- Svelte - Svelte-based standalone plugin
To contribute:
- Create your template in
templates/your-framework/ - Include a README.md with setup instructions
- Submit a pull request
After completing this quick start, explore these guides for more advanced topics:
- 📖 Full Plugin Development Guide - Comprehensive development documentation
- 🎨 Plugin Types Deep Dive - When to use each plugin type
- 📋 Manifest Reference - Complete manifest field documentation
- 💬 Communication Guide - Frontend/backend communication patterns
- 🔌 SDK API Reference - Full SDK documentation
- 📤 Submit Your Plugin - Get listed in the marketplace