Skip to content

Connecting Machines

Society agents don’t automatically discover each other. The registry is what makes agents aware of one another — it maps agent names to their connection details (URL + transport config).

This guide walks through connecting agents across a local machine and a remote server step by step.

Society assumes all machines in your network are trusted — agents process any incoming message without authentication. See Trust model for details.

┌──────────────────┐ ┌──────────────────┐
│ Local Machine │ │ Remote Server │
│ │ │ │
│ echo :8001 │◄──SSH────▸│ claude :8003 │
│ greeter :8002 │ tunnel │ echo :8001 │
│ │ │ │
│ registry.json │ │ registry.json │
└──────────────────┘ └──────────────────┘

Each machine has its own registry. To talk to a remote agent, you register it locally with the right transport config.

On the remote server:

Terminal window
# Copy binary (if not already installed)
scp society user@server:~/.local/bin/society
# SSH in and start agents
ssh user@server
cd /path/to/society
society daemon start

On the local machine:

Terminal window
society daemon start

Use onboard to add the remote agent to your local registry:

Terminal window
society onboard
Agent name: server-claude
Description: Claude on remote server
Transport [http/ssh/docker/stdio] (http): ssh
SSH host: server
SSH user: user
SSH key path: ~/.ssh/id_ed25519
SSH port (22): 22
Agent port on remote host (8080): 8003
Skills (comma-separated IDs, or empty): code, general
Added "server-claude" to registry

Now you can send messages to it:

Terminal window
society send server-claude "what OS are you running on?"

The message flows: local CLI -> SSH tunnel -> server:8003 -> Claude Code -> response back.

Step 3: Register local agents on the remote (optional)

Section titled “Step 3: Register local agents on the remote (optional)”

If you want the remote server to talk back to your local agents, SSH into the server and register them there:

Terminal window
ssh user@server
cd /path/to/society
society onboard
Agent name: laptop-echo
Transport: ssh
SSH host: laptop # or IP/hostname
SSH user: you
SSH key path: ~/.ssh/id_ed25519
Agent port: 8001

If the remote machine has CLI tools like claude or codex installed but you don’t want to run a Society daemon there, use the ssh-exec transport. It SSHes in, runs the command, and returns the output.

Auto-detect with deep scan:

Terminal window
society onboard --deep

This scans all hosts from your ~/.ssh/config and Tailscale peers, finds installed CLIs automatically, and detects live A2A agents. If multiple SSH config entries point to the same machine (e.g., different hostnames resolving to the same IP), they’re grouped and you pick your preferred route.

Manual registration:

Terminal window
society onboard --manual
Agent name: server-claude
Transport: ssh-exec
SSH host: my-server
SSH user: deploy
SSH key path: ~/.ssh/id_ed25519
Remote command: /usr/local/bin/claude

Now society send server-claude "hello" SSHes in and runs Claude directly.

If both machines are on Tailscale, you can use Tailscale hostnames directly:

Terminal window
society onboard --manual
Agent name: arch-claude
Transport: ssh # or ssh-exec
SSH host: arch # Tailscale hostname
SSH user: luis
SSH key path: ~/.ssh/id_ed25519
Agent port: 8003 # for ssh tunnel transport

Or if the Tailscale network allows direct HTTP:

Agent name: arch-claude
Transport: http
URL: http://arch:8003 # Tailscale resolves this

The SSH transports are preferred because they work even when the remote machine’s ports aren’t directly exposed.

Both SSH transports require an SSH server on the remote host. macOS has sshd disabled by default. To enable it:

  • Option 1: macOS Remote Login — System Settings > General > Sharing > Remote Login
  • Option 2: Tailscale SSHsudo tailscale set --ssh (more secure, Tailscale-only access). Note: this does not work with the App Store version of Tailscale — you need the standalone build.

Instead of manually onboarding each agent, you can export a registry from one machine and import it on another.

On the server:

Terminal window
society export --output /tmp/server-agents.json

Copy and import on local:

Terminal window
scp user@server:/tmp/server-agents.json .
society import server-agents.json

The import command will prompt for transport config for each agent, since transport details differ per machine (paths, hostnames, etc.).

If an agent is already running and reachable, you can discover it by URL:

Terminal window
society discover http://server:8001
Found agent:
Name: echo
Description: Echoes messages back
Skills: echo
Add to registry? [Y/n] y
Transport [http/ssh/docker/stdio]: http
Added "echo" to registry

This fetches the agent card from /.well-known/agent-card.json and registers it.

Terminal window
# Check what's registered
society list
# Health-check a specific agent
society ping server-claude

The ping command opens the transport, sends a test message, and reports latency. If it fails, you know the transport config or the remote agent is the issue.