<!-- source: https://deepwiki.com/openclaw/openclaw/6.2-device-node-protocol -->

# Device Node Protocol

- apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayProtocol.kt
- apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift
- apps/shared/OpenClawKit/Sources/OpenClawProtocol/WakeParamsCompatibility.swift
- docs/concepts/session-tool.md
- docs/gateway/protocol.md
- extensions/diffs/src/tool.test.ts
- extensions/diffs/src/tool.ts
- scripts/protocol-gen-swift.ts
- scripts/repro/session-status-run-session-key-live-proof.mjs
- src/agents/model-catalog.runtime.ts
- src/agents/model-ref-shared.test.ts
- src/agents/model-ref-shared.ts
- src/agents/model-selection.plugin-runtime.test.ts
- src/agents/openclaw-tools.session-status.test.ts
- src/agents/schema/typebox.ts
- src/agents/tools/common.params.test.ts
- src/agents/tools/common.ts
- src/agents/tools/nodes-tool-commands.ts
- src/agents/tools/nodes-tool-media.ts
- src/agents/tools/nodes-tool.test.ts
- src/agents/tools/nodes-tool.ts
- src/agents/tools/session-status-tool.ts
- src/agents/tools/sessions-history-tool.test.ts
- src/agents/tools/sessions-history-tool.ts
- src/agents/tools/sessions-list-tool.test.ts
- src/agents/tools/sessions-list-tool.ts
- src/agents/tools/subagents-tool.test.ts
- src/agents/tools/subagents-tool.ts
- src/auto-reply/reply/directive-handling.defaults.ts
- src/cli/system-cli.test.ts
- src/config/config.agent-concurrency-defaults.test.ts
- src/config/cron-limits.ts
- src/config/defaults.test.ts
- src/config/defaults.ts
- src/config/io.write-prepare.test.ts
- src/config/io.write-prepare.ts
- src/config/materialize.ts
- src/config/model-alias-defaults.test.ts
- src/cron/service.ts
- src/cron/service/ops.ts
- src/infra/parse-finite-number.test.ts
- src/infra/parse-finite-number.ts
- src/plugin-sdk/channel-actions.ts
- src/plugin-sdk/number-runtime.ts
- src/plugin-sdk/param-readers.ts
- src/plugin-sdk/string-coerce-runtime.ts
- src/plugins/provider-auth-choice-helpers.test.ts
- src/plugins/provider-auth-choice-helpers.ts
- src/shared/number-coercion.ts

The Device Node Protocol defines the secure communication and RPC method handling between the OpenClaw Gateway and native device clients (referred to as nodes). These nodes run on platforms such as iOS, Android, and macOS, exposing low-level device capabilities (camera, screen capture, notifications, etc.) for AI agents via the Gateway. This protocol is essential for extending the personal AI assistant's ability to interact with the user's physical devices safely and efficiently.

## Protocol Overview

