6.9 KiB
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
│ └── __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 MeshCentral's
/control.ashxWebSocket protocol for read-only inventory/status calls. 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 statisticsservices- Simulated system service statusprocesses- Simulated running process listosDetails- Simulated operating system version infonetworkState- Simulated network interface configurationuptime- 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 - Implemented locally 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:
- contract.test.ts - Schema validation and type safety
- mock-adapter.test.ts - Mock adapter behavior and edge cases
- integration.test.ts - Full workflow validation
- 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
- Add check type to
DiagnosticCheckTypeenum incontracts.ts - Implement output in
DIAGNOSTIC_OUTPUTSmap inmock-adapter.ts - Add test coverage in
integration.test.ts
License
MIT