Documentation
¶
Overview ¶
Package clauderelay provides a WebSocket relay server for Claude Code CLI with isolated, portable installation support.
This package enables you to programmatically create and manage multiple isolated Claude instances, each with its own configuration and authentication, without requiring system-wide installation.
Features ¶
• Isolated Installation: Each instance has its own Bun and Claude installation • Multiple Instances: Run multiple Claude relays on different ports • Auto-Setup: Automatically downloads and installs dependencies • Authentication Management: Handle Claude authentication programmatically • WebSocket Interface: Connect to Claude via WebSocket protocol • Conversation State: Maintains context across messages • Undo/Restore: Support for undoing and restoring conversations
Basic Usage ¶
Create a simple relay server:
import "github.com/rizrmd/claude-relay"
func main() {
// Create relay with automatic setup
relay, err := clauderelay.New(clauderelay.Options{
Port: "8081",
BaseDir: "./claude-instance",
AutoSetup: true,
EnableLogging: true,
})
if err != nil {
log.Fatal(err)
}
defer relay.Close()
// Check authentication
if authenticated, _ := relay.IsAuthenticated(); !authenticated {
if err := relay.Authenticate(); err != nil {
log.Fatal(err)
}
}
// Start the server
if err := relay.Start(); err != nil {
log.Fatal(err)
}
// Wait for shutdown
select {}
}
Multiple Instances ¶
Run multiple isolated Claude instances:
// Create instance 1
relay1, _ := clauderelay.New(clauderelay.Options{
Port: "8081",
BaseDir: "./claude-1",
})
relay1.Start()
// Create instance 2
relay2, _ := clauderelay.New(clauderelay.Options{
Port: "8082",
BaseDir: "./claude-2",
})
relay2.Start()
Embedding in Existing Server ¶
Integrate Claude relay into your existing HTTP server:
relay, _ := clauderelay.New(clauderelay.Options{
Port: "8081",
})
relay.Start()
// Use relay.GetWebSocketURL() to get the WebSocket endpoint
// Integrate with your existing routes
WebSocket Protocol ¶
The relay server exposes a WebSocket endpoint at /ws that accepts text messages and returns Claude's responses.
Client to Server: • Plain text messages to send to Claude • /undo-from:N - Undo from message index N • /restore - Restore last undone conversation
Server to Client: • Claude's responses as plain text • Progress indicators during processing • Error messages prefixed with ❌
Directory Structure ¶
Each Claude instance creates the following structure in its BaseDir:
BaseDir/ ├── .bun/ // Portable Bun installation │ └── bin/ │ ├── bun // Bun executable │ └── claude // Claude CLI ├── .claude-home/ // Claude configuration │ └── .config/ │ └── claude/ │ └── auth.json // Authentication token └── claude-relay-*/ // Temporary workspaces (runtime)
Authentication ¶
Claude requires authentication on first use. The library provides multiple authentication methods to suit different deployment scenarios:
## Authentication Methods
Claude Code CLI uses browser-based authentication, NOT API keys.
### 1. Authenticate() - Interactive/Terminal-Based
Standard authentication flow - requires terminal and browser access.
err := relay.Authenticate() // User will: // 1. See Claude interface in terminal // 2. Choose a theme (press 1 for dark) // 3. Type /login // 4. Complete browser authentication
### 2. CopyAuthFrom() - Reuse Existing Authentication
Copy authentication from another machine or backup.
// First, authenticate on a machine with browser access
// Then copy .claude-home/.config/claude/ directory
err := relay.CopyAuthFrom("/path/to/claude/config")
### 3. Options.PreAuthDirectory - Pre-authenticated Setup
Provide pre-authenticated config during initialization.
relay, _ := clauderelay.New(clauderelay.Options{
PreAuthDirectory: "/backup/claude-auth",
})
## When to Use Each Method
Authenticate() - Use when: • Local development with terminal • Initial setup with browser access • One-time authentication
CopyAuthFrom() - Use when: • Deploying to servers without browser • Docker containers • CI/CD pipelines • Reusing auth across instances
## Authentication in Production
For production deployments without browser access:
1. Authenticate once on a development machine:
relay.Authenticate() // Interactive login authPath := relay.GetAuthConfigPath() // Save the files in authPath
2. Copy auth files to production:
relay.CopyAuthFrom("/deployed/auth/backup")
## Checking Authentication Status
// Simple check authenticated, err := relay.IsAuthenticated() // Detailed status authenticated, message, err := relay.GetAuthStatus() // Returns: (true, "Authenticated", nil) or (false, "No authentication file found", nil)
Thread Safety ¶
The Relay type is thread-safe and can be safely accessed from multiple goroutines. Multiple relay instances can run concurrently without interference.
Package clauderelay provides a WebSocket relay server for Claude Code CLI with isolated, portable installation support.
This package allows you to create multiple isolated Claude instances, each with its own configuration and authentication, without requiring system-wide installation.
Basic usage:
import "github.com/yourusername/claude-relay"
// Create a new relay server
relay, err := clauderelay.New(clauderelay.Options{
Port: "8081",
BaseDir: "./claude-instance-1",
AutoSetup: true,
})
if err != nil {
log.Fatal(err)
}
defer relay.Close()
// Start the server
if err := relay.Start(); err != nil {
log.Fatal(err)
}
Package clauderelay provides isolated Claude Code CLI instances.
Index ¶
- func PromptUser(prompt string) string
- type ClaudeProcess
- func (p *ClaudeProcess) CanRestore() bool
- func (p *ClaudeProcess) CanUndo() bool
- func (p *ClaudeProcess) Cleanup() error
- func (p *ClaudeProcess) GetLastExchange() (string, string, error)
- func (p *ClaudeProcess) GetRestoredMessagesForClient() []map[string]string
- func (p *ClaudeProcess) GetWorkingDirectory() string
- func (p *ClaudeProcess) IsRunning() bool
- func (p *ClaudeProcess) Kill() error
- func (p *ClaudeProcess) ReadFile(filename string) ([]byte, error)
- func (p *ClaudeProcess) RestoreLastUndo() ([]string, error)
- func (p *ClaudeProcess) SaveFile(filename string, content []byte) error
- func (p *ClaudeProcess) SaveState()
- func (p *ClaudeProcess) SendMessage(message string) (string, error)
- func (p *ClaudeProcess) SendMessageWithProgress(message string, progressChan chan<- []byte, doneChan <-chan bool) (string, error)
- func (p *ClaudeProcess) UndoLastExchange() error
- func (p *ClaudeProcess) UndoToIndex(messageIndex int) error
- type ClaudeProcessV2
- func (p *ClaudeProcessV2) Cleanup() error
- func (p *ClaudeProcessV2) GetWorkingDirectory() string
- func (p *ClaudeProcessV2) ReadFile(filename string) ([]byte, error)
- func (p *ClaudeProcessV2) SaveFile(filename string, content []byte) error
- func (p *ClaudeProcessV2) SendMessage(message string) (string, error)
- type ClaudeSetup
- func (cs *ClaudeSetup) CheckAuthentication() (bool, error)
- func (cs *ClaudeSetup) CopyAuthFrom(sourceDir string) error
- func (cs *ClaudeSetup) GetAuthStatus() (bool, string, error)
- func (cs *ClaudeSetup) GetClaudeEnv() []string
- func (cs *ClaudeSetup) GetClaudeHome() string
- func (cs *ClaudeSetup) GetClaudePath() string
- func (cs *ClaudeSetup) HandleAuthenticationPrompt(process *ClaudeProcess) error
- func (cs *ClaudeSetup) InstallBun() error
- func (cs *ClaudeSetup) InstallClaude() error
- func (cs *ClaudeSetup) IsAuthenticationNeeded(output string) bool
- func (cs *ClaudeSetup) IsInstalled() bool
- func (cs *ClaudeSetup) RunClaudeLogin() error
- func (cs *ClaudeSetup) SetAuthToken(authToken string) error
- func (cs *ClaudeSetup) Setup() error
- func (cs *ClaudeSetup) SetupClaudeHome() error
- func (cs *ClaudeSetup) WaitForAuth(timeout time.Duration) error
- type Config
- type Connection
- type ConnectionV2
- type ConversationState
- type Options
- type Relay
- func (r *Relay) Authenticate() error
- func (r *Relay) Close() error
- func (r *Relay) CopyAuthFrom(sourceDir string) error
- func (r *Relay) GetAuthConfigPath() string
- func (r *Relay) GetAuthStatus() (bool, string, error)
- func (r *Relay) GetBaseDir() string
- func (r *Relay) GetPort() string
- func (r *Relay) GetServer() *Server
- func (r *Relay) GetSetup() *ClaudeSetup
- func (r *Relay) GetWebSocketURL() string
- func (r *Relay) IsAuthenticated() (bool, error)
- func (r *Relay) IsInstalled() bool
- func (r *Relay) IsRunning() bool
- func (r *Relay) SetAuthToken(authToken string) error
- func (r *Relay) Setup() error
- func (r *Relay) Start() error
- func (r *Relay) Stop() error
- func (r *Relay) Wait()
- type Server
- type ServerV2
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func PromptUser ¶
Types ¶
type ClaudeProcess ¶
type ClaudeProcess struct {
// contains filtered or unexported fields
}
func NewClaudeProcess ¶
func NewClaudeProcess(setup *ClaudeSetup) (*ClaudeProcess, error)
func (*ClaudeProcess) CanRestore ¶
func (p *ClaudeProcess) CanRestore() bool
func (*ClaudeProcess) CanUndo ¶
func (p *ClaudeProcess) CanUndo() bool
func (*ClaudeProcess) Cleanup ¶
func (p *ClaudeProcess) Cleanup() error
func (*ClaudeProcess) GetLastExchange ¶
func (p *ClaudeProcess) GetLastExchange() (string, string, error)
func (*ClaudeProcess) GetRestoredMessagesForClient ¶
func (p *ClaudeProcess) GetRestoredMessagesForClient() []map[string]string
func (*ClaudeProcess) GetWorkingDirectory ¶
func (p *ClaudeProcess) GetWorkingDirectory() string
func (*ClaudeProcess) IsRunning ¶
func (p *ClaudeProcess) IsRunning() bool
func (*ClaudeProcess) Kill ¶
func (p *ClaudeProcess) Kill() error
func (*ClaudeProcess) RestoreLastUndo ¶
func (p *ClaudeProcess) RestoreLastUndo() ([]string, error)
func (*ClaudeProcess) SaveFile ¶
func (p *ClaudeProcess) SaveFile(filename string, content []byte) error
func (*ClaudeProcess) SaveState ¶
func (p *ClaudeProcess) SaveState()
func (*ClaudeProcess) SendMessage ¶
func (p *ClaudeProcess) SendMessage(message string) (string, error)
func (*ClaudeProcess) SendMessageWithProgress ¶
func (*ClaudeProcess) UndoLastExchange ¶
func (p *ClaudeProcess) UndoLastExchange() error
func (*ClaudeProcess) UndoToIndex ¶
func (p *ClaudeProcess) UndoToIndex(messageIndex int) error
type ClaudeProcessV2 ¶
type ClaudeProcessV2 struct {
// contains filtered or unexported fields
}
func NewClaudeProcessV2 ¶
func NewClaudeProcessV2() (*ClaudeProcessV2, error)
func (*ClaudeProcessV2) Cleanup ¶
func (p *ClaudeProcessV2) Cleanup() error
func (*ClaudeProcessV2) GetWorkingDirectory ¶
func (p *ClaudeProcessV2) GetWorkingDirectory() string
func (*ClaudeProcessV2) ReadFile ¶
func (p *ClaudeProcessV2) ReadFile(filename string) ([]byte, error)
func (*ClaudeProcessV2) SaveFile ¶
func (p *ClaudeProcessV2) SaveFile(filename string, content []byte) error
func (*ClaudeProcessV2) SendMessage ¶
func (p *ClaudeProcessV2) SendMessage(message string) (string, error)
type ClaudeSetup ¶
type ClaudeSetup struct {
// contains filtered or unexported fields
}
func NewClaudeSetup ¶
func NewClaudeSetup() (*ClaudeSetup, error)
func NewClaudeSetupWithBaseDir ¶
func NewClaudeSetupWithBaseDir(baseDir string) (*ClaudeSetup, error)
NewClaudeSetupWithBaseDir creates a ClaudeSetup with a custom base directory. This allows multiple isolated Claude instances.
func (*ClaudeSetup) CheckAuthentication ¶
func (cs *ClaudeSetup) CheckAuthentication() (bool, error)
func (*ClaudeSetup) CopyAuthFrom ¶ added in v1.0.1
func (cs *ClaudeSetup) CopyAuthFrom(sourceDir string) error
CopyAuthFrom copies authentication config from another directory
func (*ClaudeSetup) GetAuthStatus ¶
func (cs *ClaudeSetup) GetAuthStatus() (bool, string, error)
GetAuthStatus returns detailed authentication status
func (*ClaudeSetup) GetClaudeEnv ¶
func (cs *ClaudeSetup) GetClaudeEnv() []string
func (*ClaudeSetup) GetClaudeHome ¶
func (cs *ClaudeSetup) GetClaudeHome() string
func (*ClaudeSetup) GetClaudePath ¶
func (cs *ClaudeSetup) GetClaudePath() string
func (*ClaudeSetup) HandleAuthenticationPrompt ¶
func (cs *ClaudeSetup) HandleAuthenticationPrompt(process *ClaudeProcess) error
func (*ClaudeSetup) InstallBun ¶
func (cs *ClaudeSetup) InstallBun() error
func (*ClaudeSetup) InstallClaude ¶
func (cs *ClaudeSetup) InstallClaude() error
func (*ClaudeSetup) IsAuthenticationNeeded ¶
func (cs *ClaudeSetup) IsAuthenticationNeeded(output string) bool
func (*ClaudeSetup) IsInstalled ¶
func (cs *ClaudeSetup) IsInstalled() bool
func (*ClaudeSetup) RunClaudeLogin ¶
func (cs *ClaudeSetup) RunClaudeLogin() error
func (*ClaudeSetup) SetAuthToken ¶
func (cs *ClaudeSetup) SetAuthToken(authToken string) error
SetAuthToken sets the Claude Code CLI authentication token programmatically Note: This is NOT a Claude API key, but rather the auth token from Claude Code CLI login
func (*ClaudeSetup) Setup ¶
func (cs *ClaudeSetup) Setup() error
func (*ClaudeSetup) SetupClaudeHome ¶
func (cs *ClaudeSetup) SetupClaudeHome() error
func (*ClaudeSetup) WaitForAuth ¶
func (cs *ClaudeSetup) WaitForAuth(timeout time.Duration) error
WaitForAuth waits for authentication to be completed This can be used after SetAuthToken to verify authentication worked
type Config ¶
type Config struct {
Port string `json:"port"`
ClaudePath string `json:"claude_path"`
MaxProcesses int `json:"max_processes"`
Endpoints map[string]string `json:"endpoints,omitempty"`
AllowOrigins []string `json:"allow_origins,omitempty"`
TempDirBase string `json:"temp_dir_base,omitempty"`
}
func DefaultConfig ¶
func DefaultConfig() *Config
func LoadConfig ¶
type Connection ¶
type Connection struct {
// contains filtered or unexported fields
}
type ConnectionV2 ¶
type ConnectionV2 struct {
// contains filtered or unexported fields
}
type ConversationState ¶
type Options ¶
type Options struct {
// Port is the port number for the WebSocket server.
// Default: "8080"
Port string
// BaseDir is the directory where Claude and Bun will be installed.
// Each instance should have a unique BaseDir for isolation.
// Default: current directory
BaseDir string
// AutoSetup automatically installs Claude and Bun if not present.
// Default: true
AutoSetup bool
// MaxProcesses limits the number of concurrent Claude processes.
// Default: 100
MaxProcesses int
// EnableLogging enables detailed logging output.
// Default: true
EnableLogging bool
// CustomClaudePath allows specifying a custom Claude executable path.
// If empty, uses the isolated installation.
CustomClaudePath string
// AuthToken provides a pre-existing Claude Code CLI auth token for reuse.
// This is obtained from a previous Claude Code CLI login session.
// Note: This is NOT a Claude API key.
AuthToken string
// PreAuthDirectory specifies a directory containing pre-authenticated Claude config.
// Copy from another machine's .claude-home/.config/claude/ directory.
PreAuthDirectory string
}
Options configures the Claude relay server.
type Relay ¶
type Relay struct {
// contains filtered or unexported fields
}
Relay represents a Claude WebSocket relay server instance.
func New ¶
New creates a new Claude relay instance with the given options.
Example:
relay, err := clauderelay.New(clauderelay.Options{
Port: "8081",
BaseDir: "./my-claude",
})
func (*Relay) Authenticate ¶
Authenticate runs the Claude authentication process interactively. This should be called when IsAuthenticated returns false.
Example:
authenticated, _ := relay.IsAuthenticated()
if !authenticated {
fmt.Println("Please complete Claude authentication:")
if err := relay.Authenticate(); err != nil {
log.Fatal(err)
}
}
func (*Relay) Close ¶
Close stops the server and cleans up resources. It's safe to call Close multiple times.
Example:
defer relay.Close()
func (*Relay) CopyAuthFrom ¶ added in v1.0.1
CopyAuthFrom copies authentication from another Claude installation. Use this to reuse authentication from another machine or instance.
Example:
// Copy auth from another instance
err := relay.CopyAuthFrom("/backup/claude-auth/")
func (*Relay) GetAuthConfigPath ¶ added in v1.0.1
GetAuthConfigPath returns the path where Claude Code CLI stores authentication. This can be used to backup or transfer authentication between machines.
Example:
path := relay.GetAuthConfigPath() // Returns: "/path/to/.claude-home/.config/claude"
func (*Relay) GetAuthStatus ¶
GetAuthStatus returns detailed authentication status. Returns: (isAuthenticated, statusMessage, error)
func (*Relay) GetBaseDir ¶
GetBaseDir returns the base directory for this Claude instance.
func (*Relay) GetSetup ¶
func (r *Relay) GetSetup() *ClaudeSetup
GetSetup returns the underlying ClaudeSetup instance for advanced usage.
func (*Relay) GetWebSocketURL ¶
GetWebSocketURL returns the WebSocket URL for connecting to this relay.
func (*Relay) IsAuthenticated ¶
IsAuthenticated checks if Claude is authenticated.
func (*Relay) IsInstalled ¶
IsInstalled checks if Claude and Bun are installed.
func (*Relay) SetAuthToken ¶
SetAuthToken sets a pre-existing Claude Code CLI auth token. Note: This is NOT a Claude API key, but the token from Claude Code CLI login. This method is mainly for advanced use cases where you have the raw token.
Example:
// If you somehow have the auth token from Claude Code CLI
token := getClaudeAuthToken() // from previous session
if err := relay.SetAuthToken(token); err != nil {
log.Fatal(err)
}
func (*Relay) Setup ¶
Setup installs Claude and Bun if not already installed. This is called automatically if AutoSetup is true.
func (*Relay) Start ¶
Start starts the WebSocket relay server. The server runs in the background and returns immediately.
Example:
if err := relay.Start(); err != nil {
log.Fatal(err)
}
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
func NewServer ¶
func NewServer(config *Config, setup *ClaudeSetup) *Server
func (*Server) HandleWebSocket ¶
func (s *Server) HandleWebSocket(w http.ResponseWriter, r *http.Request)
type ServerV2 ¶
type ServerV2 struct {
// contains filtered or unexported fields
}
func NewServerV2 ¶
func (*ServerV2) HandleWebSocketV2 ¶
func (s *ServerV2) HandleWebSocketV2(w http.ResponseWriter, r *http.Request)
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
claude-relay
command
Command claude-relay starts a WebSocket relay server for Claude Code CLI.
|
Command claude-relay starts a WebSocket relay server for Claude Code CLI. |
|
examples
|
|
|
auth-preconfig
command
Example of using pre-configured authentication (copying from existing auth).
|
Example of using pre-configured authentication (copying from existing auth). |
|
basic
command
Basic example of using the clauderelay library.
|
Basic example of using the clauderelay library. |
|
docker-deployment
command
Example of deploying Claude relay in Docker/production environments.
|
Example of deploying Claude relay in Docker/production environments. |
|
embedded
command
Example of embedding Claude relay in an existing HTTP server.
|
Example of embedding Claude relay in an existing HTTP server. |
|
multiple
command
Example of running multiple isolated Claude instances.
|
Example of running multiple isolated Claude instances. |
|
webservice
command
Example of using Claude relay in a web service with non-interactive authentication.
|
Example of using Claude relay in a web service with non-interactive authentication. |