
Company News
Free Business Plan Upgrades for Open Source Maintainers
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.
@dcprotocol/relay
Advanced tools
Encrypted message relay for DCP - enables cloud MCP clients to reach local vaults
Encrypted message relay for DCP - enables cloud MCP clients to securely communicate with local vaults.
This is the same relay software used for the default public relay at wss://relay.dcp.1ly.store. Running your own relay is fully supported.
The DCP Relay is a message bus that routes encrypted requests between cloud MCP clients (like Claude.ai, ChatGPT) and local DCP vaults. The relay never sees plaintext data - it only handles routing of opaque encrypted payloads.
request_id/metrics endpoint for monitoringnpm install @dcprotocol/relay
# Start relay on default port (8421)
npx -y @dcprotocol/relay
# With options
npx -y @dcprotocol/relay --port 9000 --debug
If you self-host, point Desktop, @dcprotocol/client, dcp connect, or @dcprotocol/proxy at your own relay URL instead of the public one.
import { RelayServer } from '@dcprotocol/relay';
const relay = new RelayServer({
port: 8421,
host: '0.0.0.0',
debug: true,
enableLongPoll: true,
});
await relay.start();
console.log('Relay running on port 8421');
// Graceful shutdown
process.on('SIGINT', () => relay.stop());
All messages follow this envelope format:
{
"version": "1",
"vault_id": "vault_abc123",
"request_id": "req_xyz789",
"action_type": "sign",
"encrypted_payload": "<base64-encoded-hpke-ciphertext>",
"expires_at": "2026-03-05T12:00:00Z"
}
sign - Signing operations (tx, message, x402, typed data)read - Read operationswrite - Write operationsbudget - Budget checks// Register vault (authenticated)
{
type: 'register',
payload: {
vault_id: string,
public_key: string,
signing_public_key: string,
timestamp: string,
nonce: string,
signature: string,
pairing_token?: string,
}
}
// Heartbeat
{ type: 'heartbeat', payload: { vault_id: string } }
// Request (relay -> vault)
{ type: 'request', payload: RelayEnvelope }
// Response (vault -> relay)
{ type: 'response', payload: RelayResponseEnvelope }
| Endpoint | Method | Description |
|---|---|---|
/health | GET | Health check |
/stats | GET | Relay statistics |
/metrics | GET | Detailed metrics (JSON or Prometheus format) |
/relay/request | POST | Submit request to vault (requires pairing token when enabled) |
/relay/response/:requestId | GET | Poll for response |
/relay/poll | POST | Long-poll for vault (fallback) |
/relay/respond | POST | Submit response (fallback) |
| Endpoint | Description |
|---|---|
/ws | Vault connections (authenticated) |
/ws-client | Client/agent connections |
RELAY_UNAVAILABLE, RELAY_TIMEOUT, RELAY_UNAUTHORIZEDWhen pairing tokens are enabled, clients must include one of:
Authorization: Bearer <pairing_token>X-DCP-PAIRING-TOKEN: <pairing_token>interface RelayConfig {
port: number; // Default: 8421
host: string; // Default: '0.0.0.0'
enableLongPoll: boolean; // Default: true
heartbeatIntervalMs: number; // Default: 30000
messageTtlMs: number; // Default: 300000 (5 minutes)
maxPendingMessages: number; // Default: 100 per vault
debug: boolean; // Default: false
rateLimitPerMinute: number; // Default: 60 requests per vault per minute
rateLimitWindowMs: number; // Default: 60000 (1 minute)
}
| Variable | Description | Default |
|---|---|---|
DCP_RELAY_PORT | Port to listen on | 8421 |
DCP_RELAY_HOST | Host to bind to | 0.0.0.0 |
DCP_RELAY_DEBUG | Enable debug logging | false |
DCP_RELAY_RATE_LIMIT | Max requests per vault per minute | 60 |
| Code | Description |
|---|---|
RELAY_UNAVAILABLE | Relay server not available |
RELAY_TIMEOUT | Request timed out |
RELAY_UNAUTHORIZED | Not authorized |
RELAY_INVALID_ENVELOPE | Invalid message format |
RELAY_VAULT_NOT_CONNECTED | Target vault not connected |
RELAY_DUPLICATE_REQUEST | Duplicate request_id |
RELAY_MESSAGE_EXPIRED | Message TTL exceeded |
RELAY_RATE_LIMITED | Too many requests (429) |
The relay enforces per-vault rate limits to prevent abuse. When a vault exceeds its limit, subsequent requests receive a 429 response with:
{
"error": {
"code": "RELAY_RATE_LIMITED",
"message": "Rate limit exceeded for vault vault_abc123. Try again in 45 seconds.",
"details": {
"vault_id": "vault_abc123",
"limit": 60,
"window_ms": 60000,
"retry_after_ms": 45000
}
}
}
Rate limit headers are included in all responses:
X-RateLimit-Limit: Max requests per windowX-RateLimit-Remaining: Remaining requestsX-RateLimit-Reset: Seconds until reset (on 429)Retry-After: Seconds to wait before retry (on 429)The /metrics endpoint provides detailed relay statistics:
# JSON format (default)
curl http://localhost:8421/metrics
# Prometheus format
curl http://localhost:8421/metrics?format=prometheus
dcp_relay_messages_total
dcp_relay_messages_pending
dcp_relay_messages_delivered
dcp_relay_vaults_connected
dcp_relay_vaults_tracked
dcp_relay_rate_limit_max
dcp_relay_ws_clients
FROM node:20-alpine
WORKDIR /app
RUN npm install -g @dcprotocol/relay
EXPOSE 8421
CMD ["dcp-relay", "--host", "0.0.0.0"]
version: '3.8'
services:
relay:
image: node:20-alpine
working_dir: /app
command: npx -y @dcprotocol/relay
ports:
- "8421:8421"
environment:
- DCP_RELAY_PORT=8421
- DCP_RELAY_RATE_LIMIT=60
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8421/health"]
interval: 30s
timeout: 5s
retries: 3
[Unit]
Description=DCP Relay Server
After=network.target
[Service]
Type=simple
User=dcp
ExecStart=/usr/bin/npx -y @dcprotocol/relay --port 8421
Restart=always
RestartSec=5
Environment=NODE_ENV=production
Environment=DCP_RELAY_RATE_LIMIT=60
[Install]
WantedBy=multi-user.target
DCP_RELAY_RATE_LIMIT based on expected traffic/metrics?format=prometheus with Prometheus/health endpoint for load balancer health checks--debug for troubleshooting, disable in productionupstream dcp_relay {
server 127.0.0.1:8421;
}
server {
listen 443 ssl http2;
server_name relay.dcp.1ly.store;
ssl_certificate /etc/letsencrypt/live/relay.dcp.1ly.store/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/relay.dcp.1ly.store/privkey.pem;
location / {
proxy_pass http://dcp_relay;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}
Apache-2.0
FAQs
Encrypted message relay for DCP - enables cloud MCP clients to reach local vaults
The npm package @dcprotocol/relay receives a total of 16 weekly downloads. As such, @dcprotocol/relay popularity was classified as not popular.
We found that @dcprotocol/relay demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.