Skip to main content

Plugin Setup

OpenClaw exposes shared setup helpers so plugin setup flows behave like the built-in ones. Main subpaths:
  • openclaw/plugin-sdk/setup
  • openclaw/plugin-sdk/channel-setup
  • openclaw/plugin-sdk/secret-input

Channel setup helpers

Use plugin-sdk/channel-setup when a channel plugin needs the standard setup adapter and setup wizard shapes.

Optional channel plugins

If a channel is installable but not always present, use createOptionalChannelSetupSurface(...):
import { createOptionalChannelSetupSurface } from "openclaw/plugin-sdk/channel-setup";

export const optionalExampleSetup = createOptionalChannelSetupSurface({
  channel: "example",
  label: "Example Channel",
  npmSpec: "@openclaw/example-channel",
  docsPath: "/channels/example",
});
That returns:
  • setupAdapter
  • setupWizard
Both surfaces produce a consistent “install this plugin first” experience.

Shared setup helpers

plugin-sdk/setup re-exports the setup primitives used by bundled channels. Common helpers:
  • applySetupAccountConfigPatch(...)
  • createPatchedAccountSetupAdapter(...)
  • createEnvPatchedAccountSetupAdapter(...)
  • createTopLevelChannelDmPolicy(...)
  • setSetupChannelEnabled(...)
  • promptResolvedAllowFrom(...)
  • promptSingleChannelSecretInput(...)

Example: patch channel config in setup

import {
  DEFAULT_ACCOUNT_ID,
  createPatchedAccountSetupAdapter,
  setSetupChannelEnabled,
} from "openclaw/plugin-sdk/setup";

export const exampleSetupAdapter = createPatchedAccountSetupAdapter({
  resolveAccountId: ({ accountId }) => accountId ?? DEFAULT_ACCOUNT_ID,
  applyPatch: ({ nextConfig, accountId }) => {
    const resolvedAccountId = accountId ?? DEFAULT_ACCOUNT_ID;
    return setSetupChannelEnabled({
      nextConfig,
      channel: "example",
      accountId: resolvedAccountId,
      enabled: true,
    });
  },
});

Secret input schema

Use plugin-sdk/secret-input instead of rolling your own secret-input parser.
import {
  buildOptionalSecretInputSchema,
  buildSecretInputArraySchema,
  buildSecretInputSchema,
  hasConfiguredSecretInput,
} from "openclaw/plugin-sdk/secret-input";

const ApiKeySchema = buildSecretInputSchema();
const OptionalApiKeySchema = buildOptionalSecretInputSchema();
const ExtraKeysSchema = buildSecretInputArraySchema();

const parsed = OptionalApiKeySchema.safeParse(process.env.EXAMPLE_API_KEY);
if (parsed.success && hasConfiguredSecretInput(parsed.data)) {
  // ...
}

Provider setup note

Provider-specific onboarding helpers live on provider-focused subpaths:
  • plugin-sdk/provider-auth
  • plugin-sdk/provider-onboard
  • plugin-sdk/provider-setup
  • plugin-sdk/self-hosted-provider-setup
See Provider Plugin SDK.

Setup guidance

  • Keep setup input schemas strict and small.
  • Reuse OpenClaw’s allowlist, DM-policy, and secret-input helpers.
  • Keep setup-entry modules thin; move behavior into src/.
  • Link docs from setup flows when install or auth steps are manual.