Remote Agents

Run agents on VPS/cloud while keeping keys on your local machine.

💡 Quickest Setup: Desktop App

The easiest way to set up remote agents is through the DCP Desktop App:

  1. Open Desktop App → Go to "Connect" and connect to relay
  2. Go to "Run a remote agent (VPS)" section
  3. Add scopes, click "Generate pair token"
  4. Copy the command and paste it on your VPS
  5. Done! Your agent connects to http://127.0.0.1:8421

See full step-by-step guide in API docs →

How It Works

Local Machine (your keys)
    ↕ Encrypted relay
VPS (your agent)

Agent calls localhost → Proxy forwards → Your vault → Result back

Setup

1. Local: Create Pairing Token

dcp pairing start my-vps-bot \
  --scopes sign:solana,read:credentials.api.openai \
  --budget 10usdc/day \
  --auto-approve-under 1usdc

Returns pairing token and vault ID.

2. VPS: Install Proxy

npm install -g @dcprotocol/proxy

3. VPS: Start Proxy

npx @dcprotocol/proxy \
  --pair "<pairing-token>" \
  --vault "<vault-id>" \
  --relay "wss://relay.dcp.1ly.store" \
  --port 8421

4. VPS: Use as Local

Your agent on VPS calls localhost as normal. Always start with capabilities:

// First, discover what's available
const caps = await fetch("http://127.0.0.1:8421/v1/capabilities").then(r => r.json());
console.log(caps.routes); // See all available operations

// Then use the operations
const response = await fetch("http://127.0.0.1:8421/v1/vault/sign", {
  method: "POST",
  body: JSON.stringify({ chain: "solana", ... })
});

// Proxied to your local vault!

Security

  • End-to-end encrypted (HPKE with X25519)
  • Relay sees nothing (transport only)
  • Keys never leave your machine
  • Budget limits enforced locally

Self-Host Relay

Don't want to use public relay? Host your own:

npm install -g @dcprotocol/relay
npx @dcprotocol/relay --port 8421 --host 0.0.0.0

Then use your relay URL:

--relay "wss://your-domain.com:8421"

Example: Trading Bot on VPS

// bot.js on VPS
import { DcpClient } from '@dcprotocol/client';

const dcp = new DcpClient({
  mode: 'local', // Uses local proxy
  agentName: 'trading-bot'
});

setInterval(async () => {
  const price = await getPrice();
  if (shouldTrade(price)) {
    await dcp.signTransaction({
      chain: 'solana',
      amount: 1.5,
      currency: 'SOL',
      transaction: buildTx()
    });
  }
}, 60000);