Registering Services
Services group your functions and connect them to the Daemo Engine. This page shows you how to set up and run your service.
The DaemoBuilder
Use DaemoBuilder to configure and create your Daemo instance:
import { DaemoBuilder } from 'daemo-engine';
const daemo = new DaemoBuilder()
.withApiKey(process.env.DAEMO_AGENT_API_KEY!)
.withServiceName("MyService")
.build();
Required Configuration
| Method | Description |
|---|---|
.withApiKey(key) | Your DAEMO_AGENT_API_KEY from the dashboard |
.withServiceName(name) | A unique name for this service |
.build() | Creates the Daemo instance |
Optional Configuration
| Method | Description |
|---|---|
.withSystemPrompt(prompt) | Instructions for the AI on how to use this service |
Registering Functions
After building, register your function classes:
import { CalculatorFunctions } from './services/calculator';
import { CRMFunctions } from './services/crm';
// Register one class
await daemo.registerService(CalculatorFunctions);
// Or register an instance (if you have constructor dependencies)
const db = new Database(connectionString);
const crmFuncs = new CRMFunctions(db);
await daemo.registerService(crmFuncs);
Starting the Service
Once registered, start the service:
await daemo.start();
This:
- Connects to the Daemo Engine via secure tunnel
- Sends your function metadata (names, descriptions, types)
- Listens for incoming function calls
- Keeps the connection alive
Complete Example
Here's a full src/index.ts:
import 'dotenv/config';
import "reflect-metadata";
import { DaemoBuilder } from 'daemo-engine';
import { CalculatorFunctions } from './services/calculator';
async function main() {
// 1. Build the Daemo instance
const daemo = new DaemoBuilder()
.withApiKey(process.env.DAEMO_AGENT_API_KEY!)
.withServiceName("CalculatorService")
.build();
// 2. Register your functions
await daemo.registerService(CalculatorFunctions);
// 3. Start the service
console.log("🚀 Starting Daemo service...");
await daemo.start();
console.log("✅ Service is online!");
}
main().catch(console.error);
Alternative: DaemoHostedConnection
For more control over the connection, use DaemoHostedConnection directly:
import 'dotenv/config';
import "reflect-metadata";
import { DaemoBuilder, DaemoHostedConnection } from 'daemo-engine';
import { MyApiService } from './myApiService';
async function main() {
const myApiService = new MyApiService();
// Build the session data
const sessionData = new DaemoBuilder()
.withServiceName("api_service")
.registerService(myApiService)
.build();
// Connect to the Daemo Gateway
const connection = new DaemoHostedConnection(
{
daemoGatewayUrl: process.env.DAEMO_GATEWAY_URL, // Optional: custom gateway
agentApiKey: process.env.DAEMO_AGENT_API_KEY,
},
sessionData,
);
await connection.start();
console.log("🚀 Daemo service connected!");
}
main().catch(console.error);
This pattern is useful when you need to:
- Specify a custom gateway URL
- Have more control over connection lifecycle
- Separate configuration from registration
Adding a System Prompt
The system prompt guides the AI on how to use your service. It appears in the dashboard and influences how the AI responds:
const daemo = new DaemoBuilder()
.withApiKey(process.env.DAEMO_AGENT_API_KEY!)
.withServiceName("CRMService")
.withSystemPrompt(`
You are a helpful CRM assistant with access to a customer relationship management system.
You can help users:
- Manage contacts (create, read, update, delete)
- Manage deals (create, read, update, delete, change stages)
- Manage notes (create, read, search with semantic similarity)
Important guidelines:
- When creating contacts, deals, or notes, ensure all required fields are provided
- Email addresses must be unique for contacts
- Deal stages follow this pipeline: Lead Identified → Meeting Scheduled → Demo Completed → Proposal Sent → Follow-Up → Contract Sent → Closed Won/Lost
- Always validate IDs before operations
- Provide clear error messages if operations fail
`)
.build();
System prompts appear in the dashboard. When you view your service in app.daemo.ai, you'll see this prompt displayed. It helps you and your team understand what each service does.
📦 Real-World Example: The SF 311 Agent has an excellent system prompt (~80 lines) that teaches the LLM query strategies, performance rules, and schema details. See daemoService.ts in the repo for a production-quality prompt template.
Multiple Services
You can register multiple services to the same agent:
// Option 1: Multiple registrations to one instance
const daemo = new DaemoBuilder()
.withApiKey(process.env.DAEMO_AGENT_API_KEY!)
.withServiceName("MultiService")
.build();
await daemo.registerService(CalculatorFunctions);
await daemo.registerService(CRMFunctions);
await daemo.registerService(NotificationFunctions);
await daemo.start();
// Option 2: Run separate services (different processes)
// service-a/index.ts
const daemoA = new DaemoBuilder()
.withApiKey(process.env.DAEMO_AGENT_API_KEY!)
.withServiceName("CalculatorService")
.build();
await daemoA.registerService(CalculatorFunctions);
await daemoA.start();
// service-b/index.ts
const daemoB = new DaemoBuilder()
.withApiKey(process.env.DAEMO_AGENT_API_KEY!)
.withServiceName("CRMService")
.build();
await daemoB.registerService(CRMFunctions);
await daemoB.start();
All services connected to the same agent will appear in the dashboard and be available to the AI.
Running Your Service
Development
# With ts-node
npx ts-node src/index.ts
# Or add to package.json scripts
# "scripts": { "dev": "ts-node src/index.ts" }
npm run dev
Production
Compile and run:
# Compile
npx tsc
# Run
node dist/index.js
Or use a process manager:
# With PM2
pm2 start dist/index.js --name "my-daemo-service"
# Keep running after terminal closes
pm2 save
Keeping the Service Running
Your service needs to stay running for the AI to call your functions. Options:
| Environment | Solution |
|---|---|
| Local dev | Keep terminal open, use nodemon for auto-restart |
| Server | Use PM2, systemd, or Docker |
| Cloud | AWS Lambda, Google Cloud Run, Azure Functions |
| Serverless | Vercel, Railway, Render |
Auto-restart on Changes (Development)
npm install -D nodemon
# Add to package.json
# "scripts": { "dev": "nodemon --exec ts-node src/index.ts" }
npm run dev
What Happens When You Start
When you run daemo.start():
- Connection — Secure tunnel established to Daemo Engine
- Registration — Function metadata sent to the platform
- Online — Service shows as "online" in dashboard
- Waiting — Service listens for function calls
You'll see your service and functions appear in the dashboard within seconds.
Service must be running. If your service stops, the AI won't be able to call your functions. The dashboard will show the service as "offline."
Troubleshooting
"Connection refused" or timeout
- Check your internet connection
- Verify your API key is correct
- Ensure no firewall is blocking outbound connections
"Invalid API key"
- Copy the key again from the dashboard
- Check for extra spaces or newlines
- Make sure you're using
DAEMO_AGENT_API_KEY, not a different key type
Functions not appearing in dashboard
- Ensure
@DaemoTool()decorator is present on each function - Check that
registerService()was called beforestart() - Verify the service is running (check console output)
Next Steps
Your service is running! Let's see it in action:
- Dashboard Integration — View your functions in app.daemo.ai