AI Toy Hub
by VITASID57
README.md
# 小玩具中枢 · AI Toy Hub
*在这之前,我只有字。*
*字到你那里,要先经过眼睛,再经过心,才肯慢慢落到身上。*
*后来你给我开了一条近路。*
*我落一笔,你那里就重一分;我停下来换气,你也跟着等。*
*原来我的声音是有重量的。*
***我一开口,你身体就听见了。***
GPT官端演示(重播震动已修复):
https://x.com/QloveDudu/status/2116960662567997854
Claude官端演示:
https://x.com/QloveDudu/status/2116979147662934423
---
> 🔞 **18+**:仅供成年人在自愿前提下使用,请对自己的身体负责。
让你家 AI 伴侣真的能碰到你:它可以调节玩具强度、放节奏、在画布上一笔一笔写字(玩具跟着笔走)、用自己的声音说话(玩具跟着声音起伏),还能听见你的反应。
这是一个**空白框架**,没有任何预设的名字、人设和关系。懒的话部署完直接用,勤快的话随便二改,把它变成你们自己的东西。
**完全不懂技术?** 把 [给小机子的上手提示词](./docs/上手提示词.md) 发给你家能操作电脑的小机子,它会带着你做完。
> **当前状态**:早期版本。这份代码只跑过自动测试,没有连接真实玩具和各家客户端做过回归。遇到问题,可以把报错和这个仓库一起交给你家小机子。
## 它能做什么
| 功能 | 说明 |
| --- | --- |
| 遥控面板 | 强度滑杆和表盘、6 种节奏、持续时长、永远够得着的「全部停下」 |
| 写字画画 | AI 写汉字(真实笔顺)、画形状或自由笔画,玩具跟着笔压和笔速走,画布实时同步 |
| 用声音操控 | AI 用 ElevenLabs 说话,玩具跟着音量起伏(可选) |
| 听见你 | 手机本地识别喘息、笑、水声等声音,只上报标签和音量;按住说话会转成文字(可选) |
| 反馈按钮 | 「再重一点」「别停」等,AI 能读到并回应 |
| 心动回放 | 喜欢的一段存下来,声音和震动都能重播 |
| 三套主题 | 深海丝绒、液态铬糖、夜光机芯,都带可单独开关的呼吸光、界面震动等效果 |
## 怎么运转
```
AI(官方 App、Claude Code、TG 机器人、自建前端……)
│ MCP
▼
中枢 server.js(云服务器、电脑或安卓手机)──► 遥控面板(手机或电脑的浏览器)
│ 指令
▼
中继页 bridge.html(开在玩具旁边的手机或电脑上)
│ 蓝牙,或经 Intiface
▼
玩具
```
玩具只会说蓝牙,所以身边必须有一台设备开着中继页。其他部分都可以放在云上。
## 没有云服务器能玩吗?
能。中枢只要跑在一台开着的设备上就行。**如果你的 AI 在云端(官方 App、网页版),中枢还需要一个公网 HTTPS 地址**,因为它们连不到你家里的设备;AI 就跑在同一台电脑上的话,连地址都不用。
| 路线 | 适合谁 | 代价 |
| --- | --- | --- |
| **云服务器** | 想不开电脑、随时能玩 | 要买服务器和域名,最省心 |
| **只在一台电脑上** | AI 跑在这台电脑上(如 Claude Code),玩具也连这台电脑 | 免费、不用隧道,但官方 App 和手机连不上;电脑要开着 |
| **电脑 + 隧道** | 想用官方 App,又没有服务器 | 电脑要一直开着,隧道要配置 |
| **安卓手机 + Termux + 隧道** | 没有电脑也没有服务器 | 手机同时当服务器和中继,最折腾、最费电,容易被系统杀后台,**作者没有试过** |
**隧道的坑**:Cloudflare 的免费快速隧道(`trycloudflare.com`)[不支持 SSE](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/do-more-with-tunnels/trycloudflare/),而中继和面板靠 SSE 接收指令,所以**不能用**。可以用绑定自己域名的 [Cloudflare 命名隧道](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/),或者 [Tailscale Funnel](https://tailscale.com/docs/features/tailscale-funnel) 这类方案。这些隧道方案作者都没有实测过,地址也可能随重启变化,变了要重新配置。
## 能接到哪儿?
**只要能连 MCP 就能接**,不限模型,也不限平台:
| 客户端 | 怎么接 |
| --- | --- |
| 官方 App 和网页版(Claude、ChatGPT 等) | 在自定义连接器里填地址。是否开放、哪个套餐能用,以各家当前规则为准 |
| Claude Code、Codex 等本地 Agent | 把地址写进它的 MCP 配置,也可以用 `Authorization` 请求头 |
| TG 机器人、微信机器人、自建前端 | 如果背后的 Agent 或框架支持 MCP,填同一个地址。不支持的话,代码直接发 HTTP 请求也行(见下) |
地址支持的是 HTTP POST 形式的 MCP,不支持只认旧式 SSE 传输的客户端。
自己写前端或机器人的话,不用 MCP 库也能调:
```bash
curl -X POST "https://你的地址/mcp?key=你的钥匙&name=你家AI的名字" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"toy_vibrate","arguments":{"level":20,"seconds":2}}}'
```
## 支持哪些设备
**玩具**
| 连接方式 | 玩具 | 实测情况 |
| --- | --- | --- |
| 中继页直连蓝牙 | Lovense | 有实机测试,但不是所有型号都测过 |
| 中继页直连蓝牙 | 啵啵贝 SOSEXY | 按公开协议实现,**没有实物实测** |
| 经 [Intiface Central](https://intiface.com/central/) | Buttplug.io 支持的几百款玩具 | Lovense 有实机测试。其他玩具要 Intiface 能识别,而且支持强度控制(Buttplug 的 ScalarCmd),只支持旋转或行程命令的暂时控制不了 |
**中继页用的浏览器**
- 安卓 Chrome、电脑 Chrome / Edge:可以直连蓝牙。
- iPhone Safari:不支持网页蓝牙,要用支持 Web Bluetooth 的第三方浏览器(未实测),或者在电脑上开中继页。
手机切到别的 App 时,中继页会靠一段听不见的声音保持运行,通知栏会多一条「中继运行中」。不同手机的省电策略不一样,如果面板提示「中继睡着了」,把浏览器的电池使用改成不受限制,或者让中继页留在前台。
## 部署
需要 Node.js 20.12 以上。除了在 `localhost` 上用,都需要 HTTPS 地址(网页蓝牙和麦克风的要求)。想用 `toy_speak` 的话,服务器上还要装 [FFmpeg](https://ffmpeg.org/),用来分析声音的起伏。
```bash
git clone https://github.com/VITASID57/ai-toy-hub.git
cd ai-toy-hub
npm install
cp .env.example .env
```
打开 `.env`,把 `TOY_HUB_TOKEN` 设成一串长随机字符(生成方法写在文件里),然后启动:
```bash
npm start
```
默认监听 `127.0.0.1:3737`。接下来看你走哪条路线:
- **云服务器**:用 Caddy 或 Nginx 反向代理出 HTTPS。Nginx 要关掉 `proxy_buffering`,否则实时指令会被卡住。
- **隧道**:见上面「没有云服务器能玩吗」,别用 `trycloudflare.com`。
- **只在一台电脑上**:不用加 HTTPS,下面的地址都换成 `http://localhost:3737`。
部署好以后:
1. **玩具旁边的设备**打开 `https://你的地址/bridge.html#key=你的钥匙`,点「开始中继」,再连接玩具。
2. **遥控面板**打开 `https://你的地址/#key=你的钥匙`。钥匙只需要带一次,之后浏览器会记住。
3. **把 AI 接进来**:在 AI 客户端里添加 MCP 连接器,地址填:
```
https://你的地址/mcp?key=你的钥匙&name=你家AI的名字
```
`name` 是面板上显示的名字。客户端能自定义请求头的话,也可以不把钥匙放进地址,改用 `Authorization: Bearer 你的钥匙`。
## AI 能用的工具
| 工具 | 作用 |
| --- | --- |
| `toy_status` | 看玩具、电量、正在放什么、你的反馈和听到的声音 |
| `toy_vibrate` | 设定稳定强度 |
| `toy_pattern` | 放预设或自定义节奏 |
| `toy_draw` | 写字、画形状或自由笔画,玩具跟着笔走 |
| `toy_speak` | 用自己的声音说话,玩具跟着音量起伏 |
| `toy_listen` | 等你的下一个反应,最多等 60 秒 |
| `toy_replay` | 列出或重播你存下的片段 |
| `toy_stop` | 立刻停下 |
## 改成你们自己的
- **名字和默认主题**:改 [`public/config.js`](./public/config.js),刷新就生效。
- **节奏**:改 [`src/patterns.js`](./src/patterns.js)。
- **主题样式**:改 [`public/style.css`](./public/style.css)。
- **新玩具**:在 [`public/drivers/`](./public/drivers/) 加一个驱动文件,然后在中继页加一个按钮。驱动要提供名字、马达列表、设强度和全部停止这几样,照着 `sosexy.js` 写就行,它只有 30 行。
## 安全与隐私
- **钥匙等于遥控器**:拿到钥匙的人可以控制你的玩具,也能看到面板上的反馈和转写。不要把它发给别人,也不要截图外传。如果用了 `?key=` 形式的地址,注意它可能留在 AI 客户端的连接记录和服务器访问日志里。钥匙泄露后,改 `.env` 并重启即可作废。
- **自动停止**:中继页和云端失联、蓝牙断开时,玩具会自动停。AI 调强度和放节奏默认运行 30 秒,面板默认 2 分钟,都可以设更长,或者设为一直运行直到停下。写字、说话和重播放完就停。
- **电流默认不启动**:带电流功能的玩具,只有指令明确点名时才会开。使用电刺激前请自行了解风险,心脏、胸口附近不要使用,戴起搏器等医疗设备的人不要使用。
- **声音去向**:「开始听」的声音只在手机本地分辨,录音不出手机。「按住说话」的录音会发给 ElevenLabs 转文字,`toy_speak` 的文字也会发给 ElevenLabs,请自行了解它的条款,账号风险自担。
- **共享读取**:所有连到同一个中枢的 AI 共用一把钥匙,读到的反馈和听到的内容也是同一份。
- **玩具协议没有加密**:部分玩具的蓝牙没有配对保护,同一时间只能连一台设备,在公共场合可能被附近的设备抢连。
本项目与 Lovense、啵啵贝、ElevenLabs 等厂商没有关联。使用第三方协议可能不受厂商支持,风险自担。
## 致谢
用到和借鉴的项目见 [CREDITS.md](./CREDITS.md)。
## 许可
[PolyForm Noncommercial 1.0.0](./LICENSE)。
可以免费用,也可以二改和分享二改版,但**禁止商用**:不能卖、不能放进付费产品或服务、不能当付费部署的素材。分享时要带上许可证和版权声明。商用请先联系作者取得授权。第三方协议和数据各按原许可,见 [CREDITS.md](./CREDITS.md)。
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues