Skip to Content

Multi-Client

TL;DR

CMDOP sessions support multiple concurrent client connections with two access modes: Operator (full read-write) and Observer (read-only). This enables real-time collaborative debugging between developers, AI-assisted monitoring in observer mode, seamless device switching from laptop to phone, and training/shadowing scenarios. Commands from multiple operators are processed in queue order.

CMDOP sessions support multiple concurrent client connections. This enables collaboration, AI assistance, and seamless device switching.

What is the multi-client model?

All clients see same output. Operators can send input. Observers can only watch.

What access modes are available?

What can an Operator do?

Full read-write access:

PermissionAllowed
View outputYes
Send inputYes
Execute commandsYes
File readYes
File writeYes
Resize terminalYes
Send signalsYes

What can an Observer do?

Read-only access:

PermissionAllowed
View outputYes
Send inputNo
Execute commandsNo
File readYes
File writeNo
Resize terminalNo
Send signalsNo

What are the multi-client use cases?

1. How does device switching work?

Start on laptop, continue on phone:

# Start a long-running deploy on the laptop via CLI # On laptop (CLI) await client.terminal.set_machine("prod-server") await client.terminal.execute("./deploy.sh") # Deploy starts... # Close laptop (detach, but session continues on agent) # On phone (mobile app) # Attach to same session from a different device # See deploy progress # Can send input if needed

2. How does collaborative debugging work?

Two developers on same session:

3. How does AI assistance work in a session?

Human operates, AI watches and helps:

# Human attaches as operator with full control human_stream = client.terminal.stream() await human_stream.attach(session_id) # AI attaches as observer β€” can read output but cannot send input ai_stream = client.terminal.stream(mode="observer") await ai_stream.attach(session_id) # AI callback: analyze each output chunk and send suggestions async def on_output(data): analysis = await ai.analyze(data) if analysis.has_suggestion: send_notification(analysis.suggestion) ai_stream.on_output(on_output) # Human works normally; AI suggests improvements via notifications

4. How does training / shadowing work?

Junior watches senior work:

5. How does audit / compliance observation work?

Security team monitors operations:

How does input arbitration work?

When multiple operators send input:

How is queue-based processing handled?

Commands processed in order received. Each command gets unique ID.

How does output correlation work?

# Send a command and get back a unique ID for tracking command_id = await stream.send_command("ls -la") # Wait for output tagged with the matching command ID output = await stream.wait_for_command(command_id)

How does real-time streaming work?

All operators see all output in real-time, regardless of who sent the command.

How do you use multi-client in the SDK?

How do you attach as Operator?

from cmdop import AsyncCMDOPClient async with AsyncCMDOPClient.remote(api_key="cmd_xxx") as client: # Look up the active session for a machine by hostname session = await client.terminal.get_active_session("my-server") # Open a bidirectional stream (defaults to operator mode) stream = client.terminal.stream() # Print decoded output as it arrives in real-time stream.on_output(lambda data: print(data.decode(), end="")) # Attach to the session and send a command await stream.attach(session.session_id) await stream.send_input(b"ls -la\n")

How do you attach as Observer?

# Attach in observer mode β€” read-only, cannot send input stream = client.terminal.stream(mode="observer") stream.on_output(lambda data: print(data.decode(), end="")) await stream.attach(session.session_id) # Sending input in observer mode will raise an error

How do you check attached clients?

# Retrieve session metadata including the list of all attached clients session = await client.terminal.get_session(session_id) print(f"Attached clients: {session.attached_clients}") # [ # {"user": "[email protected]", "mode": "operator", "client": "cli"}, # {"user": "[email protected]", "mode": "observer", "client": "web"}, # ]

How does authorization work for multi-client?

How does workspace-based access work?

All workspace members can attach to sessions:

# Alice and Bob are both in "acme-corp" workspace # Both can attach to any session in that workspace # Alice finds the active session for "server" session = await alice_client.terminal.get_active_session("server") # Bob can also attach β€” same workspace grants access await bob_client.terminal.attach(session.session_id)

How is role enforcement applied?

# Workspace roles determine the maximum access level for sessions # Owner/Admin: Can attach to any session as operator # Member: Can attach to any session as operator # Guest: Can only attach as observer (if configured)

What are the best practices for multi-client?

1. Use Observer Mode When Appropriate

# If you only need to watch, use observer mode to prevent accidental input stream = client.terminal.stream(mode="observer")

2. Coordinate with Team

# Check if another operator is already attached before taking over session = await client.terminal.get_session(session_id) if session.has_active_operator: # Notify the team before attaching as a second operator notify_team(f"Taking over session on {session.machine}")

3. Use AI for Non-Critical Observation

# AI observer for automated monitoring and alerting ai_stream = client.terminal.stream(mode="observer") ai_stream.on_output(detect_errors_and_alert)

4. Document Collaborative Sessions

# Enable session recording for audit and review session = await client.terminal.get_active_session( "server", record=True # Enable recording )

What are the limitations of multi-client?

Concurrent Operators

Multiple operators can send input, but:

  • Commands are queued, not merged
  • No conflict resolution
  • Last command wins for stateful operations

Observer Restrictions

Observers cannot:

  • Send any input
  • Execute commands
  • Modify files
  • Send signals
  • Change session state

Network Considerations

Each client uses bandwidth:

  • Output broadcast to all clients
  • More clients = more bandwidth on Control Plane
  • Consider observer-only for large audiences

Next

Last updated on