Coding

Intiface Direct

Try it

Control 750+ BLE intimate devices via Intiface Central using direct Buttplug v4 WebSocket protocol

What it does

Control 750+ BLE intimate devices via Intiface Central using direct Buttplug v4 WebSocket protocol

The skill document

Intiface Direct — Buttplug v4 Device Control

Control any Buttplug.io-compatible device — 700+ toys across all major brands — using natural language through OpenClaw. Connects directly to Intiface Central via WebSocket using the Buttplug v4 protocol.

How it works

OpenClaw agent
    → Node.js script (Buttplug v4 WebSocket client)
    → Intiface Central (WebSocket ws://host:port)
    → Your device (Bluetooth / USB)

Works on any platform where Intiface Central is running (Windows, macOS, Linux).


Prerequisites

  • Intiface Central — free desktop app (cross-platform)
  • Node.js (included with OpenClaw)

Setup (one time)

Step 1 — Install and open Intiface Central

Download from intiface.com/central. Open the app and click Start Server. Leave it running — it listens on ws://localhost:12345 by default.

Step 2 — Connect your device

In Intiface Central, click Start Scanning. Power on your toy. Once it appears in the device list, scanning can be stopped.

Step 3 — Install dependencies

cd skills/intiface-direct
npm install

The Connector Script

File: skills/intiface-direct/connector.cjs

Usage

# List devices
node connector.cjs list

# Vibrate once (exits after)
node connector.cjs vibrate   

# Continuous vibration (resends every 3s to prevent timeout)
node connector.cjs loop    [interval_seconds]

# Stop a device
node connector.cjs stop 

# Custom WebSocket URL (e.g. if Intiface is on another machine)
INTIFACE_WS_URL=ws://192.168.0.13:12345 node connector.cjs list

Parameters

ParamDescription
``Device index from list (usually 0 for first device)
``Feature index (usually 0 for vibration)
``Intensity 0–100 (see strength guide below)
[interval_seconds]For loop: how often to resend (default 3)

Strength Guide (0–100 range)

FeelValue
Off0
Gentle10–25
Medium30–50
Strong55–75
Maximum80–100

Creating Custom Patterns (for AI agents)

The connector does basic commands, but the real power is writing tiny temporary scripts that send any sequence of vibrations over a single WebSocket connection. This lets you create ramps, waves, pulses, and complex patterns.

Why this works

The Buttplug v4 protocol uses one persistent WebSocket connection. You can send multiple OutputCmd messages over the same connection, one after another — no need to reconnect for each value change. The ws library is already installed in node_modules/.

Pattern recipe

Write temporary scripts using the same pattern below. The AI should generate these on-the-fly and run them with node:

Example: Ramp up, hold, pulse, fade

const WebSocket = require('ws');
const ws = new WebSocket('ws://localhost:12345');
let id = 1;

function send(type, params) {
  params.Id = id++;
  ws.send(JSON.stringify([{[type]: params}]));
}

ws.on('open', () => {
  send('RequestServerInfo', {
    ClientName: 'PatternGen',
    ProtocolVersionMajor: 4,
    ProtocolVersionMinor: 0
  });
});

ws.on('message', (raw) => {
  const msgs = JSON.parse(raw.toString());
  for (const m of msgs) {
    if (m.ServerInfo) {
      // Sequence: ramp 10→20→30→40→50 (every 500ms)
      [10, 20, 30, 40, 50].forEach((v, i) => {
        setTimeout(() => {
          send('OutputCmd', {
            DeviceIndex: 0,
            FeatureIndex: 0,
            Command: { Vibrate: { Value: v } }
          });
        }, i * 500);
      });
      // Hold at 50 for 2s, then pulse 0→80→0→80→0
      setTimeout(() => {
        [0, 80, 0, 80, 0].forEach((v, i) => {
          setTimeout(() => {
            send('OutputCmd', {
              DeviceIndex: 0,
              FeatureIndex: 0,
              Command: { Vibrate: { Value: v } }
            });
          }, i * 300);
        });
        // Fade out after pulse
        setTimeout(() => {
          [60, 40, 20, 10, 0].forEach((v, i) => {
            setTimeout(() => {
              send('OutputCmd', {
                DeviceIndex: 0,
                FeatureIndex: 0,
                Command: { Vibrate: { Value: v } }
              });
              if (v === 0) ws.close();
            }, i * 400);
          });
        }, 2000);
      }, 3000);
    }
  }
});

Pattern building blocks

GoalHow
RampLoop values from 0 → target in steps (e.g. 10, 20, 30…) with setTimeout spacing
WaveLoop values back and forth (e.g. 0→100→0→100)
PulseSharp 0→max→0 transitions with short intervals
Hold steadySend the same value every ~3s in a setInterval
Fade outDescending values (80, 60, 40, 20, 0) with spacing
Pattern stringEncode as "value,hold_ms" pairs: e.g. "25,1000|50,500|75,200|100,200|75,200|50,500|25,1000" → parse and schedule

Protocol reference (all you need)

Messages are JSON arrays. The key fields:

Handshake:

[{"RequestServerInfo":{"Id":1,"ClientName":"AnyName","ProtocolVersionMajor":4,"ProtocolVersionMinor":0}}]

List devices:

[{"RequestDeviceList":{"Id":2}}]

Vibrate:

[{"OutputCmd":{"Id":3,"DeviceIndex":0,"FeatureIndex":0,"Command":{"Vibrate":{"Value":70}}}}]

Stop (value = 0):

[{"OutputCmd":{"Id":4,"DeviceIndex":0,"FeatureIndex":0,"Command":{"Vibrate":{"Value":0}}}}]

Agent Rules

  • Always stop (Value: 0) after a timed session unless the user says otherwise
  • Use DeviceIndex: 0 unless the user specifies a different device
  • Intiface Central must be running before calling any commands — remind the user if it fails
  • The ws module (require('ws')) is available in skills/intiface-direct/node_modules/ws if you need to write temporary pattern scripts
  • When writing temporary scripts, keep the WebSocket open while the pattern plays, then close it when done

Supported Brands

Lovense · Kiiroo · We-Vibe · Satisfyer · The Handy · OSR-2/SR-6 · and 700+ more


Troubleshooting

ProblemFix
connection refusedOpen Intiface Central and click Start Server
Device not foundClick Start Scanning in Intiface Central, power cycle the toy
Handshake failsMake sure ProtocolVersionMajor/Minor are set (v4)
Error: unknown variantWrong message type — use OutputCmd not VibrateCmd
missing fieldCheck field names — ProtocolVersionMajor not MessageVersion
Remote can't connectUse INTIFACE_WS_URL=ws://:12345 (check firewall)

Related skills

Control Lovense toys (Lush, Hush, Nora, Solace, ...) over the local network from the shell. Zero-dependency Python stdlib CLI, Game Mode (LAN), no cloud or A...

Intuiface (intuiface.com). Use this skill for ANY Intuiface request — reading, creating, and updating data. Whenever a task involves Intuiface, use this skill instead of calling the API directly.

1 installs

Devicebase CLI — cross-platform Go CLI for remote Android, HarmonyOS, and iOS device control via HTTP API. Supports tap, swipe, text input, app launching, screenshots, UI hierarchy inspection, and more.

Control real Android and iOS devices, run apps, take screenshots, and execute on-device inference via Ghost in the Droid MCP server (62 tools).

Connect to and control the Acasis Flow HID dock hardware (VID=0x35e6 PID=0xa4ac, 64-byte reports). Use when: the user asks to connect, check, switch view/pag...

2 installs

Control and query LifeSmart Smart Station IoT devices registered in the RootONLocal app. Queries local device/zone info via http://127.0.0.1:18080, then calls the LifeSmart LocalWeb API directly to get or set device state (lights, switches, blinds, AC, custom IR remotes) and read measurements (air q