Configuration
All PC2 configuration options and environment variables.
Configuration File
Location: data/config/pc2.json
{
"pc2_mode": true,
"http_port": 4200,
"accessControl": {
"enabled": false,
"allowedWallets": []
},
"boson": {
"enabled": true,
"superNodes": [...]
},
"ai": {
"defaultProvider": "ollama",
"ollama": {
"baseUrl": "http://localhost:11434"
}
},
"updates": {
"autoCheck": true,
"checkInterval": 21600000
}
}Core Settings
| Key | Type | Default | Description |
|---|---|---|---|
pc2_mode | boolean | true | Enable PC2 features (vs vanilla Puter) |
http_port | number | 4200 | HTTP server port |
data_dir | string | "./data" | Data storage directory |
Access Control
{
"accessControl": {
"enabled": false,
"allowedWallets": [
{
"wallet": "0x1234...",
"role": "admin",
"addedAt": "2024-01-15T10:00:00Z"
}
]
}
}| Key | Type | Description |
|---|---|---|
enabled | boolean | Enable access control |
allowedWallets | array | List of allowed wallet entries |
allowedWallets[].wallet | string | Ethereum address (0x…) |
allowedWallets[].role | string | ”owner”, “admin”, or “member” |
allowedWallets[].addedAt | string | ISO timestamp when added |
Boson Network
{
"boson": {
"enabled": true,
"superNodes": [
{
"host": "69.164.241.210",
"dhtPort": 39001,
"proxyPort": 8090
}
],
"proxy": {
"enabled": true,
"keepaliveInterval": 30000,
"reconnectDelay": 5000
}
}
}| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable Boson integration |
superNodes | array | […] | List of super node endpoints |
proxy.enabled | boolean | true | Enable Active Proxy |
proxy.keepaliveInterval | number | 30000 | PING interval (ms) |
proxy.reconnectDelay | number | 5000 | Reconnect delay (ms) |
Blockchain / RPC
PC2 reads the Base chain for token-ownership checks (including dDRM playback access). The node maintains a rotating, health-tracked pool of public RPC endpoints and exposes its own caching proxy at /api/rpc/base.
{
"blockchain": {
"chain_id": 8453,
"chain_name": "base",
"public_proxy_url": "",
"rpc_unhealthy_cooldown_ms": 60000,
"rpc_urls": [
"https://base-rpc.publicnode.com",
"https://base.drpc.org",
"https://mainnet.base.org"
]
}
}| Key | Type | Default | Description |
|---|---|---|---|
chain_id | number | 8453 | Base mainnet chain ID |
chain_name | string | "base" | Chain name |
public_proxy_url | string | "" | Optional. A publicly-reachable URL pointing at this node’s own /api/rpc/base proxy (e.g. https://yourname.ela.city/api/rpc/base). When set, dDRM access checks run through your rotating, cached, multi-RPC proxy instead of a single public RPC. Leave empty for auto-detection — the node now auto-routes through its own public proxy during playback when reachable, falling back to a healthy public RPC otherwise. |
rpc_unhealthy_cooldown_ms | number | 60000 | How long (ms) a public RPC is sidelined after returning 5xx / 429 before it’s retried. |
rpc_urls | array | […] | Ordered pool of Base RPC endpoints. Index 0 must be a key-less, rate-tolerant public RPC. |
Playback shows “purchase access tokens” on a video you own? That’s almost always a transient RPC rate-limit during the on-chain ownership check. As of the May 2026 release, the node auto-routes these checks through its own resilient /api/rpc/base proxy when it has a public address — no configuration needed. If your node runs without a public hostname, you can pin public_proxy_url to any reliable RPC or your own proxy to harden it further.
AI Providers
{
"ai": {
"defaultProvider": "ollama",
"ollama": {
"baseUrl": "http://localhost:11434",
"defaultModel": "deepseek-r1:7b"
},
"openai": {
"apiKey": "sk-...",
"defaultModel": "gpt-4o"
},
"anthropic": {
"apiKey": "sk-ant-...",
"defaultModel": "claude-3-opus-20240229"
},
"gemini": {
"apiKey": "AIza...",
"defaultModel": "gemini-2.0-flash"
},
"xai": {
"apiKey": "xai-...",
"defaultModel": "grok-3"
}
}
}| Key | Type | Description |
|---|---|---|
defaultProvider | string | Default AI provider |
[provider].apiKey | string | API key for provider |
[provider].baseUrl | string | Custom API endpoint |
[provider].defaultModel | string | Default model to use |
Updates
{
"updates": {
"autoCheck": true,
"checkInterval": 21600000,
"githubRepo": "Elacity/pc2.net"
}
}| Key | Type | Default | Description |
|---|---|---|---|
autoCheck | boolean | true | Auto-check for updates |
checkInterval | number | 21600000 | Check interval (ms, 6 hours) |
githubRepo | string | "Elacity/pc2.net" | GitHub repo for updates |
Session
{
"session": {
"expiryDays": 7,
"cookieName": "session"
}
}| Key | Type | Default | Description |
|---|---|---|---|
expiryDays | number | 7 | Session duration in days |
cookieName | string | "session" | Cookie name for session |
Storage
{
"storage": {
"maxFileSize": 104857600,
"ipfs": {
"enabled": true,
"repo": "./data/ipfs"
}
}
}| Key | Type | Default | Description |
|---|---|---|---|
maxFileSize | number | 104857600 | Max upload size (100MB) |
ipfs.enabled | boolean | true | Enable IPFS storage |
ipfs.repo | string | "./data/ipfs" | IPFS repo directory |
Environment Variables
Override config with environment variables:
| Variable | Description |
|---|---|
PORT | HTTP port (overrides http_port) |
NODE_ENV | Environment (“development” or “production”) |
PC2_DATA_DIR | Data directory path |
PC2_CONFIG_FILE | Path to config file |
OPENAI_API_KEY | OpenAI API key |
ANTHROPIC_API_KEY | Anthropic API key |
GEMINI_API_KEY | Google AI API key |
XAI_API_KEY | xAI API key |
Example Configurations
Minimal (Development)
{
"pc2_mode": true,
"http_port": 4200
}Production (VPS)
{
"pc2_mode": true,
"http_port": 4200,
"accessControl": {
"enabled": true
},
"boson": {
"enabled": true
},
"updates": {
"autoCheck": true
}
}Private (Home Server)
{
"pc2_mode": true,
"http_port": 4200,
"accessControl": {
"enabled": true,
"allowedWallets": [
{"wallet": "0xmywallet...", "role": "owner"}
]
},
"ai": {
"defaultProvider": "ollama",
"ollama": {
"baseUrl": "http://localhost:11434"
}
}
}Config Validation
PC2 validates configuration on startup. Invalid config causes:
[ERROR] Configuration validation failed:
- accessControl.allowedWallets[0].wallet: Invalid Ethereum addressFix the error and restart.
→ See Troubleshooting for common issues