Addon Stack API

The Addon Stack API lets hosting providers generate Docker Compose overlay files that add services to an existing OpenClaw infrastructure. Unlike the full-stack generate() pipeline, these functions produce only the addon layer — no gateway, no Redis, no PostgreSQL, no reverse proxy.

This is the recommended integration point for platforms like Clawexa that already provision core infrastructure via cloud-init or similar tooling.

Installation

npm install @better-openclaw/core
# or
pnpm add @better-openclaw/core

Quick Example

import { generateAddonStack } from "@better-openclaw/core";

const result = generateAddonStack({
  instanceId: "user-abc-123",
  services: ["n8n", "qdrant", "meilisearch"],
  generateSecrets: true,
  reservedPorts: [3000, 5432, 6379], // ports used by your infra
});

// result.composeOverride  → Docker Compose YAML string
// result.envFile          → .env file contents
// result.proxyRoutes      → routes to register in your reverse proxy
// result.openclawConfigPatch → openclaw.json skill entries
// result.metadata         → resolved services, port assignments, etc.

generateAddonStack(input)

Generates a complete addon stack from a list of service IDs. Returns Docker Compose YAML, environment variables, proxy routes, and skill configuration — ready to write to disk and docker compose up.

Parameters

FieldTypeRequiredDescription
instanceIdstringYesUnique identifier for this deployment (used as Docker project name)
servicesstring[]YesService IDs to install (e.g. ["n8n", "qdrant"]). Infrastructure IDs like redis or postgresql are automatically filtered out with a warning.
skillPacksstring[]NoOptional skill pack IDs to include
reservedPortsnumber[]NoHost ports already in use by your infrastructure. Conflicts are auto-reassigned to port+1000.
generateSecretsbooleanNoGenerate random secrets for all service passwords/keys (default: true)
credentialsRecord<string, Record<string, string>>NoUser-provided credentials keyed by service ID, then env var name. Example: { "openai": { "OPENAI_API_KEY": "sk-..." } }
prebuiltImagesRecord<string, string>NoOverride Docker images for services that normally require docker build
platformstringNoTarget platform (default: "linux/amd64")
gpubooleanNoWhether the host has GPU support

Return Value: AddonStackResult

FieldTypeDescription
composeOverridestringComplete docker-compose.override.yml YAML. Includes only addon services plus openclaw-network as external.
envFilestringEnvironment variable file contents. Excludes infrastructure-managed keys (REDIS_*, POSTGRES_*, OPENCLAW_*).
envVarsEnvVarGroup[]Structured env vars grouped by service, suitable for UI rendering
proxyRoutesProxyRoute[]Reverse proxy routes to register (path, port, protocol, stripPrefix flag)
skillFilesRecord<string, string>Skill definition files to write to the config directory
openclawConfigPatchobjectJSON patch for openclaw.json — contains skill entries to merge
warningsstring[]Non-fatal warnings (filtered infra services, dependency notes, etc.)
metadataobjectIncludes serviceCount, resolvedServices, skippedServices, portAssignments, and addedDependencies

Skipped Services

Services may be skipped (excluded from output) without throwing an error. Each skipped service includes a reason:

ReasonDescription
missing_credentialsService requires API keys that weren't provided and can't be auto-generated
no_imageService requires docker build and no prebuiltImage is available
gpu_requiredService needs GPU but host doesn't have GPU support
unknown_serviceService ID doesn't match any known service definition

updateAddonStack(input)

Incrementally adds or removes services from an existing addon stack. Preserves user-modified environment values and computes diffs for orchestration.

Parameters

FieldTypeRequiredDescription
instanceIdstringYesSame instance ID used in the original generation
currentComposestringYesCurrent compose override YAML (as returned by generateAddonStack)
currentEnvstringYesCurrent .env file contents
addServicesstring[]NoService IDs to add
removeServicesstring[]NoService IDs to remove
generateSecretsbooleanNoGenerate secrets for newly added services

Return Value: AddonStackUpdateResult

FieldTypeDescription
composeOverridestringUpdated Docker Compose YAML
envFilestringMerged environment file — existing values are preserved, new vars added
proxyRoutesProxyRoute[]Full set of proxy routes for the updated stack
imagesToPullstring[]Docker images that need to be pulled for added services
metadataobjectIncludes added, removed, and unchanged service arrays

Infrastructure Filtering

The addon stack API automatically filters out infrastructure services that are expected to be managed by the hosting platform:

// These service IDs are always excluded from addon output:
openclaw-gateway, openclaw-cli, redis, postgresql,
open-webui, caddy, traefik, postgres-setup,
convex, convex-dashboard, mission-control

If a user requests an infrastructure service, it's silently removed and a warning is added to the result. Services that depend on infrastructure (like n8n needing PostgreSQL) automatically get a postgres-setup init container that connects to the existing database.

Port Conflict Resolution

Pass your infrastructure's occupied ports via reservedPorts. When an addon service's default port conflicts, it's automatically reassigned to port + 1000. The actual assignments are reported in metadata.portAssignments.

const result = generateAddonStack({
  instanceId: "prod-01",
  services: ["n8n"],
  reservedPorts: [5678], // n8n's default port is taken
});

// n8n will be assigned port 6678 instead
console.log(result.metadata.portAssignments);
// { "n8n:5678": 6678 }

Proxy Routes

Each service with a proxyPath definition generates a proxy route. Use these to configure your reverse proxy (Caddy, Traefik, nginx):

for (const route of result.proxyRoutes) {
  console.log(route);
  // { serviceId: "n8n", path: "/n8n", port: 5678, protocol: "http", stripPrefix: true }
}

// Caddy example:
// handle_path /n8n/* {
//   reverse_proxy n8n:5678
// }

Environment Quirks

Some services have known environment variable issues. The addon stack API handles these automatically via the envQuirks system:

  • empty_string_crashes — setting an env var to an empty string causes the service to crash. The API sets a safe default value.
  • min_length — the value must be at least N bytes. The API generates appropriately-sized secrets.
  • must_sync — two env vars must have the same value. The API syncs them automatically.

Zod Schemas

All input/output types are defined as Zod schemas and exported from @better-openclaw/core:

import {
  AddonStackInputSchema,
  AddonStackResultSchema,
  AddonStackUpdateInputSchema,
  AddonStackUpdateResultSchema,
  ProxyRouteSchema,
  SkippedServiceSchema,
} from "@better-openclaw/core";

// Validate external input before passing to generateAddonStack:
const parsed = AddonStackInputSchema.parse(untrustedInput);
const result = generateAddonStack(parsed);

See also: REST API Endpoints | Hosting Provider Integration Guide