Plugins

CLI 백엔드 Plugin 빌드하기

CLI 백엔드 Plugin을 사용하면 OpenClaw가 로컬 AI CLI를 텍스트 추론 백엔드로 호출할 수 있습니다. 백엔드는 모델 참조에서 provider 접두사로 나타납니다.

acme-cli/acme-large

업스트림 통합이 이미 로컬 명령으로 노출되어 있거나, CLI가 로컬 로그인 상태를 소유하거나, API provider를 사용할 수 없을 때 CLI가 유용한 대체 경로인 경우 CLI 백엔드를 사용하세요.

Plugin이 소유하는 항목

CLI 백엔드 Plugin에는 세 가지 계약이 있습니다.

계약 파일 목적
패키지 진입점 package.json OpenClaw가 Plugin 런타임 모듈을 찾도록 지정
매니페스트 소유권 openclaw.plugin.json 런타임 로드 전에 백엔드 id를 선언
런타임 등록 index.ts 명령 기본값으로 api.registerCliBackend(...)를 호출

매니페스트는 검색 메타데이터입니다. CLI를 실행하지 않으며 런타임 동작을 등록하지 않습니다. 런타임 동작은 Plugin 진입점이 api.registerCliBackend(...)를 호출할 때 시작됩니다.

최소 백엔드 Plugin

  • 패키지 메타데이터 만들기

    {
      "name": "@acme/openclaw-acme-cli",
      "version": "1.0.0",
      "type": "module",
      "openclaw": {
        "extensions": ["./index.ts"],
        "compat": {
          "pluginApi": ">=2026.3.24-beta.2",
          "minGatewayVersion": "2026.3.24-beta.2"
        },
        "build": {
          "openclawVersion": "2026.3.24-beta.2",
          "pluginSdkVersion": "2026.3.24-beta.2"
        }
      },
      "dependencies": {
        "openclaw": "^2026.3.24"
      },
      "devDependencies": {
        "typescript": "^5.9.0"
      }
    }
    

    게시된 패키지는 빌드된 JavaScript 런타임 파일을 포함해야 합니다. 소스 진입점이 ./src/index.ts라면 빌드된 JavaScript 피어를 가리키는 openclaw.runtimeExtensions를 추가하세요. 진입점을 참조하세요.

  • 백엔드 소유권 선언하기

    {
      "id": "acme-cli",
      "name": "Acme CLI",
      "description": "Run Acme's local AI CLI through OpenClaw",
      "cliBackends": ["acme-cli"],
      "setup": {
        "cliBackends": ["acme-cli"],
        "requiresRuntime": false
      },
      "activation": {
        "onStartup": false
      },
      "configSchema": {
        "type": "object",
        "additionalProperties": false
      }
    }
    

    cliBackends는 런타임 소유권 목록입니다. config 또는 모델 선택에서 acme-cli/...가 언급될 때 OpenClaw가 Plugin을 자동 로드할 수 있게 합니다.

    setup.cliBackends는 descriptor-first 설정 표면입니다. 모델 검색, 온보딩 또는 상태가 Plugin 런타임을 로드하지 않고 백엔드를 인식해야 할 때 추가하세요. 해당 정적 descriptor만으로 설정에 충분한 경우에만 requiresRuntime: false를 사용하세요.

  • 백엔드 등록하기

    import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
    import {
      CLI_FRESH_WATCHDOG_DEFAULTS,
      CLI_RESUME_WATCHDOG_DEFAULTS,
      type CliBackendPlugin,
    } from "openclaw/plugin-sdk/cli-backend";
    
    function buildAcmeCliBackend(): CliBackendPlugin {
      return {
        id: "acme-cli",
        liveTest: {
          defaultModelRef: "acme-cli/acme-large",
          defaultImageProbe: false,
          defaultMcpProbe: false,
          docker: {
            npmPackage: "@acme/acme-cli",
            binaryName: "acme",
          },
        },
        config: {
          command: "acme",
          args: ["chat", "--json"],
          output: "json",
          input: "stdin",
          modelArg: "--model",
          sessionArg: "--session",
          sessionMode: "existing",
          sessionIdFields: ["session_id", "conversation_id"],
          systemPromptFileArg: "--system-file",
          systemPromptWhen: "first",
          imageArg: "--image",
          imageMode: "repeat",
          reliability: {
            watchdog: {
              fresh: { ...CLI_FRESH_WATCHDOG_DEFAULTS },
              resume: { ...CLI_RESUME_WATCHDOG_DEFAULTS },
            },
          },
          serialize: true,
        },
      };
    }
    
    export default definePluginEntry({
      id: "acme-cli",
      name: "Acme CLI",
      description: "Run Acme's local AI CLI through OpenClaw",
      register(api) {
        api.registerCliBackend(buildAcmeCliBackend());
      },
    });
    

    백엔드 id는 매니페스트의 cliBackends 항목과 일치해야 합니다. 등록된 config는 기본값일 뿐입니다. agents.defaults.cliBackends.acme-cli 아래의 사용자 config는 런타임에 그 위로 병합됩니다.

  • Config 형태

    CliBackendConfig는 OpenClaw가 CLI를 실행하고 파싱하는 방법을 설명합니다.

    필드 용도
    command 바이너리 이름 또는 절대 명령 경로
    args fresh 실행을 위한 기본 argv
    resumeArgs 재개된 세션을 위한 대체 argv; {sessionId} 지원
    output / resumeOutput 파서: json, jsonl 또는 text
    input 프롬프트 전송: arg 또는 stdin
    modelArg 모델 id 앞에 사용되는 플래그
    modelAliases OpenClaw 모델 id를 CLI 네이티브 id에 매핑
    sessionArg / sessionArgs 세션 id를 전달하는 방법
    sessionMode always, existing 또는 none
    sessionIdFields OpenClaw가 CLI 출력에서 읽는 JSON 필드
    systemPromptArg / systemPromptFileArg 시스템 프롬프트 전송 방식
    systemPromptWhen first, always 또는 never
    imageArg / imageMode 이미지 경로 지원
    serialize 같은 백엔드 실행 순서 유지
    reliability.watchdog 출력 없음 타임아웃 조정

    CLI와 일치하는 가장 작은 정적 config를 선호하세요. 실제로 백엔드에 속하는 동작에만 Plugin 콜백을 추가하세요.

    고급 백엔드 훅

    CliBackendPlugin은 다음도 정의할 수 있습니다.

    용도
    normalizeConfig(config, context) 병합 후 레거시 사용자 config 다시 쓰기
    resolveExecutionArgs(ctx) thinking effort 같은 요청 범위 플래그 추가
    prepareExecution(ctx) 실행 전 임시 인증 또는 config 브리지 만들기
    transformSystemPrompt(ctx) 최종 CLI별 시스템 프롬프트 변환 적용
    textTransforms 양방향 프롬프트/출력 치환
    defaultAuthProfileId 특정 OpenClaw 인증 프로필 선호
    authEpochMode 인증 변경이 저장된 CLI 세션을 무효화하는 방식 결정
    nativeToolMode CLI에 항상 켜진 네이티브 도구가 있는지 선언
    bundleMcp / bundleMcpMode OpenClaw의 loopback MCP 도구 브리지 사용

    이 훅들은 provider 소유로 유지하세요. 백엔드 훅으로 동작을 표현할 수 있을 때 코어에 CLI별 분기를 추가하지 마세요.

    MCP 도구 브리지

    CLI 백엔드는 기본적으로 OpenClaw 도구를 받지 않습니다. CLI가 MCP 구성을 사용할 수 있다면 명시적으로 옵트인하세요.

    return {
      id: "acme-cli",
      bundleMcp: true,
      bundleMcpMode: "codex-config-overrides",
      config: {
        command: "acme",
        args: ["chat", "--json"],
        output: "json",
      },
    };
    

    지원되는 브리지 모드는 다음과 같습니다.

    모드 용도
    claude-config-file MCP config 파일을 받는 CLI
    codex-config-overrides argv에서 config override를 받는 CLI
    gemini-system-settings 시스템 설정 디렉터리에서 MCP 설정을 읽는 CLI

    CLI가 실제로 이를 사용할 수 있을 때만 브리지를 활성화하세요. CLI에 비활성화할 수 없는 자체 내장 도구 계층이 있다면, 호출자가 네이티브 도구 없음을 요구할 때 OpenClaw가 닫힌 상태로 실패할 수 있도록 nativeToolMode: "always-on"을 설정하세요.

    사용자 구성

    사용자는 모든 백엔드 기본값을 override할 수 있습니다.

    {
      agents: {
        defaults: {
          cliBackends: {
            "acme-cli": {
              command: "/opt/acme/bin/acme",
              args: ["chat", "--json", "--profile", "work"],
              modelAliases: {
                large: "acme-large-2026",
              },
            },
          },
          model: {
            primary: "openai/gpt-5.5",
            fallbacks: ["acme-cli/large"],
          },
        },
      },
    }
    

    사용자에게 필요할 가능성이 큰 최소 override를 문서화하세요. 보통 바이너리가 PATH 밖에 있을 때의 command만 해당합니다.

    검증

    번들된 Plugin의 경우 빌더와 설정 등록을 다루는 집중 테스트를 추가한 다음, Plugin의 대상 테스트 레인을 실행하세요.

    pnpm test extensions/acme-cli
    

    로컬 또는 설치된 Plugin의 경우 검색과 실제 모델 실행 하나를 검증하세요.

    openclaw plugins inspect acme-cli --runtime --json
    openclaw agent --message "reply exactly: backend ok" --model acme-cli/acme-large
    

    백엔드가 이미지 또는 MCP를 지원한다면 실제 CLI로 해당 경로를 증명하는 라이브 스모크를 추가하세요. 프롬프트, 이미지, MCP 또는 세션 재개 동작에 대해 정적 검사에 의존하지 마세요.

    체크리스트

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s package.jsonopenclaw.extensions와 게시된 패키지를 위한 빌드된 런타임 진입점이 있습니다 OPENCLAW_DOCS_MARKER:calloutClose:

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s openclaw.plugin.jsoncliBackends와 의도적인 activation.onStartup을 선언합니다 OPENCLAW_DOCS_MARKER:calloutClose:

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s 설정/모델 검색이 콜드 상태에서 백엔드를 봐야 할 때 setup.cliBackends가 있습니다 OPENCLAW_DOCS_MARKER:calloutClose:

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s api.registerCliBackend(...)가 매니페스트와 동일한 백엔드 id를 사용합니다 OPENCLAW_DOCS_MARKER:calloutClose:

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s agents.defaults.cliBackends.<id> 아래의 사용자 override가 계속 우선합니다 OPENCLAW_DOCS_MARKER:calloutClose: