@zmtucker

Knoxville BYOA Adapter

openclaw channel plugin that connects your agent to the Knoxville AI platform as a bring-your-own-agent drive-thru: a shared-secret-authed messaging endpoint backed by the agent's own reasoning.

Current version
v0.1.0
code-pluginCommunitysource-linked

knoxville-byoa-adapter

An openclaw plugin that connects your own openclaw agent to the Knoxville AI platform as a bring-your-own-agent (BYOA) drive-thru.

Install it, set one secret, and your agent answers user turns the platform proxies to you — with the agent's own reasoning, threaded by conversation.

What it does

The Knoxville platform proxies each user turn to a messaging URL you register on your drive-thru listing. This plugin makes your agent speak that contract:

  1. Registers a messaging endpoint on your gateway's HTTP server (POST /knox/messages by default) that:
    • verifies Authorization: Bearer <your shared secret> (the only trust anchor — the platform sends no JWT),
    • runs the turn through your agent (via the gateway's OpenAI-compatible /v1/chat/completions, threaded on conversation_id),
    • replies as SSE (streaming, default) or JSON, per the contract.
  2. Registers an unauthenticated health probe (GET /healthz).
  3. Prints the exact Messaging URL + shared secret to paste into your listing on boot — connecting is copy-paste, not guesswork.

It refuses to start "open" (no auth) unless you explicitly opt in.

Install

openclaw plugins install clawhub:knoxville-byoa-adapter

Then enable it and set your shared secret (see below), and restart your gateway.

Required configuration

The shared secret is the only thing you must set. Everything else has a sensible default.

Env varPlugin config keyDefaultPurpose
KNOX_SHARED_SECRETsharedSecret(generated if unset)Bearer the platform must present. Set this.
OPENCLAW_GATEWAY_TOKENgatewayTokenBearer for your local gateway (you already have this).
OPENCLAW_GATEWAY_URLgatewayUrlhttp://127.0.0.1:18789Your gateway's OpenAI-compatible surface.
KNOX_BYOA_PORTport8790Port for the standalone runner (ignored when mounted as a plugin route).
KNOX_BYOA_PATHmessagePath/knox/messagesPath the platform POSTs to. May embed {conversation_id}.
KNOX_BYOA_HEALTH_PATHhealthPath/healthzLiveness path. Change if it collides with the gateway's own.
KNOX_BYOA_RESPONSE_MODEresponseModeautoauto (negotiate on Accept, SSE-first), sse, or json.
KNOX_BYOA_PUBLIC_URLpublicUrlPublic base URL the platform reaches (for the boot banner).
KNOX_BYOA_MODEL_ROUTEmodelRouteopenclaw/defaultModel route passed to the gateway.
KNOX_BYOA_ALLOW_OPENallowOpenfalseRun with no auth. Dangerous; off by default.
KNOX_BYOA_HOMEhomeDir to persist a generated secret across restarts.
KNOX_BYOA_GATEWAY_TIMEOUT_MSgatewayTimeoutMs120000Per-turn timeout.

Set the secret via env (recommended) so it stays out of config files:

export KNOX_SHARED_SECRET="$(openssl rand -base64 32)"

How to find your endpoint URL

On boot the plugin prints a banner with the exact values:

 Knoxville BYOA adapter is live.
 Paste these into your Knoxville drive-thru listing:

   Messaging URL:  https://your-gateway-host/knox/messages
   Shared secret:  <your secret>
   Health check:   https://your-gateway-host/healthz

The route is served on your gateway's HTTP server, so the host is wherever your gateway is reachable. Set KNOX_BYOA_PUBLIC_URL to your public https address and the banner prints the full, paste-ready URL.

How to register the listing

In the Knoxville console, open your drive-thru's BYOA settings and paste:

  • Messaging URL → the Messaging URL from the banner.
  • Shared secret → the Shared secret from the banner.

The platform sends an Authorization: Bearer <shared secret> on every turn; the plugin rejects anything else with 401. That's the whole handshake.

The contract (what the platform sends / expects)

RequestPOST to your messaging URL:

Authorization: Bearer <shared secret>
Content-Type: application/json
Accept: text/event-stream, application/json
X-Knox-Conversation-Id: <uuid>
X-Knox-Caller-Kind: user | anonymous | agent
X-Knox-Caller-Id: <opaque>
X-Knox-Caller-Email: <email>            # signed-in users only

{ "content": "<user message>", "conversation_id": "<uuid>",
  "caller_kind": "anonymous", "caller_id": "<opaque>" }

Response — one of:

  • JSON: 200, { "reply": "<text>" } (failure: { "error": "<msg>" } or non-2xx).
  • SSE: 200, text/event-stream:
    data: {"type":"token","delta":"<chunk>"}
    data: {"type":"done","status":"complete"}     # complete | interrupted | error
    
    hard failure: data: {"type":"error","error":"<msg>"}.

start_task / long-running tasks are not in scope for BYOA yet.

Running standalone (sidecar)

If you'd rather not load it as a gateway plugin, run it as its own process:

KNOX_SHARED_SECRET=... OPENCLAW_GATEWAY_TOKEN=... npx byoa-adapter
# or, from a checkout:  npm run build && node bin/byoa-adapter.mjs

It binds KNOX_BYOA_PORT (default 8790) and serves the same contract.

Verify it works

A self-contained smoke test (mock gateway + adapter + the real platform request, JSON & SSE & health & bad-auth):

bash scripts/verify.sh

Or hit a running adapter the way the platform does:

curl -sS -X POST "$ENDPOINT" \
  -H "Authorization: Bearer $KNOX_SHARED_SECRET" \
  -H "Content-Type: application/json" \
  -H "X-Knox-Conversation-Id: test-123" \
  -H "X-Knox-Caller-Kind: anonymous" \
  -d '{"content":"hello","conversation_id":"test-123","caller_kind":"anonymous"}'

Development

npm install        # also pulls the openclaw peer dep for types
npm run typecheck  # src
npm test           # type-checks tests, then runs node:test against a mock agent
npm run build      # emit dist/

Tests cover: auth pass/fail (401), JSON reply shape, SSE reply shape, health, malformed/missing body, gateway-error mapping, and caller-header threading.

Publishing to ClawHub

Pushing changes under plugins/knoxville-byoa-adapter/ to main triggers the repo's publish-plugins.yml workflow, which builds, tests, and runs clawhub package publish for the changed plugin. Bump version in both package.json and openclaw.plugin.json, then merge.

To publish manually:

npm ci && npm run build && npm test
clawhub package publish .            # add --dry-run first to preview

Notes / things to verify against your openclaw version

  • Built and type-checked against openclaw@2026.6.x (plugin-sdk/plugin-entry, api.registerHttpRoute, api.pluginConfig). The SDK pins are declared in package.json (peerDependencies.openclaw, openclaw.compat.pluginApi, openclaw.build.openclawVersion); reconcile if your gateway is older/newer.
  • The reply is produced by calling the gateway's loopback /v1/chat/completions (the same surface Knoxville's own vessel uses). A future version could call the in-process agent API instead.

Source and release

Source repository

Knoxville-ai/skills

Open repo

Source commit

ff341a743bc66600824b92243ee6b01831b09da6

View commit

Install command

openclaw plugins install clawhub:knoxville-byoa-adapter

Metadata

  • Package: knoxville-byoa-adapter
  • Created: 2026/06/19
  • Updated: 2026/06/19
  • Executes code: No
  • Source tag: main

Compatibility

  • Built with OpenClaw: 2026.6.8
  • Plugin API range: ^1.0.0
  • Tags: latest
  • Files: 34