Module 7: Remote Control and CLAUDE.md for Teams
2. Remote Control — Setup, Sessions, and Control from Mobile Devices
2. Remote Control — Setup, Sessions, and Control from Mobile Devices
Description
So far, supervising Claude Code means being in front of your terminal. If an Agent Team is running a 40-minute refactor, you have two options: keep watching the screen or leave and lose all visibility into what's happening. Remote control changes that dynamic — it lets you connect to active Claude Code sessions from another device to monitor progress, see which files are being edited, and keep control without being physically at your computer.
This capsule covers the complete technical setup: how to enable remote control, how to connect devices, how to monitor sessions in real time, and the security considerations you need before exposing sessions to remote access. By the end, you'll be able to launch an Agent Team on your machine, leave, and check the status from your phone.
Experimental status (March 2026): Remote control is a feature in active development in Claude Code. The APIs and commands described in this capsule are based on the documentation and functionality available as of March 2026. Verify the current availability at docs.anthropic.com/en/docs/claude-code before implementing. Some commands may have been renamed or require additional flags.
Understanding Remote Control
The conceptual model
Remote control doesn't create a new session — it connects to an existing session. Your Claude Code keeps running on your machine. The remote control is a read (and optionally write) window into that session from another place.
Your machine (where Claude Code runs)
┌─────────────────────────────────────┐
│ Claude Code Session (active) │
│ ├── Agent Team running │
│ ├── Active hooks │
│ └── SDK scripts running │
│ │
│ Remote Control Server (local) │
│ └── Exposes an API for connections │
└──────────────┬──────────────────────┘
│ (secure connection)
│
┌──────────────┴──────────────────────┐
│ Your phone / another device │
│ ├── See session state │
│ ├── See edited files │
│ ├── Approve/reject operations │
│ └── Send commands │
└─────────────────────────────────────┘
What you can do remotely
| Capability | Description | Requires |
|---|---|---|
| Monitor | See the current state of the session, edited files, executed commands | Read-only |
| Approve/Reject | Respond to hook PermissionRequests | Limited write |
| View Agent Team | The state of each teammate — in progress, completed, failed | Read-only |
| Send message | Send an additional instruction to the session | Write |
| Interrupt | Cancel the current execution | Write |
Remote access: available methods
Claude Code offers multiple ways of remote access:
Method 1: claude.ai Web Interface
→ Connect a Claude Code session to the web interface
→ Requires an authenticated Anthropic account
→ Best for visual monitoring
Method 2: CLI from another terminal/machine
→ Connect via SSH + claude session commands
→ Best for developers who prefer the terminal
Method 3: SDK API (programmatic)
→ Use the SDK from scripts to query the state
→ Best for custom dashboards and automation
Enabling Remote Control
Step 1: Verify support
claude --version
claude --help | grep -i remote
If remote doesn't appear in the help, your version may not support this feature yet. Update:
npm update -g @anthropic-ai/claude-code
Step 2: Configure remote access
The remote control configuration is done at the project or user settings level:
{
"remote": {
"enabled": true,
"require_auth": true,
"allowed_operations": ["monitor", "approve", "reject", "interrupt"],
"session_visibility": "authenticated"
}
}
Save this in .claude/settings.json (project level) or ~/.claude/settings.json (user level).
Step 3: Start a session with remote control enabled
claude --remote
# Or with explicit configuration:
claude --remote --remote-port 3500
When the session starts with --remote, Claude Code:
- Starts the remote control server on a local port
- Generates a temporary authentication token
- Shows the URL and token to connect
Remote control enabled.
Connect URL: https://claude.ai/remote/session/abc123
Auth token: rc_tk_xxxxxxxxxxxxxxxx
Step 4: Connect from another device
From the web browser:
Open the provided URL, enter the authentication token, and you'll see the session dashboard in real time.
From another terminal (same machine or SSH):
claude remote connect --session abc123 --token rc_tk_xxxxxxxxxxxxxxxx
From the SDK (programmatic):
import subprocess
import json
result = subprocess.run(
["claude", "remote", "status", "--session", "abc123",
"--token", "rc_tk_xxxxxxxxxxxxxxxx",
"--output-format", "json"],
capture_output=True, text=True
)
status = json.loads(result.stdout)
print(f"State: {status['state']}")
print(f"Edited files: {status['files_changed']}")
print(f"Pending operations: {status['pending_approvals']}")
Real-Time Session Monitoring
Session state
Once connected, you can query the session state:
claude remote status --session abc123 --output-format json
Typical response:
{
"session_id": "abc123",
"state": "running",
"started_at": "2026-03-13T10:30:00Z",
"running_for_ms": 125000,
"current_task": "Refactoring authentication module",
"tools_used": 42,
"files_changed": [
"src/auth/login.py",
"src/auth/middleware.py",
"tests/test_auth.py"
],
"pending_approvals": [],
"agent_team": {
"team_lead": {
"state": "coordinating",
"current_task": "Reviewing teammate outputs"
},
"teammates": [
{
"name": "auth-specialist",
"state": "working",
"task": "Implementing JWT refresh"
},
{
"name": "test-writer",
"state": "waiting",
"task": "Waiting for auth changes"
}
]
},
"cost_usd": 0.0234,
"errors": []
}
Continuous monitoring
To monitor in real time (similar to tail -f):
claude remote watch --session abc123 --interval 5
This command prints the state every 5 seconds. It's especially useful for long operations where you want a constant heartbeat.
Monitoring script with Python
For a more customized dashboard:
#!/usr/bin/env python3
"""Remote monitor for Claude Code sessions."""
import subprocess
import json
import time
import sys
def get_session_status(session_id, token):
result = subprocess.run(
["claude", "remote", "status",
"--session", session_id,
"--token", token,
"--output-format", "json"],
capture_output=True, text=True
)
if result.returncode != 0:
return None
return json.loads(result.stdout)
def display_status(status):
print(f"\033[2J\033[H") # clear screen
print(f"{'='*50}")
print(f"Session: {status['session_id']}")
print(f"State: {status['state']}")
print(f"Time: {status['running_for_ms'] // 1000}s")
print(f"Cost: ${status.get('cost_usd', 0):.4f}")
print(f"{'='*50}")
if status.get('agent_team'):
team = status['agent_team']
print(f"\nAgent Team:")
print(f" Lead: {team['team_lead']['state']}")
for tm in team.get('teammates', []):
icon = "🔄" if tm['state'] == 'working' else "⏳"
print(f" {icon} {tm['name']}: {tm['task']}")
if status.get('pending_approvals'):
print(f"\n⚠️ PENDING APPROVALS:")
for approval in status['pending_approvals']:
print(f" → {approval['operation']}: {approval['description']}")
if status.get('files_changed'):
print(f"\nFiles ({len(status['files_changed'])}):")
for f in status['files_changed'][-5:]:
print(f" 📄 {f}")
def main():
if len(sys.argv) < 3:
print("Usage: python monitor.py <session_id> <token>")
sys.exit(1)
session_id = sys.argv[1]
token = sys.argv[2]
print("Connecting to remote control...")
while True:
status = get_session_status(session_id, token)
if status is None:
print("Error getting status. Retrying...")
time.sleep(10)
continue
display_status(status)
if status['state'] in ('completed', 'error', 'cancelled'):
print(f"\nSession finished: {status['state']}")
break
time.sleep(5)
if __name__ == "__main__":
main()
Monitoring Agent Teams Remotely
View the team state
When an Agent Team is active, remote control exposes the state of each teammate:
claude remote team-status --session abc123 --output-format json
{
"team_lead": {
"state": "coordinating",
"tasks_assigned": 4,
"tasks_completed": 2,
"tasks_in_progress": 1,
"tasks_pending": 1
},
"teammates": [
{
"name": "backend-dev",
"state": "working",
"current_task": "Implement user CRUD",
"files_touched": ["src/api/users.py", "src/models/user.py"],
"started_at": "2026-03-13T10:32:00Z"
},
{
"name": "test-writer",
"state": "completed",
"completed_task": "Write unit tests for auth",
"files_touched": ["tests/test_auth.py"],
"duration_ms": 45000
},
{
"name": "docs-writer",
"state": "idle",
"waiting_for": "backend-dev to complete user CRUD"
}
],
"task_board": {
"total": 4,
"completed": 2,
"in_progress": 1,
"pending": 1
}
}
Real monitoring scenarios
Scenario 1: Nightly refactor
You launch a big refactor before going to sleep:
claude --remote -p "Refactor the payments module: \
extract the Stripe logic to an adapter pattern, \
add unit tests for each adapter, \
update the documentation" \
--allowedTools "Read,Write,Edit,Grep,Glob,Bash"
From your phone, you periodically check:
- How many files has it edited?
- Has it found errors?
- Does it need any approval?
Scenario 2: CI with approval
A CI pipeline uses Claude Code to generate a changelog and create a PR. The script needs approval before pushing:
result = subprocess.run(
["claude", "--remote", "-p",
"Generate the sprint changelog and create a PR",
"--output-format", "json"],
capture_output=True, text=True,
cwd="/path/to/project"
)
You receive a notification on your phone: "Claude wants to run git push origin release/v2.3.0". You approve or reject.
Security in Remote Control
Authentication
Each remote control session generates a unique token. Without the token, there's no access:
Token format: rc_tk_[32 alphanumeric characters]
Validity: only during the life of the session
Scope: one specific session
Security principles
| Principle | Implementation |
|---|---|
| Mandatory authentication | Unique token per session, non-reusable |
| Minimum scope | The token only grants access to that session, not others |
| Automatic expiration | The token expires when the session ends |
| Limited connections | Maximum of N devices connected simultaneously |
| Audited operations | Every remote action is recorded in logs |
Advanced security configuration
{
"remote": {
"enabled": true,
"require_auth": true,
"max_connections": 3,
"allowed_operations": ["monitor", "approve", "reject"],
"log_remote_actions": true,
"session_visibility": "authenticated",
"auto_disconnect_idle_minutes": 30
}
}
What NOT to do with remote control
❌ Don't share the token on insecure channels (public Slack, unencrypted email)
❌ Don't enable remote control without require_auth on shared networks
❌ Don't grant write access if you only need monitoring
❌ Don't leave sessions with active remote control unsupervised for hours
❌ Don't use remote control over public WiFi networks without a VPN
Advanced Use Cases
Use 1: Weekend batch jobs
You configure a script that launches 5 sequential tasks on Friday night:
#!/usr/bin/env python3
"""Batch of tasks for the weekend."""
import subprocess
import json
tasks = [
"Update all pip dependencies and resolve conflicts",
"Add type hints to all the files in src/core/",
"Generate docstrings for undocumented functions in src/api/",
"Create integration tests for the /users endpoints",
"Update the README.md with the current documentation",
]
for i, task in enumerate(tasks, 1):
print(f"\n[{i}/{len(tasks)}] Running: {task[:50]}...")
result = subprocess.run(
["claude", "--remote", "-p", task,
"--output-format", "json",
"--allowedTools", "Read,Write,Edit,Grep,Glob,Bash"],
capture_output=True, text=True,
timeout=1800
)
if result.returncode == 0:
output = json.loads(result.stdout)
print(f" Cost: ${output.get('cost_usd', 0):.4f}")
else:
print(f" Error: {result.stderr[:100]}")
On Saturday morning, you check from your phone: how many tasks did it complete? Did any fail? How much did the total batch cost?
Use 2: Monitoring an Agent Team in a meeting
While you're in a meeting, your Agent Team is implementing a feature. With remote control:
- You open the dashboard on your phone under the table
- You see that the
backend-devteammate completed its task - The
test-writeris running but found 2 failing tests - The team lead reassigned a subtask
- There's a pending approval for an
npm publish— you reject it because a code review is missing
All without opening your laptop.
Use 3: Remote pair programming with agents
Your teammate is running Claude Code and wants you to review what the agent is doing. They share the session ID and the token with you. You connect from your machine and see the session in real time. If the agent is going down the wrong path, you can send a message redirecting the work.
Troubleshooting
"Remote control doesn't appear in claude --help"
Cause: Your version of Claude Code doesn't support remote control, or the feature is behind a feature flag.
Solution:
npm update -g @anthropic-ai/claude-code
claude --version
claude config list | grep remote
If the feature flag isn't enabled, check the official documentation for opt-in instructions.
"Connection refused when connecting remotely"
Cause: The remote control server isn't running, the port is occupied, or a firewall blocks the connection.
Solution:
# Verify that the session is active
claude remote list
# Verify that the port is listening
lsof -i :3500
# If the port is occupied, use another
claude --remote --remote-port 3501
"Token expired or invalid"
Cause: The token was generated for a session that already ended, or it was copied incorrectly.
Solution:
# List active sessions with their tokens
claude remote list --show-tokens
# Regenerate the token for an active session
claude remote refresh-token --session abc123
"Remote control works slowly"
Cause: The polling interval is too frequent, or the network connection has high latency.
Solution:
# Increase the polling interval
claude remote watch --session abc123 --interval 15
# Reduce the output verbosity
claude remote status --session abc123 --compact
"I can't see the Agent Team state"
Cause: Agent Teams is an experimental feature that may not expose state via remote control in all versions.
Solution: Verify that your version of Claude Code supports remote team-status. If it's not available, use remote status, which shows a general summary without a per-teammate breakdown.
Comparison: Terminal vs Remote Control
| Aspect | Local Terminal | Remote Control |
|---|---|---|
| Presence | You must be at the computer | Any device with a network |
| Latency | Instant | Depends on the connection (1-5s typical) |
| Capabilities | All | Monitoring + approval + interruption |
| Security | Implicit (physical access) | Token + authentication |
| Multiple observers | No (one terminal) | Yes (multiple devices) |
| Ideal for | Active development, debugging | Supervision, long operations |
| Agent Teams | Full control of the team lead | State view, approval |
| Hooks | Run locally | Monitored remotely |
| SDK scripts | Local execution | Local execution + remote monitoring |
| Cost | No overhead | Minimal server overhead |
Practical rule: Use the local terminal for active development (when you're iterating quickly). Use remote control for passive supervision (when you launch a job and leave).
Exercises
Exercise 1: Basic remote control setup (Easy)
Start a Claude Code session with remote control enabled. From another terminal on the same machine, connect and query the session state.
See solution
Terminal 1 — Start the session:
claude --remote
Note the session ID and the token that are shown.
Terminal 2 — Connect:
claude remote status --session <SESSION_ID> --token <TOKEN> --output-format json | jq .
You should see the session's current state: running, idle, or waiting.
If --remote isn't available in your version:
claude -p "Say 'remote control test successful'" --output-format json > /tmp/session-test.json
cat /tmp/session-test.json | jq .state
Exercise 2: Simple monitoring script (Easy)
Write a bash script that queries a session's state every 10 seconds and prints it in a readable format.
See solution
scripts/simple-monitor.sh:
#!/bin/bash
SESSION_ID=$1
TOKEN=$2
if [ -z "$SESSION_ID" ] || [ -z "$TOKEN" ]; then
echo "Usage: ./simple-monitor.sh <session_id> <token>"
exit 1
fi
while true; do
clear
echo "=== Remote Monitor ==="
echo "Session: $SESSION_ID"
echo "Time: $(date +%H:%M:%S)"
echo "========================"
STATUS=$(claude remote status \
--session "$SESSION_ID" \
--token "$TOKEN" \
--output-format json 2>/dev/null)
if [ $? -ne 0 ]; then
echo "Error connecting. Retrying..."
sleep 10
continue
fi
STATE=$(echo "$STATUS" | jq -r '.state')
COST=$(echo "$STATUS" | jq -r '.cost_usd // 0')
FILES=$(echo "$STATUS" | jq -r '.files_changed | length')
echo "State: $STATE"
echo "Cost: \$$COST"
echo "Files: $FILES"
if [ "$STATE" = "completed" ] || [ "$STATE" = "error" ]; then
echo "Session finished."
break
fi
sleep 10
done
chmod +x scripts/simple-monitor.sh
./scripts/simple-monitor.sh abc123 rc_tk_xxxxx
Exercise 3: Security configuration (Medium)
Write a settings.json configuration that enables remote control with the following restrictions:
- Maximum 2 simultaneous connections
- Only monitoring and approval operations (no sending messages)
- Automatic disconnection after 15 minutes of inactivity
- Logging of all remote actions
See solution
.claude/settings.json:
{
"remote": {
"enabled": true,
"require_auth": true,
"max_connections": 2,
"allowed_operations": ["monitor", "approve", "reject"],
"log_remote_actions": true,
"session_visibility": "authenticated",
"auto_disconnect_idle_minutes": 15
}
}
The key is in allowed_operations: by not including "message" or "interrupt", the remote observers can only view and approve/reject, not send new instructions or stop the execution. This is ideal for scenarios where a senior monitors an agent's work without intervening directly.
Exercise 4: Agent Team monitor with Python (Medium)
Write a Python script that monitors an Agent Team remotely and generates a report when all the teammates have finished.
See solution
scripts/team-monitor.py:
#!/usr/bin/env python3
"""Monitors an Agent Team and generates a report when it finishes."""
import subprocess
import json
import time
import sys
from datetime import datetime
def get_team_status(session_id, token):
result = subprocess.run(
["claude", "remote", "team-status",
"--session", session_id,
"--token", token,
"--output-format", "json"],
capture_output=True, text=True
)
if result.returncode != 0:
return None
return json.loads(result.stdout)
def all_done(status):
if not status or not status.get("teammates"):
return False
return all(
tm["state"] in ("completed", "error")
for tm in status["teammates"]
)
def generate_report(history):
report = []
report.append(f"# Agent Team Report")
report.append(f"Generated: {datetime.now().isoformat()}")
report.append(f"")
if not history:
report.append("No data collected.")
return "\n".join(report)
final = history[-1]
report.append(f"## Summary")
report.append(f"- Total teammates: {len(final.get('teammates', []))}")
completed = sum(1 for t in final.get("teammates", [])
if t["state"] == "completed")
errors = sum(1 for t in final.get("teammates", [])
if t["state"] == "error")
report.append(f"- Completed: {completed}")
report.append(f"- Errors: {errors}")
report.append(f"")
report.append(f"## Teammates")
for tm in final.get("teammates", []):
report.append(f"### {tm['name']}")
report.append(f"- State: {tm['state']}")
report.append(f"- Files: {', '.join(tm.get('files_touched', []))}")
report.append(f"")
return "\n".join(report)
def main():
if len(sys.argv) < 3:
print("Usage: python team-monitor.py <session_id> <token>")
sys.exit(1)
session_id, token = sys.argv[1], sys.argv[2]
history = []
print("Monitoring Agent Team...")
while True:
status = get_team_status(session_id, token)
if status:
history.append(status)
teammates = status.get("teammates", [])
for tm in teammates:
icon = {"working": "🔄", "completed": "✅",
"error": "❌", "idle": "⏳"}.get(tm["state"], "?")
print(f" {icon} {tm['name']}: {tm['state']}")
if all_done(status):
print("\nAll the teammates finished.")
break
time.sleep(10)
report = generate_report(history)
report_path = f"team-report-{datetime.now():%Y%m%d-%H%M%S}.md"
with open(report_path, "w") as f:
f.write(report)
print(f"Report: {report_path}")
if __name__ == "__main__":
main()
Exercise 5: Local remote control simulation (Hard)
Without access to real remote control, simulate the pattern using two processes: one that runs Claude Code with the headless SDK and writes its state to a JSON file, and another that reads that file periodically as a "remote monitor."
See solution
Process 1 — Executor (scripts/executor.sh):
#!/bin/bash
STATE_FILE="/tmp/claude-remote-sim.json"
update_state() {
cat > "$STATE_FILE" << EOF
{
"state": "$1",
"task": "$2",
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"files_changed": $3
}
EOF
}
update_state "starting" "Initializing session" "[]"
sleep 2
update_state "running" "Analyzing codebase" "[]"
RESULT=$(claude -p "List the Python files in the current directory" \
--output-format json \
--allowedTools "Bash,Glob" 2>/dev/null)
if [ $? -eq 0 ]; then
update_state "completed" "Task finished" "[\"analysis-result.json\"]"
else
update_state "error" "Task failed" "[]"
fi
echo "Execution finished. Final state in $STATE_FILE"
Process 2 — Monitor (scripts/local-monitor.sh):
#!/bin/bash
STATE_FILE="/tmp/claude-remote-sim.json"
echo "Waiting for session..."
while [ ! -f "$STATE_FILE" ]; do
sleep 1
done
echo "Session found. Monitoring..."
while true; do
clear
echo "=== REMOTE MONITOR (simulated) ==="
echo "$(date +%H:%M:%S)"
echo "================================="
if [ -f "$STATE_FILE" ]; then
STATE=$(cat "$STATE_FILE" | jq -r '.state')
TASK=$(cat "$STATE_FILE" | jq -r '.task')
FILES=$(cat "$STATE_FILE" | jq -r '.files_changed | length')
echo "State: $STATE"
echo "Task: $TASK"
echo "Files: $FILES"
fi
if [ "$STATE" = "completed" ] || [ "$STATE" = "error" ]; then
echo ""
echo "Session finished: $STATE"
break
fi
sleep 3
done
Usage:
chmod +x scripts/executor.sh scripts/local-monitor.sh
# Terminal 1:
./scripts/executor.sh
# Terminal 2 (simultaneous):
./scripts/local-monitor.sh
This pattern is exactly what remote control does internally: one process writes state, another reads it. The difference is that remote control does it over the network instead of a local file.
Exercise 6: Multi-session dashboard (Hard)
Design a Python script that monitors multiple Claude Code sessions simultaneously and shows them in a consolidated dashboard with the state of each one.
See solution
scripts/multi-monitor.py:
#!/usr/bin/env python3
"""Multi-session dashboard for Claude Code."""
import subprocess
import json
import time
import sys
def get_status(session_id, token):
try:
result = subprocess.run(
["claude", "remote", "status",
"--session", session_id,
"--token", token,
"--output-format", "json"],
capture_output=True, text=True, timeout=10
)
if result.returncode == 0:
return json.loads(result.stdout)
except (subprocess.TimeoutExpired, json.JSONDecodeError):
pass
return {"session_id": session_id, "state": "unreachable"}
def display_dashboard(sessions_status):
print("\033[2J\033[H")
print(f"{'='*60}")
print(f" CLAUDE CODE MULTI-SESSION DASHBOARD")
print(f" {time.strftime('%H:%M:%S')}")
print(f"{'='*60}\n")
for status in sessions_status:
sid = status.get("session_id", "?")[:8]
state = status.get("state", "unknown")
cost = status.get("cost_usd", 0)
files = len(status.get("files_changed", []))
pending = len(status.get("pending_approvals", []))
icon = {
"running": "🔄", "completed": "✅",
"error": "❌", "unreachable": "⚠️"
}.get(state, "?")
print(f" {icon} {sid} | {state:<12} | "
f"${cost:.4f} | {files} files | "
f"{pending} approvals")
print(f"\n{'='*60}")
def main():
sessions = []
for i in range(1, len(sys.argv), 2):
if i + 1 < len(sys.argv):
sessions.append({
"id": sys.argv[i],
"token": sys.argv[i + 1]
})
if not sessions:
print("Usage: python multi-monitor.py <id1> <tok1> [<id2> <tok2> ...]")
sys.exit(1)
while True:
statuses = [get_status(s["id"], s["token"]) for s in sessions]
display_dashboard(statuses)
if all(s.get("state") in ("completed", "error", "unreachable")
for s in statuses):
print("All the sessions finished.")
break
time.sleep(10)
if __name__ == "__main__":
main()
Summary
- Remote control lets you connect to active Claude Code sessions from other devices — your phone, another computer, or a remote script
- It's enabled with
--remotewhen starting a session, which generates an authentication token and a connection URL - The remote capabilities include monitoring state, approving/rejecting operations, viewing Agent Teams, and interrupting execution
- Real-time monitoring shows edited files, executed commands, accumulated cost, and the state of each teammate
- Security is based on per-session tokens, a connection limit, and configuration of allowed operations
- Three access methods: web interface (visual), remote CLI (terminal), programmatic SDK (scripts)
- Remote control is ideal for long operations, batch jobs, and Agent Team supervision without physical presence
- The internal pattern is simple: one process writes state, another reads it — remote control does this over the network
- Experimental status (March 2026): verify current availability in the official documentation before implementing
Additional Resources
- Claude Code Overview (Anthropic Docs) — General context of Claude Code
- Claude Code CLI Reference — CLI flags including
--remote - Claude Code Settings — Remote control configuration in settings.json
- Claude Code Hooks — Hooks monitored via remote control
- Claude Code Best Practices — Security best practices
- Claude Code Tips and Tricks — Tips for automation and monitoring
- Claude Code Agent Teams — Agent Teams monitored remotely
- Anthropic API Security — Anthropic's security principles
Next capsule: In capsule 03 you'll design remote approval flows — how to define which operations need human approval, configure approval gates with PermissionRequest hooks, approve from your phone with configurable timeouts, and define policies for when no one approves in time. You go from monitoring (capsule 02) to actively controlling (capsule 03).