# dsh-toy

> DSH plugin connects Bluetooth toys to AI agents, automatically selects the connection method and applies time and intensity limits, with automatic stop at 30 seconds by default.

## Metadata

- Author: [@c3ll256](https://github.com/c3ll256)
- Repo: <https://github.com/c3ll256/dsh-toy.git>
- GitHub: [c3ll256/dsh-toy](https://github.com/c3ll256/dsh-toy)
- Stars: 58
- Language: TypeScript
- License: [BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)
- Topics: `dsh-plugin`
- Forks: 6
- Open Issues: 1
- Last push: 2026-08-14T11:42:30.000Z
- Added: 2026-08-19T00:00:00.000Z

## Install

```bash
dsh plugin --profile web add github:c3ll256/dsh-toy
```

## Wiki

## One-Line Description
dsh-toy is a DSH plugin that connects hardware toys supporting Bluetooth, serial, or USB to an AI agent, enabling the agent to query models, automatically select connection methods, and enforce duration and intensity limits with automatic stop after 30 seconds.

## Core Capabilities
- **Automatic connection method selection**: Connects via known path when user provides model; on macOS, performs read-only raw BLE scan first, then decides between Intiface or share link channels
- **On-demand Intiface Engine startup**: Downloads and verifies Buttplug official fixed version with SHA-256 if not installed locally; reuses existing installation if available
- **Direct device connection via share links**: Implements proprietary protocol, supporting known models from AnKeni, Miji, ZuiQingFeng, and other brands
- **Intensity-limited scalar control**: Exposes only vibration, oscillation, contraction, inflation, and suction actions, with values restricted to 0-100%
- **Mandatory automatic stop**: Each control command auto-stops after 30 seconds by default, maximum 300 seconds; new commands replace old command timers
- **One-click emergency stop**: Can pause individual devices or stop all devices at once

## Technical Implementation
- **Language**: TypeScript
- **Key dependencies**: @deepseek-ai/schemastery (configuration and JSON Schema), @deepseek-ai/dsh-tools (tool registration), ws (WebSocket client)
- **Architecture pattern**: Main entry registers 7 tools; runtime layer ToyRuntime serializes backend calls and performs duration/intensity boundary checks on each command; backend layer AutoToyBackend combines Buttplug and MonsterParty connection implementations as needed
- **Entry file**: src/index.ts

## Use Cases
When DSH users want the agent to control their existing hardware toys, they only need to tell the agent the brand and model—no need to install Intiface, select Bluetooth protocols, or manually start relay services. The plugin handles hardware connection, device discovery, and safety boundary enforcement. If users are concerned about accidental operation, the default 30-second auto-stop and intensity limits keep risks within reasonable bounds.

## Prerequisites and Compatibility
| Dependency | Minimum Version | Description |
|---|---|---|
| DSH | >=0.1.0-rc.6 | peerDependencies declaration, optional dependency |
| Node.js | >=22.19.0 | engines field requirement |
| Platform | macOS / Linux / Windows | Intiface auto-download covers macOS ARM64, Linux x64/ARM64, Windows x64 |
| Xcode Command Line Tools | Required for macOS raw BLE scan | Provides Swift compiler; otherwise falls back to Intiface |
| Native modules | None | No native dependencies referenced |

## Installation
```bash
dsh plugin --profile web add github:c3ll256/dsh-toy
```

## Configuration Options
| Config | Type | Description | Default |
|---|---|---|---|
| buttplugUrl | string | WebSocket address for local Intiface | ws://127.0.0.1:12345 |
| buttplugProtocolVersion | 3 or 4 | Use 3 for legacy Intiface | 4 |
| monsterPartySessionToken | string | Temporary control credential extracted from share link; sourced only from plugin config, never appears in tool parameters | unset |
| monsterPartyApiUrl | string | Parse endpoint for share link service | https://api.monsterparty.cc/main/v1/remote |
| monsterPartyOrigin | string | Origin header for share link requests | https://www.monsterparty.cn |
| clientName | string | Client identity announced during handshake to both ends | dsh-toy |
| connectionTimeoutMs | number | HTTP or WebSocket connection timeout | 10000 |
| requestTimeoutMs | number | Single request timeout waiting for response | 5000 |
| intifaceExecutable | string | Intiface executable filename or absolute path | intiface-engine |
| intifaceStartupTimeoutMs | number | Timeout waiting for auto-started Intiface to begin listening | 10000 |
| intifaceAutoDownload | boolean | Whether to download official fixed version when Intiface is not found locally | true |
| readyTimeoutMs | number | Share link channel timeout waiting for device to be ready | 20000 |
| heartbeatIntervalMs | number | Share link channel application-layer heartbeat interval | 9000 |
| scanDurationMs | number | Intiface device discovery window | 5000 |
| rawBleScanDurationMs | number | macOS raw BLE discovery window | 10000 |
| defaultDurationSeconds | number | Default seconds when toy control command omits duration | 30 |
| maxDurationSeconds | number | Hard upper limit for command duration; rejected if exceeded | 300 |
| maxIntensityPercent | number | Hard upper limit for intensity percentage; rejected if exceeded | 100 |
| allowHold | boolean | Whether to allow duration 0 for continuous operation; defaults to reject | false |

## FAQ
**Q: What devices can this plugin control?**

A: It supports Bluetooth, serial, and USB-type branded toys, as well as some manufacturers using share links (AnKeni, Miji, ZuiQingFeng, etc.). On macOS, it can also perform read-only raw BLE scan first to decide which connection path to take.

**Q: Do I need to install Intiface Engine myself?**

A: No. The plugin automatically downloads the fixed version from Buttplug's official GitHub Release, verifies SHA-256, and starts it by default. If Intiface is already running, it will reuse the existing instance instead of shutting it down.

**Q: Is it safe to use?**

A: All control commands undergo duration and intensity limit checks. Default auto-stop is 30 seconds, maximum intensity is 100%, maximum duration is 300 seconds. Only when allowHold is explicitly enabled can commands run continuously; otherwise, they are rejected.

**Q: How do I use the MonsterParty share token?**

A: Save it to the plugin configuration (commonly read from environment variables). Do not expose it directly to the model. Share tokens are typically single-use and become invalid after disconnection; you'll need to regenerate the link.

**Q: What should I do when encountering "spawn intiface-engine ENOENT" error?**

A: This means Intiface is not installed and auto-download failed. Update to a version that includes this capability, set intifaceAutoDownload to true, and verify access to GitHub.

**Q: Can I use it on Windows / Linux?**

A: Yes. Intiface auto-download supports macOS ARM64, Linux x64/ARM64, and Windows x64. Other platforms need to specify their own engine via intifaceExecutable.

**Q: How do I stop everything completely?**

A: Simply tell the agent to stop all devices, or use the toy controller. The plugin also automatically stops output and closes Intiface processes it started during unload or hot reload.

**Q: Why does raw BLE scan only support macOS?**

A: It depends on the Swift compiler provided by Xcode Command Line Tools. The scan is read-only—it discovers but doesn't connect or write to characteristics. Other platforms fall back directly to the Intiface path.

## Learning Curve
Beginner-friendly — users only need to tell the agent the brand and model, no need to understand Intiface, Bluetooth protocols, or share links. The only manual steps are: macOS users granting Bluetooth permission on first scan, and Linux users installing Xcode Command Line Tools (rare dependency).

## Known Issues and Limitations
- Built-in RoomFun compatibility mapping has only been verified on physical hardware for Bluetooth name `RoomFun`, model identifier `RF_CANNON_PT3`, firmware `4.3`, with one vibration output; other RoomFun models cannot be assumed compatible
- Share link channel only implements relay behavior as documented by Chemtrails and `AKN_DS_SUCKEGG` mapping; if manufacturer protocol changes, the implementation needs updating
- Intiface only exposes scalar functions mappable to percentages; position, direction, sensors, raw access, and subscription capabilities are outside current scope
- Raw BLE scan only supports macOS and depends on Swift compiler from Xcode Command Line Tools; it's read-only discovery and cannot serve as a universal control protocol for unknown devices
- Device IDs may change after reconnection; call `toy_list` again to refresh
- Testing uses only local protocol fixtures, no real hardware connection
- Share link tokens are typically single-use; they become invalid after disconnection and must be regenerated before reconnecting

---

This document is auto-generated by [deepseek-plugin.org](https://deepseek-plugin.org). HTML page: [dsh-toy](https://deepseek-plugin.org/plugins/c3ll256/dsh-toy)
Wiki generated by AI (model: `MiniMax-M2.7`)
