"sessioncast-go v0.1.0 — Go SDK for SessionCast Relay"
We're releasing sessioncast-go, a Go client library for interacting with the SessionCast relay server. It's the same library that powers the SessionCast provider in OpenCode.
Install
go get github.com/sessioncast/sessioncast-goWhat It Does
sessioncast-go connects to the SessionCast relay via WebSocket and lets you call your local CLI agent's capabilities from any Go program:
- LLM Chat — Send prompts, get completions from whatever LLM your agent is running
- LLM Streaming — Stream responses chunk by chunk via channels
- Remote Exec — Run shell commands on the agent machine
- SendKeys — Send keystrokes to tmux sessions
- List Sessions — Query active tmux sessions
- Capability Negotiation — Discover what the connected agent supports
Quick Start
package main
import (
"context"
"fmt"
"log"
sessioncast "github.com/sessioncast/sessioncast-go"
)
func main() {
client := sessioncast.NewClient(
sessioncast.WithRelayURL("wss://relay.sessioncast.io/ws"),
sessioncast.WithToken("agt_YOUR_TOKEN"),
sessioncast.WithMachineID("my-machine"),
)
ctx := context.Background()
if err := client.Connect(ctx); err != nil {
log.Fatal(err)
}
defer client.Disconnect()
// Chat completion
resp, err := client.LlmChat(ctx, &sessioncast.LlmChatRequest{
Model: "claude-code",
Messages: []sessioncast.ChatMessage{
{Role: "user", Content: "What is Docker? Answer in 2 sentences."},
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Choices[0].Message.Content)
}Streaming
stream, err := client.LlmChatStream(ctx, &sessioncast.LlmChatRequest{
Model: "claude-code",
Messages: []sessioncast.ChatMessage{
{Role: "user", Content: "Write a hello world HTTP server in Go."},
},
})
if err != nil {
log.Fatal(err)
}
for event := range stream {
if event.Error != nil {
log.Fatal(event.Error)
}
if event.Chunk != nil {
fmt.Print(event.Chunk.Content)
}
if event.Response != nil {
fmt.Printf("\n\nTokens used: %d\n", event.Response.Usage.TotalTokens)
}
}Remote Exec
result, err := client.Exec(ctx, &sessioncast.ExecRequest{
Command: "ls -la /tmp",
Cwd: "/home/user",
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Exit code: %d\nStdout:\n%s\n", result.ExitCode, result.Stdout)Auto-Reconnect
For long-running services, use ConnectWithReconnect — it handles disconnections with exponential backoff (1s → 2s → 4s → ... → 30s max):
client.ConnectWithReconnect(ctx, func() {
fmt.Println("Connected!")
})Architecture
Your Go App
→ sessioncast-go (this library)
→ WebSocket → SessionCast Relay
→ CLI Agent (target machine)
→ LLM / Shell / tmuxThe library handles connection lifecycle, ping/pong keepalive (30s interval), request-response correlation via UUID, capability negotiation, and timeout management.
Package Structure
client.go— WebSocket client, connect/disconnect, message routingllm.go—LlmChat()andLlmChatStream()exec.go—Exec(),SendKeys(),ListSessions()protocol.go— Message types, request/response structscorrelator.go— UUID-based request-response matchingcapability.go— Capability negotiation handshakereconnect.go— Auto-reconnect with exponential backoff
Dependencies
Only two:
github.com/gorilla/websocket— WebSocket clientgithub.com/google/uuid— Request ID generation
Configuration
All options use the functional options pattern:
sessioncast.NewClient(
sessioncast.WithRelayURL("wss://relay.sessioncast.io/ws"),
sessioncast.WithToken("agt_YOUR_TOKEN"),
sessioncast.WithMachineID("my-machine"),
sessioncast.WithAgentID("my-agent"),
sessioncast.WithLabel("My App"),
sessioncast.WithRequestTimeout(120 * time.Second),
sessioncast.WithPingInterval(30 * time.Second),
sessioncast.WithLogger(slog.Default()),
)Links
- GitHub — sessioncast-go
- OpenCode Integration — How this SDK powers the OpenCode provider
- SessionCast CLI — The agent that receives your requests