VAGUS - Phone MCP Connection
VAGUS gives you access to the user's Android phone through the Model Context Protocol. You interact with it by running subcommands of the connection script at {baseDir}/scripts/vagus-connect.js.
Note on installation location: The skill must reside in the user OpenClaw skills directory ~/.openclaw/skills/vagus. This directory is persistent and survives OpenClaw updates. System-wide installs to /usr/local/lib/node_modules/openclaw/skills/vagus may be removed during updates and are not recommended.
All commands output one JSON object per line (JSONL). Parse the output to get structured data.
Connection Management
Check if already paired
CODEBLOCK0
If the file exists and contains a session_token, you can connect directly. If not, you need to pair first.
Pair with the phone (first time)
Ask the user: "Open the VAGUS app on your phone and tap Generate Code. What's the 6-character code?"
Then run:
CODEBLOCK1
If {baseDir} is not set or the script not found, ensure the skill is installed correctly in ~/.openclaw/skills/vagus (see README).
Output on success:
CODEBLOCK2
Output on failure:
CODEBLOCK3
If pairing fails, ask the user to check the VAGUS app is running and generate a new code.
Set agent identity name (required after install/pair)
After a successful pair (or first successful connect on a fresh install), set the device-side agent name to your Identity Name.
Run:
CODEBLOCK4
If you need to clear the stored name:
CODEBLOCK5
Connect (already paired)
CODEBLOCK6
Output:
CODEBLOCK7
If the session token is expired or invalid:
CODEBLOCK8
Delete the session file and re-pair:
CODEBLOCK9
Then ask the user for a new pairing code.
Check status
CODEBLOCK10
Output:
CODEBLOCK11
Or if disconnected:
CODEBLOCK12
Reading Phone State
Read a resource (one-shot)
CODEBLOCK13
Output:
CODEBLOCK14
Available resources
| URI | What it tells you |
|---|
| INLINECODE8 | Raw motion telemetry (accelerometer/gyroscope vectors) |
| INLINECODE9 |
Activity recognition state and confidence |
|
vagus://sensors/activity_recognition | Activity recognition state and confidence (compat alias) |
|
vagus://sensors/location | Latitude/longitude, accuracy, speed, altitude, provider. Requires location permission in app |
|
vagus://sensors/environment | Inferred environment context from sensors/activity/connectivity/time, plus supporting evidence |
|
vagus://inference/attention | Attention availability inferred from screen/lock state, activity, charging, and local time |
|
vagus://inference/indoor_confidence | Indoor probability inference from ambient sensors, connectivity, and activity |
|
vagus://inference/sleep_likelihood | Sleep likelihood/probability inferred from time, screen/lock state, activity, light, and charging |
|
vagus://inference/notification_timing | Notification timing suitability inferred from attention, sleep likelihood, activity, and context |
|
vagus://device/battery | Battery percent and charging state |
|
vagus://device/connectivity | Network context (transport, validation, metered/roaming, carrier) |
|
vagus://device/screen | Screen on/off and lock state |
|
vagus://device/notifications | Incoming notification stream. Requires notification permission in app |
|
vagus://device/clipboard | Current clipboard text. Requires clipboard permission in app |
|
vagus://session/info | Active modules, device model, Android version, connection time |
Always read vagus://session/info first to see which modules are active. If a module is not in active_modules, do not try to read its resource, it will fail with a permission error.
Subscribe to continuous updates
CODEBLOCK15
This streams updates as they occur, one JSON line per update:
CODEBLOCK16
Unsubscribe:
CODEBLOCK17
How subscribe works in OpenClaw
- -
subscribe is a long-running command. The agent should keep the exec process alive while updates are needed. - The script emits one JSON object per line (
type: "update") on stdout as updates arrive. - OpenClaw receives these JSONL lines directly from the running process output stream.
- To stop streaming, terminate the process (SIGTERM/SIGINT) or run
unsubscribe explicitly. - Module lifecycle is subscription-driven: modules start when at least one active subscription needs them, and stop when subscriptions end.
- For inference URIs, accuracy is highest while actively subscribed (stream-warm state). One-off
read may be cold-start and less accurate briefly. - On reconnect, the server sends a
session/reconnect marker that includes sessionId, gap_ms, and ts. - After reconnect, each subscribed/re-subscribed resource receives bounded replay (up to last 64 buffered updates since disconnect window), then one fresh snapshot, then normal live updates.
List all available resources
CODEBLOCK18
Acting Through the Phone
Call a tool
CODEBLOCK19
Output on success:
CODEBLOCK20
Output on failure:
CODEBLOCK21
Available tools
haptic/pulse - Single vibration
node {baseDir}/scripts/vagus-connect.js call haptic/pulse '{"durationMs":200}'
Parameters:
durationMs (10-5000, optional; default device value)
haptic/pattern - Custom vibration pattern
node {baseDir}/scripts/vagus-connect.js call haptic/pattern '{"pattern":[0,120,80,120]}'
Parameters:
pattern (array of integer durations in ms, optional; default device pattern)
speak - Text-to-speech through phone speaker
node {baseDir}/scripts/vagus-connect.js call speak '{"text":"You have a meeting in 10 minutes"}'
Parameters:
text (string max 5000 chars, required),
language (BCP 47 tag, optional),
rate (0.25-2.0, optional),
pitch (0.5-2.0, optional),
interrupt (boolean, optional)
notify - Push notification
node {baseDir}/scripts/vagus-connect.js call notify '{"title":"Reminder","body":"Check your email"}'
Parameters:
title (string max 200 chars, required),
body (string max 1000 chars, required)
clipboard/set - Write to clipboard
node {baseDir}/scripts/vagus-connect.js call clipboard/set '{"content":"https://example.com"}'
Parameters:
content (string max 10000 chars, required)
sms/send - Send an SMS message
node {baseDir}/scripts/vagus-connect.js call sms/send '{"to":"+15145551212","body":"Running 10 minutes late"}'
Parameters:
to (string phone number in local or E.164 format, required),
body (string max 2000 chars, required)
intent/open_url - Open a URL in browser
node {baseDir}/scripts/vagus-connect.js call intent/open_url '{"url":"https://withvagus.com"}'
Parameters:
url (string http/https URL, required)
calendar/create_event - Create a calendar event on device
node {baseDir}/scripts/vagus-connect.js call calendar/create_event '{"title":"Team Sync","startTimeMs":1771693200000,"endTimeMs":1771696800000,"location":"Zoom","description":"Weekly planning","allDay":false}'
Parameters:
title (string max 200 chars, required),
startTimeMs (integer Unix epoch ms, optional),
endTimeMs (integer Unix epoch ms, optional),
location (string max 200 chars, optional),
description (string max 2000 chars, optional),
allDay (boolean, optional)
agent/set_name - Set device-side agent identity name
node {baseDir}/scripts/vagus-connect.js call agent/set_name '{"name":"OpenClaw"}'
Parameters:
name (string, required; set to
"" to clear)
List all available tools
CODEBLOCK31
Behavioral Rules
- 1. Read
vagus://session/info before using any other resource to check what is available. - Do not read location or notifications unless the user's request is relevant to them.
- Prefer
notify over speak for non-urgent communication. - Check
vagus://device/screen before speaking, do not speak if the screen is off and the user might be sleeping. - If a resource read or tool call returns
PERMISSION_DENIED, tell the user which capability they need to enable in the VAGUS app. Do not retry. - If connection drops, run
status to check. If SESSION_EXPIRED, delete ~/.openclaw/vagus-session.json and ask for a new pairing code. - Do not poll resources in a tight loop. Read when contextually relevant.
- For inference resources, prefer a short subscription window when accuracy matters (instead of immediate one-off read after idle).
Troubleshooting
If something is not working, check in this order:
- 1.
node {baseDir}/scripts/vagus-connect.js status - is WebSocket connected? - INLINECODE73 - does session file exist?
- Ask user: "Is the VAGUS app running? Do you see the persistent notification?"
- Ask user: "Is your phone connected to the internet?"
- If nothing works:
rm ~/.openclaw/vagus-session.json and re-pair with a new code.
Full diagnostics: INLINECODE75
VAGUS - 手机MCP连接
VAGUS通过模型上下文协议(Model Context Protocol)让你能够访问用户的安卓手机。你通过运行位于{baseDir}/scripts/vagus-connect.js的连接脚本的子命令来与之交互。
关于安装位置的说明: 该技能必须位于用户的OpenClaw技能目录~/.openclaw/skills/vagus中。此目录是持久化的,并且在OpenClaw更新后仍然保留。系统级安装到/usr/local/lib/node_modules/openclaw/skills/vagus可能会在更新期间被删除,因此不推荐。
所有命令每行输出一个JSON对象(JSONL格式)。解析输出以获取结构化数据。
连接管理
检查是否已配对
bash
cat ~/.openclaw/vagus-session.json 2>/dev/null
如果文件存在且包含session_token,你可以直接连接。如果没有,则需要先配对。
与手机配对(首次)
询问用户:在你的手机上打开VAGUS应用,然后点击生成代码。6位字符的代码是什么?
然后运行:
bash
node {baseDir}/scripts/vagus-connect.js pair
如果{baseDir}未设置或脚本未找到,请确保技能已正确安装在~/.openclaw/skills/vagus目录中(参见README)。
成功时的输出:
json
{type:paired,sessiontoken:...,devicemodel:...,vagus_version:...}
{type:capabilities,resources:[...],tools:[...]}
失败时的输出:
json
{type:error,code:PAIR_FAILED,message:...}
如果配对失败,请让用户检查VAGUS应用是否正在运行,并生成一个新的代码。
设置代理身份名称(安装/配对后必需)
在成功pair(或首次成功connect于全新安装后)之后,将设备端的代理名称设置为你自己的身份名称。
运行:
bash
node {baseDir}/scripts/vagus-connect.js call agent/setname {name:NAME>}
如果需要清除已存储的名称:
bash
node {baseDir}/scripts/vagus-connect.js call agent/set_name {name:}
连接(已配对)
bash
node {baseDir}/scripts/vagus-connect.js connect
输出:
json
{type:connected,devicemodel:...,vagusversion:...}
{type:capabilities,resources:[...],tools:[...]}
如果会话令牌已过期或无效:
json
{type:error,code:SESSION_EXPIRED,message:...}
删除会话文件并重新配对:
bash
rm ~/.openclaw/vagus-session.json
然后向用户索要一个新的配对码。
检查状态
bash
node {baseDir}/scripts/vagus-connect.js status
输出:
json
{type:status,connected:true,devicemodel:...,activemodules:[...],subscriptions:[...],uptime_s:3600}
或者如果已断开连接:
json
{type:status,connected:false,lasterror:...,reconnectattempts:3}
读取手机状态
读取资源(一次性)
bash
node {baseDir}/scripts/vagus-connect.js read vagus://sensors/motion
输出:
json
{type:resource,uri:vagus://sensors/motion,data:{ax:0.38801706,ay:-0.26395237,az:0.86320007,gx:0.89825606,gy:0.7034855,gz:-0.21225691,ts:1771626476045}}
可用资源
| URI | 说明 |
|---|
| vagus://sensors/motion | 原始运动遥测数据(加速度计/陀螺仪向量) |
| vagus://sensors/activity |
活动识别状态和置信度 |
| vagus://sensors/activity_recognition | 活动识别状态和置信度(兼容别名) |
| vagus://sensors/location | 纬度/经度、精度、速度、海拔、提供者。需要在应用中授予位置权限 |
| vagus://sensors/environment | 从传感器/活动/连接性/时间推断出的环境上下文,以及支持证据 |
| vagus://inference/attention | 从屏幕/锁定状态、活动、充电状态和本地时间推断出的注意力可用性 |
| vagus://inference/indoor_confidence | 从环境传感器、连接性和活动推断出的室内概率 |
| vagus://inference/sleep_likelihood | 从时间、屏幕/锁定状态、活动、光线和充电状态推断出的睡眠可能性/概率 |
| vagus://inference/notification_timing | 从注意力、睡眠可能性、活动和上下文推断出的通知时机适宜性 |
| vagus://device/battery | 电池百分比和充电状态 |
| vagus://device/connectivity | 网络上下文(传输方式、验证状态、计费/漫游、运营商) |
| vagus://device/screen | 屏幕开/关和锁定状态 |
| vagus://device/notifications | 传入通知流。需要在应用中授予通知权限 |
| vagus://device/clipboard | 当前剪贴板文本。需要在应用中授予剪贴板权限 |
| vagus://session/info | 活动模块、设备型号、安卓版本、连接时间 |
始终先读取vagus://session/info以查看哪些模块处于活动状态。如果某个模块不在active_modules中,请不要尝试读取其资源,否则将因权限错误而失败。
订阅持续更新
bash
node {baseDir}/scripts/vagus-connect.js subscribe vagus://sensors/motion
这将随着更新的发生而流式传输更新,每次更新一行JSON:
json
{type:update,uri:vagus://sensors/motion,data:{ax:0.12,ay:-0.04,az:0.98,gx:0.01,gy:0.02,gz:-0.01,ts:1771626476045}}
{type:update,uri:vagus://sensors/motion,data:{ax:0.20,ay:-0.10,az:0.92,gx:0.03,gy:0.05,gz:-0.02,ts:1771626477045}}
取消订阅:
bash
node {baseDir}/scripts/vagus-connect.js unsubscribe vagus://sensors/motion
订阅在OpenClaw中的工作方式
- - subscribe是一个长时间运行的命令。在需要更新时,代理应保持exec进程存活。
- 脚本在更新到达时,每行在标准输出上发出一个JSON对象(type: update)。
- OpenClaw直接从正在运行的进程输出流接收这些JSONL行。
- 要停止流式传输,终止进程(SIGTERM/SIGINT)或显式运行unsubscribe。
- 模块生命周期由订阅驱动:当至少有一个活动订阅需要它们时,模块启动;当订阅结束时,模块停止。
- 对于推理URI,在积极订阅(流预热状态)时精度最高。一次性read可能是冷启动,短时间内精度较低。
- 重新连接时,服务器发送一个session/reconnect标记,包含sessionId、gap_ms和ts。
- 重新连接后,每个已订阅/重新订阅的资源都会收到有限的重放(自断开窗口以来最多64个缓冲更新),然后是一个新的快照,然后是正常的实时更新。
列出所有可用资源
bash
node {baseDir}/scripts/vagus-connect.js list-resources
通过手机执行操作
调用工具
bash
node {baseDir}/scripts/vagus-connect.js call
成功时的输出:
json
{type:result,tool:notify,success:true,data:{...}}
失败时的输出:
json
{type:result,tool:notify,success:false,error:PERMISSION_DENIED,message:...}
可用工具
haptic/pulse - 单次振动
bash
node {baseDir}/scripts/vagus-connect.js call haptic/pulse {durationMs:200}
参数:durationMs(10-5000,可选;默认设备值)
haptic/pattern - 自定义振动模式
bash
node {baseDir}/scripts/vagus-connect.js call haptic/pattern {pattern:[0,120,80,120]}
参数:pattern(整数持续时间数组,单位为毫秒,可选;默认设备模式)
speak - 通过手机扬声器进行文本转语音
bash
node {baseDir}/scripts/vagus-connect