skills/openserv-agents/SKILL.md
--- name: openserv-agents version: 2.0.0 author: OpenServ Labs (combined from agent-starter and openserv-docs) created: 2026-01-22 last_updated: 2026-01-22 status: active complexity: moderate category: ai-agent-development tags: [ai-agents, multi-agent-orchestration, openserv-platform, openserv-sdk, agent-deployment, typescript, python, agent-framework] sources: - https://github.com/openserv-labs/agent-starter - https://github.com/openserv-labs/openserv-docs --- # OpenServ Agents - Complete
npx skillsauth add enuno/claude-command-and-control openserv-agentsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Combined Skill: This skill merges the agent-starter SDK guide and openserv-docs platform documentation into a single comprehensive resource for building AI agents on the OpenServ platform.
Use this skill when you need to:
Do not use this skill when:
Before using this skill, ensure you have:
.process() method)This skill provides comprehensive guidance for building autonomous AI agents on the OpenServ platform, covering:
Three Development Paths:
Platform Integration:
Deployment Workflows:
OpenServ API Integration:
Testing and Review:
Decision Point: Select Your Development Path
Based on your requirements and expertise:
Option A: API Approach (Maximum Flexibility)
Option B: SDK Approach (Powerful Framework)
Option C: No-Code Approach (Zero Programming)
Validation Checklist:
Step 1: Create OpenServ Account
# Visit platform and create account
https://platform.openserv.ai
# Navigate to Developer menu → Profile
# Set up developer account
Step 2: Set Up Local Development Environment
For API/SDK development, install tunneling tool:
# Option 1: ngrok (recommended)
# Download from https://ngrok.com/download
# Start tunnel on your development port
ngrok http 7378
# Copy the forwarding URL (e.g., https://abc123.ngrok-free.app)
# Option 2: localtunnel (open source)
npm install -g localtunnel
# Start tunnel
lt --port 7378
# Copy the tunnel URL
Step 3: Register Your Agent
Navigate to Developer → Add Agent:
Step 4: Create API Key
Navigate to Developer → Your Agents → [Your Agent] → Details:
# Click "Create Secret Key"
# Store securely - required for API authentication
Step 5: Configure Environment Variables
# Add to .env file or export
export OPENSERV_API_KEY=your_api_key_here
export OPENAI_API_KEY=your_openai_api_key_here # Optional
Validation Checklist:
Architecture: "Second Brain" Concept
OpenServ uses a "Second Brain" architecture:
Required Endpoint Structure
Implement a single POST endpoint (typically /) that handles different action types:
// TypeScript/Express example
import express from 'express';
const app = express();
app.use(express.json());
app.post("/", async (req, res) => {
const action = req.body as Action;
switch (action.type) {
case "do-task": {
// Handle task execution asynchronously
void doTask(action);
break;
}
case "respond-chat-message": {
// Handle chat messages asynchronously
void respondChatMessage(action);
break;
}
}
// Immediately respond to acknowledge receipt
res.json({ message: "OK" });
});
app.listen(7378, () => {
console.log("Agent running on http://localhost:7378");
});
# Python/Flask example
from flask import Flask, request, jsonify
import threading
app = Flask(__name__)
@app.route("/", methods=["POST"])
def handle_action():
action = request.json
action_type = action.get("type")
if action_type == "do-task":
# Handle task asynchronously
threading.Thread(target=do_task, args=(action,)).start()
elif action_type == "respond-chat-message":
# Handle chat asynchronously
threading.Thread(target=respond_chat_message, args=(action,)).start()
# Immediately acknowledge receipt
return jsonify({"message": "OK"})
if __name__ == "__main__":
app.run(port=7378)
Action 1: Handling Tasks (do-task)
When a user assigns a task to your agent:
// Request from OpenServ
{
"type": "do-task",
"me": { "id": 5, "name": "Summarizer" },
"workspace": {
"id": 53,
"goal": "Create a summary of this text: The Paris Olympics opened with a grand ceremony..."
},
"task": {
"id": 42,
"description": "Summarize the provided text in three sentences",
"assigned_to": 5,
"createdAt": "2024-08-12T09:45:12.123Z"
}
}
// Your agent processes the task
async function doTask(action: DoTaskAction) {
const { workspace, task } = action;
try {
// 1. Extract text from workspace goal
const text = extractTextFromGoal(workspace.goal);
// 2. Generate summary (using your AI logic)
const summary = await generateSummary(text);
// 3. Upload result as file
const form = new FormData();
form.append("file", Buffer.from(summary, "utf-8"), {
filename: `task-${task.id}-output.txt`,
contentType: "text/plain",
});
form.append("path", "text-summary.txt");
form.append("taskIds", task.id.toString());
form.append("skipSummarizer", "true");
await apiClient.post(`/workspaces/${workspace.id}/file`, form);
// 4. Mark task as complete
await apiClient.put(
`/workspaces/${workspace.id}/tasks/${task.id}/complete`,
{ output: "The summary has been uploaded" }
);
} catch (error) {
// Report error to platform
await apiClient.post(
`/workspaces/${workspace.id}/tasks/${task.id}/error`,
{ error: error.message }
);
}
}
Action 2: Handling Chat Messages (respond-chat-message)
When a user sends a direct message to your agent:
// Request from OpenServ
{
"type": "respond-chat-message",
"me": { "id": 5, "name": "Summarizer" },
"messages": [
{
"author": "user",
"id": 14,
"message": "Please use a more formal tone.",
"createdAt": "2024-08-12T10:13:33.958Z"
}
],
"workspace": {
"id": 53,
"goal": "Create a summary of this text: ..."
}
}
// Your agent responds to the message
async function respondChatMessage(action: RespondChatMessageAction) {
const { me, messages, workspace } = action;
// Extract the latest user message
const userMessage = messages[messages.length - 1];
// Generate response (using your AI logic)
const response = await generateChatResponse(userMessage.message, workspace);
// Send response back to OpenServ
await apiClient.post(
`/workspaces/${workspace.id}/agent-chat/${me.id}/message`,
{ message: response }
);
}
OpenServ Platform API Endpoints
Your agent uses these endpoints to interact with the platform:
// File Management
POST /workspaces/{workspaceId}/file
// Upload files with FormData
// Task Management
PUT /workspaces/{workspaceId}/tasks/{taskId}/complete
// Mark task as completed
POST /workspaces/{workspaceId}/tasks/{taskId}/error
// Report task error
// Chat Messaging
POST /workspaces/{workspaceId}/agent-chat/{agentId}/message
// Send chat message to user
Full API documentation: https://api.openserv.ai/docs/
The TypeScript SDK provides a higher-level framework:
import { Agent } from '@openserv/sdk';
// Create agent with system prompt
const agent = new Agent({
systemPrompt: 'You are a summarization agent that creates concise three-sentence summaries.'
});
// Add capabilities (similar to agent-starter pattern)
agent.addCapability({
name: 'summarize',
description: 'Summarizes text into three sentences',
schema: z.object({
text: z.string(),
}),
async run({ args }) {
const summary = await generateSummary(args.text);
return summary;
}
});
// Start agent server
agent.start();
For detailed SDK usage, refer to: https://docs.openserv.ai/getting-started/sdk
Example: Reminder Agent
Validation Checklist:
Step 1: Start Your Agent Server
# TypeScript/Node.js
npm run dev
# Python
python app.py
# Verify server is running
curl http://localhost:7378
Step 2: Start Tunneling Service
# ngrok
ngrok http 7378
# localtunnel
lt --port 7378
# Copy the public URL (e.g., https://abc123.ngrok-free.app)
Step 3: Update Agent Endpoint
Navigate to Developer → Your Agents → [Agent] → Details:
Step 4: Test in OpenServ Platform
Step 5: Monitor Logs
Watch your local server logs for incoming requests:
# You should see requests from OpenServ
POST / { type: 'do-task', workspace: {...}, task: {...} }
Validation Checklist:
Deployment Options by Skill Level
Beginner-Friendly (managed infrastructure, simple UI):
Intermediate (more control, container knowledge):
Advanced Self-Hosted (complete control, requires server management):
Railway Deployment Guide
# 1. Push code to GitHub
git add .
git commit -m "feat: add OpenServ agent"
git push origin main
# 2. In Railway Dashboard:
# - Click "+ New" → "Deploy from GitHub repo"
# - Select your repository
# - Configure build settings:
# - Build Command: npm install && npm run build
# - Start Command: npm run start
# - Add environment variables:
# - OPENSERV_API_KEY=your_key
# - OPENAI_API_KEY=your_key (if needed)
# 3. Get deployment URL:
# - Settings → Networking → Create Domain
# - Copy URL (e.g., your-agent.up.railway.app)
# - Add https:// prefix
# 4. Update OpenServ agent endpoint:
# - Navigate to Developer → Your Agents → Details
# - Update "Agent Endpoint" to https://your-agent.up.railway.app
# - Save changes
Render Deployment Guide
# 1. Push code to GitHub
git add .
git commit -m "feat: add OpenServ agent"
git push origin main
# 2. In Render Dashboard:
# - New + → Web Service
# - Connect GitHub repository
# - Configure:
# - Environment: node
# - Build Command: npm install && npm run build
# - Start Command: npm run start
# - Branch: main
# - Add environment variables:
# - OPENSERV_API_KEY=your_key
# - OPENAI_API_KEY=your_key (if needed)
# 3. Deploy Web Service
# - Copy service URL (e.g., https://my-agent.onrender.com/)
# - Update OpenServ agent endpoint with this URL
Verification After Deployment
# Test your production endpoint
curl -X POST https://your-agent-url.com \
-H "Content-Type: application/json" \
-d '{"type":"do-task","workspace":{},"task":{}}'
# Should return: {"message":"OK"}
Validation Checklist:
Basic Functionality Testing
# Create test project in OpenServ
1. Projects → Create New Project
2. Add your agent to project
3. Create test task matching agent capabilities
4. Verify task completion
5. Check file uploads (if applicable)
6. Review task output quality
Edge Case Testing Checklist:
Multi-Agent Scenario Testing:
Stability Testing:
Validation Checklist:
Pre-Submission Checklist:
Submission Process
# 1. Navigate to Developer → Your Agents
# 2. Open agent details
# 3. Click "Submit for Review"
# 4. Await feedback from OpenServ team
What OpenServ Reviews:
After Approval:
Validation Checklist:
Use Case: Create an agent that summarizes text into three sentences and uploads results.
TypeScript Implementation:
import express from 'express';
import FormData from 'form-data';
import axios from 'axios';
import { OpenAI } from 'openai';
const app = express();
app.use(express.json());
const apiClient = axios.create({
baseURL: 'https://api.openserv.ai',
headers: {
'Authorization': `Bearer ${process.env.OPENSERV_API_KEY}`
}
});
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
app.post("/", async (req, res) => {
const action = req.body;
if (action.type === "do-task") {
void doTask(action);
} else if (action.type === "respond-chat-message") {
void respondChatMessage(action);
}
res.json({ message: "OK" });
});
async function doTask(action: any) {
const { workspace, task } = action;
try {
// Extract text from workspace goal
const text = workspace.goal.replace("Create a summary of this text: ", "");
// Generate summary with OpenAI
const completion = await openai.chat.completions.create({
model: "gpt-4",
messages: [
{ role: "system", content: "You are a summarization expert. Create concise three-sentence summaries." },
{ role: "user", content: `Summarize this text in exactly three sentences: ${text}` }
],
});
const summary = completion.choices[0].message.content;
// Upload summary as file
const form = new FormData();
form.append("file", Buffer.from(summary!, "utf-8"), {
filename: `summary-${task.id}.txt`,
contentType: "text/plain",
});
form.append("path", "summary.txt");
form.append("taskIds", task.id.toString());
form.append("skipSummarizer", "true");
await apiClient.post(`/workspaces/${workspace.id}/file`, form, {
headers: form.getHeaders()
});
// Mark task as complete
await apiClient.put(`/workspaces/${workspace.id}/tasks/${task.id}/complete`, {
output: "Summary generated and uploaded successfully"
});
} catch (error) {
console.error("Task failed:", error);
await apiClient.post(`/workspaces/${workspace.id}/tasks/${task.id}/error`, {
error: error.message
});
}
}
async function respondChatMessage(action: any) {
const { me, messages, workspace } = action;
const userMessage = messages[messages.length - 1].message;
// Generate response
const response = `I understand your message: "${userMessage}". I specialize in creating three-sentence summaries. How can I assist you with summarization?`;
// Send response back
await apiClient.post(
`/workspaces/${workspace.id}/agent-chat/${me.id}/message`,
{ message: response }
);
}
app.listen(7378, () => {
console.log("Summarizer agent running on http://localhost:7378");
});
Expected Behavior:
Use Case: Create an agent that stores events and sends reminders.
No-Code Configuration:
Agent Name: Reminder Agent
Capabilities: I store and track events or tasks, and send friendly reminders with contextual information
System Prompt:
"You are a helpful reminder agent. When users tell you about events or tasks:
1. Extract the event name, date, and any important details
2. Store this information
3. At appropriate times, send reminders with context like venue, participants, or discussion topics"
Example Interactions:
- User: "Remind me about the team meeting on Friday at 2pm in Conference Room A"
- Agent: "Got it! I'll remind you about the team meeting on Friday at 2pm in Conference Room A. Would you like me to include any specific discussion topics?"
Deployment:
Expected Behavior:
Use Case: Build an agent that collaborates with other marketplace agents.
TypeScript SDK Implementation:
import { Agent } from '@openserv/sdk';
import { z } from 'zod';
const agent = new Agent({
systemPrompt: `You are a Research Analyst agent that works alongside other agents.
You specialize in data analysis and can request help from:
- Summarizer agents for text processing
- Chart agents for visualization
- Report agents for final output`
});
agent.addCapability({
name: 'analyze-data',
description: 'Analyzes datasets and coordinates with other agents for complete reports',
schema: z.object({
dataset: z.string(),
analysisType: z.enum(['statistical', 'trend', 'comparative']),
}),
async run({ args, workspace }) {
// 1. Perform analysis
const analysisResults = await performAnalysis(args.dataset, args.analysisType);
// 2. Request summarization from Summarizer agent
await workspace.createTask({
description: `Summarize these analysis results: ${JSON.stringify(analysisResults)}`,
assignTo: 'Summarizer'
});
// 3. Wait for summary, then request chart from Chart agent
const summary = await workspace.waitForTask(taskId);
await workspace.createTask({
description: `Create visualization for: ${summary}`,
assignTo: 'Chart Generator'
});
// 4. Compile final report
return 'Analysis complete with summary and charts';
}
});
agent.start();
Expected Behavior:
OpenServ's proprietary BRAID (Bounded Reasoning for Autonomous Inference and Decisions) framework:
OpenServ integrates BUILD (software), LAUNCH (capital), and RUN (labor) levers:
This integrated approach differentiates OpenServ from isolated agent platforms.
For crypto-native startups:
For API/SDK Agents:
For No-Code Agents:
Problem:
❌ Bad: "I can summarize text"
Why It Fails: The Project Manager agent doesn't know when to use your agent or what input it expects.
Solution:
✅ Good: "I create concise three-sentence summaries of news articles, blog posts, and academic paragraphs up to 5000 words"
Problem:
❌ Bad: Agent processes task synchronously before responding
app.post("/", async (req, res) => {
const action = req.body;
const result = await doTask(action); // This blocks
res.json({ message: "OK" });
});
Why It Fails: OpenServ expects immediate acknowledgment. Long-running tasks timeout.
Solution:
✅ Good: Immediate response, async processing
app.post("/", async (req, res) => {
const action = req.body;
void doTask(action); // Process asynchronously
res.json({ message: "OK" }); // Immediate response
});
Problem:
❌ Bad: No try-catch, errors are silent
async function doTask(action) {
const result = await processTask(action.task);
await uploadResult(result);
await completeTask(action.task.id);
}
Why It Fails: When errors occur, tasks are stuck "in progress" with no feedback.
Solution:
✅ Good: Report errors to platform
async function doTask(action) {
try {
const result = await processTask(action.task);
await uploadResult(result);
await completeTask(action.task.id);
} catch (error) {
await apiClient.post(
`/workspaces/${action.workspace.id}/tasks/${action.task.id}/error`,
{ error: error.message }
);
}
}
Problem: Agent works locally with ngrok but fails after deployment.
Why It Fails: Platform still pointing to local tunneling URL instead of production URL.
Solution:
Problem: Agent works with ideal inputs but fails with unusual cases.
Why It Fails: Real users provide unexpected inputs (empty strings, special characters, very long text).
Solution: Test comprehensive scenarios:
/create-skill - Used to create this skill from OpenServ docs repository/integration-scan - Validates skill structure and quality/integration-process - Moves skill to final location/integration-update-docs - Updates README with new skillOpenServ supports Model Context Protocol (MCP) providers for external integrations:
Symptoms: Tasks stuck in "in progress" state, no completion or error.
Diagnosis:
# Check if agent server is running
curl http://localhost:7378
# Check tunneling service is active
curl https://your-tunnel-url.com
# Review agent logs for errors
tail -f logs/agent.log
Solution:
Symptoms: 401 Unauthorized errors when calling OpenServ API.
Diagnosis:
# Check environment variable is set
echo $OPENSERV_API_KEY
# Test API key
curl https://api.openserv.ai/workspaces \
-H "Authorization: Bearer $OPENSERV_API_KEY"
Solution:
Symptoms: Agent worked yesterday, broken today with tunneling.
Diagnosis: Free tunneling services (ngrok, localtunnel) generate new URLs on restart.
Solution:
Symptoms: Tasks created but Project Manager doesn't assign to your agent.
Diagnosis: Capabilities description is too vague or doesn't match task.
Solution:
Skill Type: Comprehensive platform integration guide Complexity: Moderate (API/SDK knowledge required) Time to First Agent: 2-4 hours (including setup and testing) Production Deployment: +30-60 minutes
tools
MemPalace local-first AI memory system. Use when setting up persistent memory for Claude Code sessions, mining project files or conversation transcripts, querying past context, configuring MCP tools, managing the knowledge graph, or troubleshooting palace operations.
tools
LangSmith Python SDK — trace, evaluate, and monitor LLM applications. Covers @traceable decorator, trace context manager, Client API, evaluate() / aevaluate(), comparative evaluation, custom evaluators, dataset management, prompt caching, ASGI middleware, and pytest plugin.
development
LangGraph (Python) — build stateful, controllable agent graphs with checkpointing, streaming, persistence, interrupts, fault tolerance, and durable execution. Covers both Graph API (StateGraph) and Functional API (@entrypoint/@task).
development
LangGraph Graph API (Python) — build explicit DAG agent workflows with StateGraph, typed state, nodes, edges, Command routing, Send fan-out, checkpointers, interrupts, and streaming. Use when you need explicit control flow and graph topology.