@dsiloed/silo-link
v1.3.0
Published
Claude Code Remote Bridge — connects Claude Code sessions to DSiloed via MCP + ActionCable
Downloads
1,919
Maintainers
Readme
SiloLink — Claude Code Remote Bridge
SiloLink is a local daemon that connects Claude Code sessions to DSiloed conversations. It provides an MCP server that Claude Code connects to, and maintains a real-time WebSocket connection to DSiloed via ActionCable. Messages flow bidirectionally — you can launch, monitor, interact with, and command Claude Code sessions from the DSiloed web UI, Slack, SMS, or Discord.
See it in action — Interactive Demo | Documentation
┌──────────────────────┐
│ DSiloed Server │
│ │
Claude Code (tmux) ──MCP──► │ │
Claude Code (tmux) ──MCP──► SiloLink ──WebSocket──► ActionCable
Claude Code (tmux) ──MCP──► :3579 ──REST API──► ├── ConversationChannel
│ ├── ControlChannel
│ Claude Launcher │
│ Message Queue │ Web UI / Slack
│ Session Manager │ Discord / SMS
└──────────────────────┘Features
- Launch Claude sessions from the web UI — click "+" in the SiloLinks section to spawn a new session
- Auto-launch — send a message to any SiloLink conversation and Claude starts automatically
- Multi-session — each conversation gets its own Claude Code tmux session
- Message buffering — messages that arrive before Claude registers are queued and delivered
- Status notifications — "Starting session..." and "Session ready!" feedback in the conversation
- Agent Dashboard — active sessions appear in Mission Control with real-time status
- Control Channel — launch/stop/status commands via ActionCable from the UI
- Channel linking — command Claude from Slack, Discord, Teams, or SMS
- Session continuity —
remote_load_contextrestores prior conversation history on session restart - Workspace isolation — git worktrees give each session its own branch and working directory
- File claim tracking — advisory soft-locks with cross-session conflict notifications
- Provider abstraction —
AgentLauncherinterface supports Claude, Gemini, and OpenAI adapters
Installation
npm install -g @dsiloed/silo-linkThis installs the silolink CLI globally.
Configuration
silolink configCreates ~/.silolink/config.json:
| Field | Description | Default |
|-------|-------------|---------|
| host | DSiloed server URL | https://www.dsiloed.com |
| tenant_id | Your tenant identifier | harmoniq |
| shared_key | Tenant shared key for JWT authentication | — |
| user_sub | Your username or email | — |
| mcp_port | Local port for the MCP server | 3579 |
| reconnect_interval_ms | Base reconnect delay | 5000 |
| max_reconnect_attempts | Max reconnect tries | 20 |
| agent_provider | AI provider: claude, gemini, openai | claude |
| claude_command | Path to Claude CLI binary | claude |
| claude_working_directory | Working directory for spawned sessions | — |
| claude_auto_respawn | Auto-respawn on idle/exit | false |
| claude_idle_timeout_ms | Idle threshold before respawn | 30000 |
| claude_session_prompt | Default prompt for spawned sessions | Register with SiloLink... |
Example with Claude launcher enabled:
{
"host": "https://www.dsiloed.com",
"tenant_id": "portablemind",
"shared_key": "your-shared-key",
"user_sub": "[email protected]",
"mcp_port": 3579,
"claude_command": "/home/user/.local/bin/claude",
"claude_working_directory": "/home/user/projects",
"claude_auto_respawn": true,
"claude_idle_timeout_ms": 30000
}Usage
Starting SiloLink
# Foreground (see logs in terminal)
silolink start
# Background (daemon mode)
silolink start --daemonManaging the Daemon
silolink status # Check connection state and active sessions
silolink sessions # List active sessions
silolink stop # Stop daemon (kills all Claude tmux sessions)Launching Claude Sessions
# Launch from CLI
silolink launch
silolink launch -p "Work on the auth refactor"
# Launch from the DSiloed web UI
# Click "+" in the SiloLinks section of TeamChatConnecting Claude Code (Manual)
Add SiloLink as an MCP server in your Claude Code settings (.claude.json or project .mcp.json):
{
"mcpServers": {
"silolink": {
"command": "npx",
"args": ["mcp-remote", "http://localhost:3579/mcp"]
}
}
}Claude Session Launcher
SiloLink spawns and manages Claude Code sessions using tmux:
On-Demand (from DSiloed UI)
- Click + in the SiloLinks section of TeamChat
- Enter a session name and optional prompt → Launch Session
- Conversation appears immediately — "Starting session..." shows while Claude initializes
- Claude sends "Session ready!" when the poll loop begins (~20-30 seconds)
Auto-Launch (on inbound message)
When a message arrives on a SiloLink conversation with no active session:
- SiloLink posts "Restarting session..." immediately
- Spawns Claude Code in a new tmux session
- The triggering message is buffered and delivered once Claude registers
- Claude sends "Session ready" and enters the poll loop
Multi-Session
Each conversation gets its own tmux session. Multiple sessions run simultaneously.
# List active tmux sessions
tmux list-sessions | grep silolink
# Attach to watch Claude work
tmux attach -t silolink-claude-1774363497579
# Detach: Ctrl+B, DSession Lifecycle
- Launch → SiloLink posts "Starting session..." → spawns tmux → Claude registers → "Session ready!"
- Messages → user sends message → SiloLink enqueues → Claude polls and responds
- Delete → gear icon → "Delete SiloLink" stops the Claude session and deletes the conversation
- Shutdown →
silolink stopkills all tmux sessions and completes agent sessions on DSiloed
MCP Tools
| Tool | Description | Blocking |
|------|-------------|----------|
| remote_register | Register session, create/attach conversation | No |
| remote_load_context | Load prior conversation history for session continuity | No |
| remote_notify | Fire-and-forget message | No |
| remote_ask | Post question, wait for reply | Yes |
| remote_poll | Non-blocking check for next message (recommended) | No |
| remote_check_messages | Non-blocking check for ALL pending messages | No |
| remote_wait_for_command | Block until next message (prefer remote_poll) | Yes |
| remote_sessions | List active sessions | No |
| remote_unregister | Unregister and clean up | No |
| remote_workspace_create | Create an isolated git worktree for this session | No |
| remote_workspace_claim | Claim files (advisory soft-lock) with conflict detection | No |
| remote_workspace_check | Check file claims across all sessions | No |
| remote_workspace_merge | Merge worktree branch back and clean up | No |
| remote_workspace_list | List all active workspaces | No |
remote_register
Input: { session_name?: "my project", conversation_id?: 453 }
Output: { session_id, conversation_id, conversation_url }When conversation_id is provided, attaches to that existing conversation (used by auto-launcher).
remote_load_context
Input: { conversation_id?: 109, limit?: 50 }
Output: { success: true, conversation_id, resume_id, message_count, history: [...] }Fetches prior conversation history and the last claude_resume_id from agent session metadata. Call after remote_register when attaching to an existing conversation to restore session continuity.
remote_poll (Recommended)
Input: {}
Output: { success: true, message: "...", sender_name: "..." }
— or —
{ success: true, pending: true }Non-blocking. Safer than remote_wait_for_command — can't lose messages on cancellation.
remote_notify
Input: { message: "Build completed successfully" }
Output: { success: true, message_id }remote_ask
Input: { question: "Should I proceed?", timeout?: 300 }
Output: { response: "Yes", sender_name: "rholmes" }Workspace Isolation
Multiple sessions can work on the same repo without conflicts using git worktrees:
Session A: feature/auth ──► ~/.silolink/worktrees/myapp/feature/auth/
Session B: feature/api ──► ~/.silolink/worktrees/myapp/feature/api/Creating a Workspace
// Agent creates a worktree on session start
remote_workspace_create({ repo: "/home/user/myapp", branch: "feature/auth" })
// → { worktree_path: "~/.silolink/worktrees/myapp/feature/auth", branch: "feature/auth" }
// Claim files before editing (advisory — warns on conflicts, doesn't block)
remote_workspace_claim({ files: ["src/auth.ts", "src/middleware.ts"] })
// → { claimed: [...], conflicts: [] }
// Check what other sessions are working on
remote_workspace_check({})
// → { all_claims: [{ session_id: "session-B", files: ["src/api.ts"] }] }
// When done, merge back
remote_workspace_merge({})
// → { success: true, merged_branch: "feature/auth" }Cross-Session Conflict Notifications
When session A claims files that session B already owns, both sessions receive automatic notifications via their message queues and DSiloed conversations.
Launcher Integration
The control channel launch command supports workspace params:
{ "type": "launch", "conversation_id": 123, "repo_path": "/home/user/myapp", "branch": "feature/auth" }Provider Selection
Set agent_provider in ~/.silolink/config.json:
{ "agent_provider": "claude" }Supported providers: claude (default, fully implemented), gemini (stub), openai (stub).
Control Channel API
SiloLink subscribes to a tenant-scoped ActionCable control channel on startup. The DSiloed UI sends commands via REST:
| Endpoint | Method | Description |
|----------|--------|-------------|
| /api/v1/silolink/launch | POST | Launch new session (creates conversation) |
| /api/v1/silolink/stop | POST | Stop session (by conversation_id or all) |
| /api/v1/silolink/status | GET | Request SiloLink status |
# Launch
curl -X POST /api/v1/silolink/launch \
-d '{"name": "my-feature", "prompt": "Work on auth"}'
# Response
{"success": true, "conversation_id": 458, "message": "Launch command sent"}CLAUDE.md Integration
Add to your project's CLAUDE.md:
## Remote Communication (SiloLink)
When the SiloLink MCP server is connected:
1. Register with `remote_register({ session_name: "<name>" })`.
If a conversation_id is provided, pass it too.
2. **Session Continuity**: If you registered with an existing conversation_id,
call `remote_load_context()` to load prior conversation history.
3. ALL communication MUST go through SiloLink — never write to terminal.
4. Send progress updates with `remote_notify()`.
5. When idle, use the poll loop:
- Call `remote_poll()` — returns instantly
- If `{ pending: true }`: sleep 3s, poll again
- If message received: process it, notify result, resume
6. Use `remote_ask()` for questions needing immediate reply.Poll Loop Pattern
// Register (use conversation_id if provided in launch prompt)
remote_register({ session_name: "portablemind", conversation_id: 123 })
// If attaching to existing conversation, load prior context
context = remote_load_context()
// Review context.history to understand what was discussed
// Poll loop
while (idle) {
result = remote_poll()
if (result.pending) { sleep(3s); continue }
handle(result.message)
remote_notify({ message: "Done: ..." })
}Agent Sessions
Active SiloLink sessions appear in the Mission Control Agent Dashboard with:
- Session name (matches conversation name)
- Status: idle, working, waiting for human, error, completed
- Heartbeats on every tool call
- Conversation link for quick navigation
Permissions
Option 1 — Skip all prompts:
claude --dangerously-skip-permissionsOption 2 — Allow SiloLink tools only:
{ "permissions": { "allow": ["mcp__silolink__*"] } }Technical Details
- Authentication: HS256 JWTs (24h validity, auto-refresh every 12h)
- Reconnection: Exponential backoff (1s → 60s cap)
- Echo Prevention: Tracked outbound message IDs + prefix matching
- Session Cleanup: Idle sessions cleaned after 1 hour, agent sessions completed on DSiloed
- Multi-Session: Multiple tmux sessions, one per conversation
- Message Buffering: Pre-registration messages delivered on session register
- API Timeouts: 30-second abort on all DSiloed API calls
- Map Validation: Session manager validates 3-map consistency every 5 minutes
- Shutdown: Kills all Claude tmux sessions first, then completes agent sessions
Health Check
curl http://localhost:3579/health
# { "status": "ok", "sessions": 2, "cable": "connected" }Development
pnpm dev start # Dev mode (no build)
pnpm exec tsc --noEmit # Type check
pnpm build # Build
pnpm test # TestsProject Structure
src/
index.ts # CLI entry point
cli/
commands.ts # CLI commands (start, stop, status, launch, config)
daemon.ts # PID file management
config/
config-manager.ts # ~/.silolink/config.json management
jwt-generator.ts # HS256 JWT generation + auto-refresh
core/
bridge.ts # Main orchestrator — startup, shutdown, control channel
session-manager.ts # Session registry with 3-map lookup + validation
message-queue.ts # Per-session inbound queue with acknowledgment protocol
agent-launcher.ts # AgentLauncher interface and types
claude-launcher.ts # Claude Code launcher (tmux-based, implements AgentLauncher)
gemini-launcher.ts # Gemini launcher stub (implements AgentLauncher)
openai-launcher.ts # OpenAI launcher stub (implements AgentLauncher)
launcher-factory.ts # Provider selection factory
workspace-manager.ts # Git worktree lifecycle, file claims, conflict detection
cable/
action-cable-client.ts # ActionCable WebSocket client with auto-reconnect
subscription-manager.ts # Conversation subscriptions, echo prevention, message buffering
api/
dsiloed-client.ts # REST client for DSiloed API (30s timeouts)
mcp/
server.ts # MCP server (Streamable HTTP on Express)
tools/
register-tools.ts # All 14 MCP tool definitions
types/
index.ts # Shared TypeScript interfacesLicense
MIT
