Build Your First Capsule Service
This walks you through wiring a minimal Node.js Capsule Service into Opstage in about 10 minutes.
Public Review package
This guide uses @xtrape/capsule-agent-node from the public-review npm dist-tag. Pin an explicit prerelease version if you need reproducible builds during Public Review.
What you'll build
A tiny service that:
- registers itself with Opstage on first start,
- declares one Capsule Service called
my-capsule, - reports its health,
- exposes one action (
echo), - executes commands dispatched from the Opstage console.
1. Have Opstage CE running
Follow the Quick Start first. You should be able to sign in to http://localhost:8080.
2. Create a registration token
In the Opstage console:
- Go to Registration Tokens.
- Click Create Token.
- Copy the one-time
opstage_reg_...value. It is shown only once.
3. Set up a Node project
mkdir my-capsule && cd my-capsule
pnpm init
pnpm add @xtrape/capsule-agent-node@public-review
pnpm add -D typescript tsx @types/nodeFull runnable demo
For a complete service with health, configs, search/list actions, row actions, and detail results, use xtrape-capsule-demo.
tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "Bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"outDir": "dist"
},
"include": ["src"]
}4. Write the agent bootstrap
src/main.ts:
import { CapsuleAgent } from "@xtrape/capsule-agent-node";
const agent = new CapsuleAgent({
backendUrl: process.env.OPSTAGE_BACKEND_URL ?? "http://localhost:8080",
registrationToken: process.env.OPSTAGE_REGISTRATION_TOKEN,
tokenStore: {
file: process.env.OPSTAGE_AGENT_TOKEN_FILE ?? "./data/agent-token.txt",
},
agent: {
code: "my-capsule-agent",
name: "My Capsule Agent",
runtime: "nodejs",
},
service: {
code: "my-capsule",
name: "My Capsule Service",
version: "0.1.0",
runtime: "nodejs",
description: "A minimal Capsule Service used as a Hello-World example.",
},
});
// Health reporting
agent.health(async () => ({
status: "UP",
message: "ok",
details: { uptimeSeconds: Math.floor(process.uptime()) },
}));
// Config reporting (optional)
agent.configs(() => [
{
key: "GREETING",
type: "string",
sensitive: false,
editable: false,
valuePreview: process.env.GREETING ?? "hello",
},
]);
// Action — server-callable operation
agent.action({
name: "echo",
label: "Echo",
description: "Return the submitted message.",
dangerLevel: "LOW",
requiresConfirmation: false,
inputSchema: {
type: "object",
required: ["message"],
properties: {
message: { type: "string", default: "hello" },
},
},
handler: async (payload) => ({
success: true,
data: { echo: payload.message },
}),
});
await agent.start();
console.log("Capsule Service started.");5. Run the service
OPSTAGE_BACKEND_URL=http://localhost:8080 \
OPSTAGE_REGISTRATION_TOKEN=opstage_reg_... \
pnpm exec tsx src/main.tsOn first start the agent:
- exchanges the registration token for an agent token,
- saves the issued credentials under
./data/agent-token.txt, - starts heartbeating and reporting
my-capsule.
Subsequent restarts use the cached agent token. The registration token
can be revoked from the Opstage console once your service is online. :::
6. Verify in the console
In Opstage CE you should now see:
- Agents — your new agent listed as
ONLINE. - Capsule Services —
my-capsulewith healthHEALTHY. - Audit Events —
agent.registered,service.reported,agent.heartbeat.received.
7. Trigger an action
- Open
my-capsule→ Actions tab. - Click Run on
echo. - Fill the form (
message: "hi") and confirm. - Opstage creates a
command; your agent picks it up via long-poll and runs the handler. - The command result appears in Commands with
status = SUCCEEDEDandresult = { "echo": "hi" }.
8. Inspect the audit trail
Every meaningful event is recorded:
command.created(operator triggered the action)command.dispatched(agent picked it up)command.completed(agent reported success)
Match CE, SDK, Contracts, and Demo versions
Pin matching 0.1.x versions across xtrape-capsule-ce, @xtrape/capsule-agent-node, @xtrape/capsule-contracts-node, and xtrape-capsule-demo. During Public Review the npm packages live under the public-review dist-tag — see the v0.1.0 release notes for the matching matrix.
→ Continue with Node Embedded Agent for the full SDK surface.