hzhang 7a577db696 fix(hf-plugin): wrap tool returns in MCP {content:[...]} shape
OpenClaw's Codex tool dispatcher (thread-lifecycle:255) expects every
tool execute() to return { content: [...] } and calls result.content.reduce()
to compute total text length. All 9 harborforge_* tools returned bare
objects ({ running, processing, currentSlot, ... }) which has no
.content field — so .reduce of undefined threw, and the agent saw the
cryptic 'Cannot read properties of undefined (reading reduce)' on
every call. This silently blocked every calendar slot transition on
prod for hours: agents could call harborforge_calendar_complete but
it always errored, so slots never moved out of not_started.

Fix is at the registerTool boundary: api.registerTool is wrapped once
to coerce every tool's execute return through ensureMcpContentShape.
Tools that already return the correct shape are unchanged. No per-tool
edits needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 08:28:27 +01:00

HarborForge OpenClaw Plugin

OpenClaw plugin that exposes OpenClaw-side metadata to the HarborForge Monitor, provides an optional local Monitor bridge, drives the HarborForge Calendar scheduler, and can optionally install the hf CLI.

Part of the HarborForge platform.

  • Role: OpenClaw integration layer for HarborForge (registered plugin id: harbor-forge).
  • Talks to the HarborForge backend (backendUrl, default https://monitor.hangman-lab.top) for Calendar APIs.
  • Talks to a local HarborForge.Monitor bridge over 127.0.0.1:<monitor_port> (no fixed default; commonly 9100).

Current State

  • Plugin registration id: harbor-forge (was harborforge-monitor)
  • Plugin version: 0.2.0 (package manifests); telemetry reports pluginVersion 0.3.1
  • Legacy sidecar server/ architecture removed — telemetry is served directly by the plugin
  • Monitor bridge runs over the local monitor_port
  • Calendar scheduler integration (PLG-CAL-001 / 002 / 004)
  • Installer supports --install-cli and an optional managed Monitor (--install-monitor)
  • skills/hf/ is installed only with --install-cli

Project Structure

HarborForge.OpenclawPlugin/
├── package.json
├── README.md
├── docs/                         # design notes (calendar, monitor connector)
├── plugin/
│   ├── openclaw.plugin.json      # plugin manifest + config schema
│   ├── index.ts                  # plugin entry, tool registration
│   ├── tsconfig.json
│   ├── core/
│   │   ├── config.ts             # config defaults / resolution
│   │   ├── managed-monitor.ts    # optionally spawn HarborForge.Monitor
│   │   ├── monitor-bridge.ts     # client for the Monitor bridge
│   │   └── openclaw-agents.ts    # enumerate OpenClaw agents
│   ├── calendar/                 # Calendar scheduler + bridge
│   │   ├── index.ts
│   │   ├── scheduler.ts
│   │   ├── calendar-bridge.ts
│   │   └── types.ts
│   ├── hooks/
│   │   ├── gateway-start.ts
│   │   └── gateway-stop.ts
│   └── package.json
├── skills/
│   └── hf/
│       └── SKILL.md              # installed only with --install-cli
└── scripts/
    └── install.mjs

Installation

Standard Install

node scripts/install.mjs

This will:

  • Build and install the OpenClaw plugin
  • Copy regular skills
  • Not install the hf binary
  • Not copy skills/hf/

Plugin + hf CLI

node scripts/install.mjs --install-cli

This additionally:

  • Builds HarborForge.Cli (go build ./cmd/hf)
  • Installs hf to <openclaw>/bin/hf (default ~/.openclaw/bin/hf) and chmod +x
  • Copies skills/hf/ into the OpenClaw skills directory

Common Options

# Build only (no install / config)
node scripts/install.mjs --build-only

# Install only, skip dependency checks
node scripts/install.mjs --skip-check

# Specify OpenClaw profile path (also honors OPENCLAW_PATH env)
node scripts/install.mjs --openclaw-profile-path /custom/path/.openclaw

# Build and install a managed HarborForge.Monitor binary alongside the plugin
node scripts/install.mjs --install-monitor yes --monitor-branch main

# Verbose logs
node scripts/install.mjs --verbose

# Uninstall (plugin, config entries, hf binary, managed monitor)
node scripts/install.mjs --uninstall

The installer also updates OpenClaw config (plugins.load.paths, plugins.allow, plugins.entries.harbor-forge.enabled) via openclaw config.

Configuration

Edit ~/.openclaw/openclaw.json:

{
  "plugins": {
    "entries": {
      "harbor-forge": {
        "enabled": true,
        "config": {
          "enabled": true,
          "backendUrl": "https://monitor.hangman-lab.top",
          "identifier": "my-server-01",
          "apiKey": "your-api-key-here",
          "monitor_port": 9100,
          "reportIntervalSec": 30,
          "httpFallbackIntervalSec": 60,
          "logLevel": "info",
          "calendarEnabled": true,
          "calendarHeartbeatIntervalSec": 60
        }
      }
    }
  }
}

Then restart:

openclaw gateway restart

Config Options

Option Type Default Description
enabled boolean true Enable the plugin
backendUrl string https://monitor.hangman-lab.top HarborForge backend base URL (Monitor + Calendar APIs)
identifier string hostname Server / claw identifier
apiKey string (none) Server API key from the HarborForge Monitor admin panel
monitor_port number (none) Local bridge port; plugin talks to HarborForge.Monitor via 127.0.0.1:<monitor_port>
reportIntervalSec number 30 Metadata push interval (seconds)
httpFallbackIntervalSec number 60 HTTP heartbeat interval when WS unavailable
logLevel string info Log level: debug / info / warn / error
calendarEnabled boolean true Enable Calendar scheduler integration (PLG-CAL-001)
calendarHeartbeatIntervalSec number 60 Calendar heartbeat interval (seconds)
calendarApiKey string (none) API key for Calendar API auth; falls back to apiKey / X-Agent-ID
managedMonitor string (none) Absolute path to a HarborForge.Monitor binary; if set, gateway start/stop hooks spawn/stop it

Local Monitor Bridge

When the plugin has monitor_port configured and HarborForge.Monitor uses the same MONITOR_PORT:

  • Monitor serves a local bridge on 127.0.0.1:<MONITOR_PORT>
  • The plugin probes GET /health
  • The plugin tool harborforge_monitor_telemetry reads GET /telemetry
  • The plugin pushes OpenClaw metadata (version, plugin version, agents) via POST /openclaw on the reportIntervalSec cadence, enriching Monitor heartbeats
  • If the bridge port is unconfigured or unreachable, the plugin still works normally

This link is an optional enhancement, not a precondition for the plugin to start or for Monitor heartbeats.

Managed Monitor

If managedMonitor points to an installed HarborForge.Monitor binary, the gateway_start hook spawns it (passing --backend-url, --identifier, --api-key, --monitor-port, --report-interval, --log-level from the plugin config) and gateway_stop terminates it. Use install.mjs --install-monitor yes to build and wire this automatically.

Calendar Scheduler

When calendarEnabled is true, on gateway start the plugin starts a Calendar scheduler that heartbeats the backend (/calendar/agent/heartbeat, /calendar/agent/status, /calendar/agent/notify) to receive and run scheduled TimeSlots, waking/spawning agents via the OpenClaw spawn API (with a notification fallback). Scheduler state is persisted to a state file; gateway restarts can be requested by the backend (PLG-CAL-004).

Tools Provided

Tool Description
harborforge_status Plugin status, resolved config, Monitor bridge health, calendar status, telemetry snapshot
harborforge_telemetry Current system telemetry snapshot from this host
harborforge_monitor_telemetry Query the Monitor bridge for host hardware telemetry
harborforge_calendar_status Calendar scheduler status and current slot
harborforge_calendar_complete Complete the current calendar slot with actual duration
harborforge_calendar_abort Abort the current calendar slot
harborforge_calendar_pause Pause the current calendar slot
harborforge_calendar_resume Resume the paused calendar slot
harborforge_restart_status Check whether a gateway restart is pending

Telemetry Snapshot Fields

  • identifier, hostname, platform, timestamp
  • uptime
  • memory: total / free / used / usagePercent
  • load: avg1 / avg5 / avg15
  • openclaw: version / pluginVersion

Development

cd plugin
npm install
npm run build

The build runs tsc and emits dist/ (dist/index.js is the plugin entry).

Dependencies

  • Node.js 18+
  • OpenClaw Gateway
  • Go 1.20+ (only for --install-cli / --install-monitor)

Tips

  • After installing hf, add ~/.openclaw/bin to your PATH
  • When an agent uses hf, try hf --help-brief first
  • For the full command tree, see hf --help
Description
No description provided
Readme 5.3 MiB
Languages
TypeScript 85.3%
JavaScript 14.7%