Device nodes connect to the Gateway via the Gateway WebSocket protocol (v4) [apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift5-6](https://github.com/openclaw/openclaw/blob/fbdf5937/apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift#L5-L6) The connection uses the `role: "node"` parameter in the `ConnectParams` struct to designate it as a node connection [apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift57](https://github.com/openclaw/openclaw/blob/fbdf5937/apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift#L57-L57)

### Node Connection Flow

The connection flow involves a handshake, identity verification, and an optional pairing phase if the device is not already recognized. Nodes declare their hardware capabilities (e.g., `camera`, `voice`) and supported commands (e.g., `camera.snap`) during the `connect` handshake [docs/gateway/protocol.md198-199](https://github.com/openclaw/openclaw/blob/fbdf5937/docs/gateway/protocol.md?plain=1#L198-L199)

Title: Node Connection and Pairing Sequence

```

```

Sources: [apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift49-109](https://github.com/openclaw/openclaw/blob/fbdf5937/apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift#L49-L109) [docs/gateway/protocol.md182-213](https://github.com/openclaw/openclaw/blob/fbdf5937/docs/gateway/protocol.md?plain=1#L182-L213) [apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift153-207](https://github.com/openclaw/openclaw/blob/fbdf5937/apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift#L153-L207)

## Node Role & Authorization

Nodes connect to the Gateway with specific claims. This restricts them to a specific subset of RPC methods and enforces a strict cryptographically-backed authorization model.

### Node-Specific RPC Methods

The Gateway maintains a set of methods specifically for the `node` role. These are enforced during the handshake and subsequent message handling.

Sources: [apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift40-47](https://github.com/openclaw/openclaw/blob/fbdf5937/apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift#L40-L47) [docs/gateway/protocol.md111-116](https://github.com/openclaw/openclaw/blob/fbdf5937/docs/gateway/protocol.md?plain=1#L111-L116) [apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift23-30](https://github.com/openclaw/openclaw/blob/fbdf5937/apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift#L23-L30)

## Device Pairing & Identity

Nodes must be **paired** with the Gateway to receive commands. Pairing establishment establishes a trust relationship between the Gateway and the hardware device.

### Pairing Flow Implementation

1. Handshake : Nodes provide a device object containing a publicKey , signature , and nonce docs/gateway/protocol.md 63-69
2. Request : If unpaired, the node calls node.pair.request . The Gateway registers the intent and emits a node.pair.requested event.
3. Approval : An operator approves the request. Upon approval, a deviceToken is issued in the hello-ok.auth payload docs/gateway/protocol.md 142-148
4. Verification : The node completes the flow by calling node.pair.verify .

### Presence Reporting

The `NodePresenceAliveReason` enum allows nodes to specify why they are waking up, such as `bg_app_refresh`, `significant_location`, or `silent_push` [apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift40-47](https://github.com/openclaw/openclaw/blob/fbdf5937/apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift#L40-L47) This is processed via the Gateway health state to update global presence in `PresenceEntry` [apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift239-256](https://github.com/openclaw/openclaw/blob/fbdf5937/apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift#L239-L256)

Sources: [apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift40-47](https://github.com/openclaw/openclaw/blob/fbdf5937/apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift#L40-L47) [docs/gateway/protocol.md138-168](https://github.com/openclaw/openclaw/blob/fbdf5937/docs/gateway/protocol.md?plain=1#L138-L168) [apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift239-256](https://github.com/openclaw/openclaw/blob/fbdf5937/apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift#L239-L256)

## Node Invocation Protocol ( node.invoke )

The core interactive mechanism for remote device commands is the `node.invoke` RPC method. This permits the Gateway or agents to control device-specific capabilities remotely.

### Execution Policy

When an agent calls `node.invoke`, the Gateway routes the request to the target node. The Gateway enforces command policies, ensuring that the node has declared the capability and that the command is allowed for the node's current pairing state.

### System Run (Exec) Commands on Nodes

Exec approvals are the guardrail for letting a sandboxed agent run commands on a real host node.

- Validation : The Gateway reconciles node pairings on connect to ensure that only approved nodes can receive sensitive execution requests.
- Approvals : Node execution requests often require an ExecApprovalRequestParams frame which includes requireDeliveryRoute scripts/protocol-gen-swift.ts 79

Title: Mapping Protocol Entities to Code Logic

```

```

Sources: [apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift40-237](https://github.com/openclaw/openclaw/blob/fbdf5937/apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift#L40-L237) [scripts/protocol-gen-swift.ts185-223](https://github.com/openclaw/openclaw/blob/fbdf5937/scripts/protocol-gen-swift.ts#L185-L223) [src/agents/tools/nodes-tool.ts84-145](https://github.com/openclaw/openclaw/blob/fbdf5937/src/agents/tools/nodes-tool.ts#L84-L145)

## Node-Specific Tools & Capabilities

### Camera, Screen, and Notifications

Nodes declare capabilities like `camera`, `screen`, and `voice` in the `caps` array [docs/gateway/protocol.md198](https://github.com/openclaw/openclaw/blob/fbdf5937/docs/gateway/protocol.md?plain=1#L198-L198) The `createNodesTool` function provides an agent interface to these actions [src/agents/tools/nodes-tool.ts125-145](https://github.com/openclaw/openclaw/blob/fbdf5937/src/agents/tools/nodes-tool.ts#L125-L145)

### Action Handling

The `nodes` tool handles various actions including:

- Media : camera_snap , camera_clip , screen_record src/agents/tools/nodes-tool.ts 32-36
- System : location_get , notifications_list , device_status src/agents/tools/nodes-tool.ts 37-40
- Pairing : approve , reject , pending src/agents/tools/nodes-tool.ts 28-30

### Canvas and Plugin Surfaces

Nodes can host interactive "Canvases" or other plugin-driven UIs.

- Surface Refresh : Nodes use node.pluginSurface.refresh to receive fresh, scoped URLs for surfaces like canvas docs/gateway/protocol.md 111-116
- AnyCodable : Swift models use AnyCodable for flexible plugin-specific parameters and responses apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift 52

### Numeric Coercion in Node Tools

When node-specific tools (like timers or capture intervals) receive input, the system uses the `normalization-core` utilities to ensure safety:

- Timeouts : durationMs for screen recording is capped at 300,000ms (5 minutes) in the tool schema src/agents/tools/nodes-tool.ts 105
- Limits : photos_latest is capped at 20 src/agents/tools/nodes-tool.ts 103
- Safety : asSafeIntegerInRange and asPositiveSafeInteger are used to sanitize tool inputs src/agents/tools/common.ts 3-6

Sources: [docs/gateway/protocol.md111-213](https://github.com/openclaw/openclaw/blob/fbdf5937/docs/gateway/protocol.md?plain=1#L111-L213) [apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift52](https://github.com/openclaw/openclaw/blob/fbdf5937/apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift#L52-L52) [src/agents/tools/nodes-tool.ts84-123](https://github.com/openclaw/openclaw/blob/fbdf5937/src/agents/tools/nodes-tool.ts#L84-L123) [src/agents/tools/common.ts1-20](https://github.com/openclaw/openclaw/blob/fbdf5937/src/agents/tools/common.ts#L1-L20)

## Node Command Policies

The Gateway enforces strict policies on which commands a node can execute.

- Scope Gating : Commands are checked against negotiated scopes. Approving a node pairing requires resolving necessary scopes via resolveNodePairApprovalScopes src/agents/tools/nodes-tool.ts 7
- Protocol Versioning : Both client and server negotiate protocol versions (current version: 4) to ensure compatibility of RPC signatures apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift 5-6
- Startup Protection : While the Gateway is finishing startup sidecars, the connect request can return a retryable UNAVAILABLE error docs/gateway/protocol.md 100-104

Sources: [apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift5-6](https://github.com/openclaw/openclaw/blob/fbdf5937/apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift#L5-L6) [docs/gateway/protocol.md100-104](https://github.com/openclaw/openclaw/blob/fbdf5937/docs/gateway/protocol.md?plain=1#L100-L104) [src/agents/tools/nodes-tool.ts7-81](https://github.com/openclaw/openclaw/blob/fbdf5937/src/agents/tools/nodes-tool.ts#L7-L81)
