Files

MeshCentral ↔ OpenClaw Bridge - Implementation

Read-only bridge for device inventory and diagnostics between MeshCentral and OpenClaw.

⚠️ READ-ONLY LIVE TESTING - The real MeshCentral control-channel adapter is authorized for the project's narrowly scoped read-only compatibility test. Diagnostics remain mock-only. Commands, state changes, and production-cluster access are prohibited.

Overview

This implementation provides:

  • Typed contracts - Zod schemas for all data structures
  • Adapter pattern - Clean boundary between bridge and MeshCentral client
  • Mock-backed - Works offline with sample data for development/testing
  • Structured errors - Consistent error handling with codes and metadata
  • Timeouts/output limits - Configurable safeguards for operations

Project Layout

implementation/
├── src/
│   ├── index.ts              # Main entry point
│   ├── contracts.ts          # Typed schemas and interfaces
│   ├── adapter.ts            # Adapter factory and base interface
│   ├── mock-adapter.ts       # Mock implementation for development
│   ├── upstream-transport.ts # Proven read-only MeshCentral transport
│   └── __tests__/            # Test suite
├── package.json              # Node.js dependencies
├── tsconfig.json             # TypeScript configuration
├── jest.config.js            # Jest test configuration
├── example-config.json       # Development/testing config
└── example-config-real.json  # Real MeshCentral integration config (needs credentials)

Quick Start

Install Dependencies

cd implementation
npm install

Run Tests (Mock Data Only)

# All tests - uses mock data, no MeshCentral connection required
npm test

# Watch mode (development)
npm run test:watch

# With coverage
npm test -- --coverage

Build

npm run build

Lint

npm run lint

Usage Example

import { createMeshCentralAdapter, DeviceStatus } from './src/index';

async function main() {
  // Create adapter with configuration
  const adapter = createMeshCentralAdapter({
    meshCentralUrl: 'http://10.10.10.60:8080',
    adapterType: 'mock', // Safe local mode; real mode is read-only and PVE3-scoped
    timeoutMs: 10_000,
    maxOutputLength: 65_536,
  });

  // List all devices (uses mock data)
  const devices = await adapter.listDevices();
  console.log(`Found ${devices.length} devices`);

  // Filter by group
  const onlineDevices = await adapter.listDevices({ groupId: 'grp-servers' });
  console.log(`Online servers: ${onlineDevices.length}`);

  // Get device details
  const device = await adapter.getDevice('dev-001');
  console.log(`Device: ${device.name} (${device.status})`);

  // Run diagnostics (mock data only - no real system commands executed)
  const diskSpace = await adapter.runDiagnostic({
    deviceId: 'dev-001',
    checkType: 'diskSpace',
  });
  console.log(diskSpace.output);

  // Health check (mock always returns healthy)
  const healthy = await adapter.healthCheck();
  console.log(`Bridge healthy: ${healthy}`);
}

main().catch(console.error);

Configuration

Option Type Default Description
meshCentralUrl string 'http://localhost:8080' MeshCentral server URL (unused in mock mode)
adapterType 'real' | 'mock' 'mock' Use mock for local tests; real requires credentials and a reviewed live-test environment
timeoutMs number 10_000 Request timeout in milliseconds
maxOutputLength number 65_536 Maximum output bytes for diagnostics (truncates if exceeded)

Note: The real adapter uses the upstream-compatible MeshCentral /control.ashx WebSocket transport for read-only inventory/status calls. MeshCentral bootstrap messages and native grouped response formats are handled explicitly. Diagnostics still return mock data; no remote commands or state-changing operations are implemented.

Supported Diagnostic Checks

⚠️ MOCK DATA ONLY - All diagnostic outputs are simulated static strings. No real system commands are executed.

  • diskSpace - Simulated filesystem usage statistics
  • services - Simulated system service status
  • processes - Simulated running process list
  • osDetails - Simulated operating system version info
  • networkState - Simulated network interface configuration
  • uptime - Simulated system uptime and load average

Error Handling

All errors include a code from the ErrorCodes enum:

Code Description
ADAPTER_NOT_FOUND Adapter method not implemented
CONFIGURATION_INVALID Invalid configuration provided
TIMEOUT_EXCEEDED Request timed out
OUTPUT_LIMIT_EXCEEDED Output exceeded maxOutputLength (truncated)
AUTHENTICATION_FAILED Authentication error (not implemented)
CONNECTION_FAILED Network connection failed (not implemented)
RESOURCE_NOT_FOUND Device or group not found
MESHCENTRAL_ERROR Generic MeshCentral API error (not implemented)

Adapter Status

Mock Adapter ✅

  • Device listing and filtering by group
  • Device details retrieval
  • Group listing and lookup
  • Diagnostic execution with simulated output
  • Health check

Real Adapter ⚠️ (Read-only scope only)

The real adapter is implemented locally and may be used only for the documented read-only compatibility test. It must remain limited to the approved MeshCentral account and PVE3 target.

  • MeshCentral control-channel integration - Verified live via /control.ashx
  • Device/group inventory and status - Implemented locally
  • Response size and schema validation - Implemented and unit-tested
  • Real-time status updates - Not implemented
  • Actual command execution - Not implemented (diagnostics use mock data)

Testing Strategy

Tests are organized into:

  1. contract.test.ts - Schema validation and type safety
  2. mock-adapter.test.ts - Mock adapter behavior and edge cases
  3. integration.test.ts - Full workflow validation
  4. adapter-factory.test.ts - Adapter creation and configuration

Future Implementation Notes

Real MeshCentral Integration

The adapter uses the MeshCentral control WebSocket rather than the illustrative HTTP endpoints below. The protocol implementation is still subject to version-specific live verification:

// Historical/illustrative endpoints; not used by the current adapter
const ENDPOINTS = {
  devices: '/api/devices',
  device: (id: string) => `/api/device/${id}`,
  groups: '/api/groups',
  diagnostics: (deviceId: string) => `/api/device/${deviceId}/diagnostics`,
};

Authentication will use MeshCentral's token-based auth.

⚠️ SECURITY REQUIRED - Do not enable TLS validation bypass (rejectUnauthorized: false). Certificate verification must be enabled for production use.

Adding New Diagnostic Checks

  1. Add check type to DiagnosticCheckType enum in contracts.ts
  2. Implement output in DIAGNOSTIC_OUTPUTS map in mock-adapter.ts
  3. Add test coverage in integration.test.ts

License

MIT