Content
# Tool List
The MCP service is designed for **XHTKJ** and **醉清风** mini-program supported BLE devices. It encapsulates the BLE communication protocol restored from the relevant mini-programs into an MCP tool, allowing Agents to control device connections, intensity, built-in rhythm, and custom waveforms within clear consent and configuration limits.
The service uses Streamable HTTP transport by default and is compatible with the legacy SSE transport.
## Applicable Devices
This project supports the following mini-program ecosystem BLE devices:
- XHTKJ mini-program supported BLE devices;
- 醉清风 mini-program supported BLE devices.
Compatibility is determined based on device broadcast UUID, GATT services, product ID, and control command protocol. Different batches, models, or firmware may have different functions. After connecting, call `device_status` to check the identified `product_id` and `capability` to decide whether to use the main, secondary, mode, or custom waveform control.
The device capabilities involved in the current protocol may include general intensity, dual-channel output, heating, vibration, shock, and electrical stimulation. Unidentified models will be processed according to the general protocol. When using them for the first time, keep the output upper limit low and perform actual device verification.
## Installation
```powershell
cd mcp
python -m pip install -r requirements.txt
```
## Start Service
```powershell
python server.py
```
Default Streamable HTTP endpoint:
```text
http://127.0.0.1:8000/mcp
```
`/mcp` is the protocol endpoint, not an ordinary webpage. When opened directly in a browser, it may return `406 Not Acceptable` because the browser does not send the required request header for the MCP protocol. You can visit the following address in the browser to check the service status:
```text
http://127.0.0.1:8000/health
```
## Use SSE Mode
When compatible with the old MCP client, switch to SSE:
```powershell
$env:MCP_TRANSPORT="sse"
python server.py
```
Default SSE endpoint:
```text
http://127.0.0.1:8000/sse
```
## Service Configuration
Output limit, listening address, and port can be configured through environment variables:
```powershell
$env:TOY_MAX_OUTPUT_PERCENT="20"
$env:TOY_MAX_DURATION_SECONDS="900"
$env:MCP_HOST="127.0.0.1"
$env:MCP_PORT="8000"
python server.py
```
Environment variable description:
| Environment Variable | Default Value | Description |
| --- | ---: | --- |
| `TOY_MAX_OUTPUT_PERCENT` | `20` | Maximum output percentage allowed by MCP |
| `TOY_MAX_DURATION_SECONDS` | `900` | Maximum duration of single control, range 10~3600 |
| `MCP_HOST` | `127.0.0.1` | Service listening address |
| `MCP_PORT` | `8000` | Service listening port |
| `MCP_TRANSPORT` | `streamable-http` | Transport mode, can be set to `sse` |
| `MCP_ALLOWED_HOSTS` | Local machine only | Allowed HTTP Host to access MCP endpoint |
| `MCP_ALLOWED_ORIGINS` | Empty | Allowed browser Origin |
## Port Mapping and Reverse Proxy
When using other IP or domain to access the service through port mapping or reverse proxy, add the actual HTTP `Host` sent by the client to the whitelist:
```powershell
$env:MCP_ALLOWED_HOSTS="xx.xx.xx.xx:8000"
python server.py
```
Otherwise, the service will record:
```text
Invalid Host header
421 Misdirected Request
```
Multiple hosts are separated by English commas. Browser-like MCP clients may also send `Origin` request headers:
```powershell
$env:MCP_ALLOWED_HOSTS="xx.xx.xx.xx:8000,mcp.example.com"
$env:MCP_ALLOWED_ORIGINS="http://xx.xx.xx.xx:8000,https://mcp.example.com"
python server.py
```
If the service process must listen to all network interfaces directly, set:
```powershell
$env:MCP_HOST="0.0.0.0"
```
If the port mapping program forwards public requests to local `127.0.0.1:8000`, usually no modification to `MCP_HOST` is needed.
## Security Tips
The current service does not implement authentication, please do not expose it directly to the public Internet. It is recommended to configure:
- HTTPS;
- Access token or other authentication;
- Limit allowed source IPs;
- Keep a lower `TOY_MAX_OUTPUT_PERCENT`;
- Do not disable DNS Rebinding protection.
## MCP Tools
| Tool | Effect |
| --- | --- |
| `scan_devices` | Scan nearby BLE devices and mark target devices |
| `connect_device` | Connect device using address or automatically find target device |
| `device_status` | Query connection, product capability, current control, remaining time, and disconnection reason |
| `set_strength` | Set main and optional secondary intensity |
| `play_strength_sequence` | Continuously send custom intensity sequence in the background, can be looped |
| `set_mode` | Switch device mode |
| `play_custom_wave` | Issue custom percentage waveform |
| `stop_device` | Immediately stop current mode and clear command queue |
| `disconnect_device` | Stop output and disconnect BLE connection |
Control duration is configured according to the usage of the device. Intensity tools last 5 minutes by default, mode and custom waveform last 10 minutes by default, and the maximum is 15 minutes. It can be adjusted through `TOY_MAX_DURATION_SECONDS`, with a maximum of 3600 seconds. The device will automatically stop after expiration; calling the output tool again before expiration will refresh the automatic stop countdown. `auto_stop_remaining_seconds` in `device_status` indicates the current remaining time.
`active_control` records the current intensity, mode, or waveform range. The Agent can adjust the rhythm based on it to avoid starting from an unknown state every time.
`set_strength` only sends a fixed intensity. If continuous change is needed, use `play_strength_sequence`. For example, main intensity cycles according to `5 -> 10 -> 15 -> 10`, each step lasts 2 seconds, and runs for a total of 10 minutes:
```json
{
"primary_values_percent": [5, 10, 15, 10],
"step_duration_seconds": 2,
"repeat": true,
"duration_seconds": 600
}
```
The secondary channel can be sent a constant value or a sequence of the same length as the main channel:
```json
{
"primary_values_percent": [5, 10, 15, 10],
"secondary_values_percent": [2, 4, 6, 4],
"step_duration_seconds": 1.5,
"repeat": true,
"duration_seconds": 600
}
```
The minimum step is 0.1 seconds, the maximum is 30 seconds, and the sequence has a maximum of 200 points. Calling other output tools will replace the current sequence. Calling `stop_device` will immediately cancel the sequence and stop the device.
`disconnect_device` stops output first, then disconnects BLE. The BLE connection is held by a long-running service process and can maintain the connection across multiple stateless HTTP requests. Do not put BLE cleanup logic on the request-level `lifespan` of FastMCP, otherwise, the device will disconnect immediately after each MCP tool call.
## MCP Client Configuration
Clients supporting Streamable HTTP can use the following configuration:
```json
{
"mcpServers": {
"ble-toy": {
"url": "http://127.0.0.1:8000/mcp"
}
}
}
```
When using a public IP or domain, replace `url` with the actual address and configure `MCP_ALLOWED_HOSTS` synchronously.