From f69a20a70320b6ee8d7c290c8316ddb975120713 Mon Sep 17 00:00:00 2001 From: Otto Jongerius Date: Fri, 27 Mar 2026 18:26:09 +1300 Subject: [PATCH 1/4] Add real-time web dashboard with live SSE stream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Embedded single-page dashboard at :8080 with: - Live tool call stream via Server-Sent Events - Session sidebar with risk indicators - Tool call table with policy/operation/risk filters - Intent chain visualization (temporal grouping) - One-click hash chain verification - Approve/deny paused tool calls from browser New files: - internal/web/ — HTTP handlers, SSE hub, embedded static files - internal/audit/queries.go — dashboard query methods (sessions, tool calls, intents, stats) No external dependencies added (pure stdlib SSE, no WebSocket library). --- CLAUDE.md | 4 +- README.md | 18 +- cmd/beacon-proxy/main.go | 44 +- internal/audit/queries.go | 252 ++++++++++ internal/audit/queries_test.go | 295 +++++++++++ internal/proxy/proxy.go | 14 + internal/web/server.go | 231 +++++++++ internal/web/server_test.go | 223 +++++++++ internal/web/static/index.html | 860 +++++++++++++++++++++++++++++++++ 9 files changed, 1902 insertions(+), 39 deletions(-) create mode 100644 internal/audit/queries.go create mode 100644 internal/audit/queries_test.go create mode 100644 internal/web/server.go create mode 100644 internal/web/server_test.go create mode 100644 internal/web/static/index.html diff --git a/CLAUDE.md b/CLAUDE.md index 8af8941..bce5963 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -15,8 +15,8 @@ make lint # runs go vet ./... - `cmd/beacon-proxy/main.go` — CLI entry point - `internal/proxy/` — core proxy (child process, stdin/stdout piping, JSON-RPC parsing) - `internal/audit/` — SQLite audit store (sessions, messages) -- `internal/policy/` — policy engine (not yet implemented) -- `internal/web/` — dashboard web UI (not yet implemented) +- `internal/policy/` — policy engine (YAML rules, pause/approve flow) +- `internal/web/` — dashboard web UI (embedded HTML, SSE live stream, API handlers) ## Conventions diff --git a/README.md b/README.md index 2eb7a52..5c67683 100644 --- a/README.md +++ b/README.md @@ -127,9 +127,22 @@ beacon-proxy --server-name filesystem -- npx -y @modelcontextprotocol/server-fil } ``` +## Dashboard + +Beacon includes a real-time web dashboard at `http://localhost:8080` (configurable via `--port`). + +- **Live tool call stream** — see every MCP action as it happens via SSE +- **Session overview** — browse sessions, see tool call counts and max risk per server +- **Risk & policy views** — filter by operation type, policy action, or risk level +- **Intent chains** — visualize temporal groupings of related tool calls +- **Approve/deny** — handle paused tool calls directly from the browser +- **Hash chain verification** — one-click integrity check of the entire audit trail + +No build step — the dashboard is a single HTML file embedded in the binary. + ## Inspecting the Audit Trail -All messages are logged to SQLite. Query directly: +The dashboard provides the primary UI. You can also query SQLite directly: ```bash # List all sessions @@ -173,8 +186,9 @@ sqlite3 ~/.beacon/audit.db "SELECT direction, method, jsonrpc_id FROM messages O - [x] HTTP approval endpoints for paused tool calls - [x] Temporal intent grouping (5s gap threshold) +- [x] Real-time web dashboard with live SSE stream + ### Next -- [ ] Real-time web dashboard ### Vision - [ ] Cross-system intent chains — one human request, multiple MCP servers, one narrative diff --git a/cmd/beacon-proxy/main.go b/cmd/beacon-proxy/main.go index 14c4949..5545683 100644 --- a/cmd/beacon-proxy/main.go +++ b/cmd/beacon-proxy/main.go @@ -2,7 +2,6 @@ package main import ( "context" - "encoding/json" "flag" "fmt" "log" @@ -17,13 +16,14 @@ import ( "github.com/ottojongerius/beacon/internal/audit" "github.com/ottojongerius/beacon/internal/policy" "github.com/ottojongerius/beacon/internal/proxy" + "github.com/ottojongerius/beacon/internal/web" ) func main() { serverName := flag.String("server-name", "unknown", "label for this MCP server") dbPath := flag.String("db", "~/.beacon/audit.db", "path to SQLite audit database") rulesPath := flag.String("rules", "", "path to YAML policy rules file (uses defaults if not set)") - port := flag.Int("port", 8080, "HTTP port for approval endpoints") + port := flag.Int("port", 8080, "HTTP port for dashboard and approval endpoints") retentionDays := flag.Int("retention-days", 0, "auto-delete sessions older than N days on startup (0 = keep forever)") // Find "--" separator — everything after it is the server command @@ -82,8 +82,9 @@ func main() { } engine := policy.NewEngine(rules) - // Start HTTP server for approvals - go startHTTPServer(*port, engine) + // Start dashboard web server + dashboard := web.NewServer(store, engine) + go startHTTPServer(*port, dashboard) ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -103,6 +104,7 @@ func main() { Store: store, Policy: engine, Intent: audit.NewIntentTracker(store, 5*time.Second), + Dashboard: dashboard, } if err := p.Run(ctx); err != nil { @@ -110,38 +112,10 @@ func main() { } } -func startHTTPServer(port int, engine *policy.Engine) { - mux := http.NewServeMux() - - mux.HandleFunc("POST /api/tool-calls/{id}/approve", func(w http.ResponseWriter, r *http.Request) { - id := r.PathValue("id") - if err := engine.Approve(id, "http-user"); err != nil { - http.Error(w, err.Error(), http.StatusNotFound) - return - } - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, `{"status":"approved"}`) - }) - - mux.HandleFunc("POST /api/tool-calls/{id}/deny", func(w http.ResponseWriter, r *http.Request) { - id := r.PathValue("id") - if err := engine.Deny(id); err != nil { - http.Error(w, err.Error(), http.StatusNotFound) - return - } - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, `{"status":"denied"}`) - }) - - mux.HandleFunc("GET /api/tool-calls/pending", func(w http.ResponseWriter, r *http.Request) { - ids := engine.PendingApprovals() - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(map[string]any{"pending": ids}) - }) - +func startHTTPServer(port int, dashboard *web.Server) { addr := fmt.Sprintf("127.0.0.1:%d", port) - log.Printf("beacon: approval server listening on %s", addr) - if err := http.ListenAndServe(addr, mux); err != nil { + log.Printf("beacon: dashboard listening on http://%s", addr) + if err := http.ListenAndServe(addr, dashboard.Handler()); err != nil { log.Printf("beacon: HTTP server error: %v", err) } } diff --git a/internal/audit/queries.go b/internal/audit/queries.go new file mode 100644 index 0000000..0a6ddd9 --- /dev/null +++ b/internal/audit/queries.go @@ -0,0 +1,252 @@ +package audit + +import ( + "database/sql" + "encoding/json" + "time" +) + +// SessionSummary is a session with aggregate stats for the dashboard. +type SessionSummary struct { + ID string `json:"id"` + ServerName string `json:"server_name"` + ServerCommand string `json:"server_command"` + StartedAt time.Time `json:"started_at"` + EndedAt *time.Time `json:"ended_at"` + MessageCount int `json:"message_count"` + ToolCallCount int `json:"tool_call_count"` + MaxRisk int `json:"max_risk"` +} + +// ListSessions returns all sessions with aggregate counts, newest first. +func (s *Store) ListSessions() ([]SessionSummary, error) { + rows, err := s.db.Query(` + SELECT s.id, s.server_name, s.server_command, s.started_at, s.ended_at, + COALESCE((SELECT COUNT(*) FROM messages WHERE session_id = s.id), 0) AS msg_count, + COALESCE((SELECT COUNT(*) FROM tool_calls WHERE session_id = s.id), 0) AS tc_count, + COALESCE((SELECT MAX(risk_score) FROM tool_calls WHERE session_id = s.id), 0) AS max_risk + FROM sessions s ORDER BY s.started_at DESC + `) + if err != nil { + return nil, err + } + defer rows.Close() + + var out []SessionSummary + for rows.Next() { + var ss SessionSummary + var endedAt sql.NullTime + if err := rows.Scan(&ss.ID, &ss.ServerName, &ss.ServerCommand, &ss.StartedAt, &endedAt, + &ss.MessageCount, &ss.ToolCallCount, &ss.MaxRisk); err != nil { + return nil, err + } + if endedAt.Valid { + ss.EndedAt = &endedAt.Time + } + out = append(out, ss) + } + return out, rows.Err() +} + +// ToolCallSummary is a tool call row for the dashboard. +type ToolCallSummary struct { + ID string `json:"id"` + SessionID string `json:"session_id"` + ToolName string `json:"tool_name"` + Arguments string `json:"arguments"` + Result *string `json:"result"` + Error *string `json:"error"` + OperationType string `json:"operation_type"` + RiskScore int `json:"risk_score"` + RiskReasons []string `json:"risk_reasons"` + PolicyAction string `json:"policy_action"` + ApprovedBy *string `json:"approved_by"` + RequestedAt time.Time `json:"requested_at"` + RespondedAt *time.Time `json:"responded_at"` + DurationMs *int64 `json:"duration_ms"` + ServerName string `json:"server_name"` +} + +// ListToolCalls returns tool calls with optional filters, newest first. +func (s *Store) ListToolCalls(sessionID, policyFilter, opFilter string, limit int) ([]ToolCallSummary, error) { + query := ` + SELECT tc.id, tc.session_id, tc.tool_name, tc.arguments, tc.result, tc.error, + tc.operation_type, tc.risk_score, tc.risk_reasons, tc.policy_action, + tc.approved_by, tc.requested_at, tc.responded_at, tc.duration_ms, + s.server_name + FROM tool_calls tc + JOIN sessions s ON s.id = tc.session_id + WHERE 1=1 + ` + var args []any + + if sessionID != "" { + query += " AND tc.session_id = ?" + args = append(args, sessionID) + } + if policyFilter != "" { + query += " AND tc.policy_action = ?" + args = append(args, policyFilter) + } + if opFilter != "" { + query += " AND tc.operation_type = ?" + args = append(args, opFilter) + } + query += " ORDER BY tc.requested_at DESC" + if limit > 0 { + query += " LIMIT ?" + args = append(args, limit) + } + + rows, err := s.db.Query(query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + var out []ToolCallSummary + for rows.Next() { + var tc ToolCallSummary + var reasons string + var result, errJSON, approvedBy sql.NullString + var respondedAt sql.NullTime + var durationMs sql.NullInt64 + if err := rows.Scan(&tc.ID, &tc.SessionID, &tc.ToolName, &tc.Arguments, + &result, &errJSON, &tc.OperationType, &tc.RiskScore, &reasons, + &tc.PolicyAction, &approvedBy, &tc.RequestedAt, &respondedAt, &durationMs, + &tc.ServerName); err != nil { + return nil, err + } + if result.Valid { + v := s.decrypt(result.String) + tc.Result = &v + } + if errJSON.Valid { + v := s.decrypt(errJSON.String) + tc.Error = &v + } + if approvedBy.Valid { + tc.ApprovedBy = &approvedBy.String + } + if respondedAt.Valid { + tc.RespondedAt = &respondedAt.Time + } + if durationMs.Valid { + tc.DurationMs = &durationMs.Int64 + } + tc.Arguments = s.decrypt(tc.Arguments) + json.Unmarshal([]byte(reasons), &tc.RiskReasons) + if tc.RiskReasons == nil { + tc.RiskReasons = []string{} + } + out = append(out, tc) + } + return out, rows.Err() +} + +// IntentSummary is an intent context with its tool calls for the dashboard. +type IntentSummary struct { + ID string `json:"id"` + SessionID string `json:"session_id"` + CreatedAt time.Time `json:"created_at"` + ToolCalls []IntentToolEntry `json:"tool_calls"` +} + +// IntentToolEntry is a single tool call within an intent chain. +type IntentToolEntry struct { + SequenceOrder int `json:"sequence_order"` + ToolCallID string `json:"tool_call_id"` + ToolName string `json:"tool_name"` + OperationType string `json:"operation_type"` + RiskScore int `json:"risk_score"` + PolicyAction string `json:"policy_action"` +} + +// ListIntents returns intent contexts with their tool calls for a session. +func (s *Store) ListIntents(sessionID string) ([]IntentSummary, error) { + rows, err := s.db.Query(` + SELECT ic.id, ic.session_id, ic.created_at, + itc.sequence_order, itc.tool_call_id, + tc.tool_name, tc.operation_type, tc.risk_score, tc.policy_action + FROM intent_contexts ic + JOIN intent_tool_calls itc ON itc.intent_id = ic.id + JOIN tool_calls tc ON tc.id = itc.tool_call_id + WHERE ic.session_id = ? + ORDER BY ic.created_at ASC, itc.sequence_order ASC + `, sessionID) + if err != nil { + return nil, err + } + defer rows.Close() + + intentMap := make(map[string]*IntentSummary) + var order []string + + for rows.Next() { + var intentID, sessionID string + var createdAt time.Time + var entry IntentToolEntry + if err := rows.Scan(&intentID, &sessionID, &createdAt, + &entry.SequenceOrder, &entry.ToolCallID, + &entry.ToolName, &entry.OperationType, &entry.RiskScore, &entry.PolicyAction); err != nil { + return nil, err + } + if _, ok := intentMap[intentID]; !ok { + intentMap[intentID] = &IntentSummary{ + ID: intentID, + SessionID: sessionID, + CreatedAt: createdAt, + } + order = append(order, intentID) + } + intentMap[intentID].ToolCalls = append(intentMap[intentID].ToolCalls, entry) + } + + var out []IntentSummary + for _, id := range order { + out = append(out, *intentMap[id]) + } + return out, rows.Err() +} + +// DashboardStats returns aggregate stats for the dashboard header. +type DashboardStats struct { + TotalSessions int `json:"total_sessions"` + ActiveSessions int `json:"active_sessions"` + TotalToolCalls int `json:"total_tool_calls"` + FlaggedCalls int `json:"flagged_calls"` + PausedCalls int `json:"paused_calls"` + BlockedCalls int `json:"blocked_calls"` + AvgRiskScore int `json:"avg_risk_score"` + MaxRiskScore int `json:"max_risk_score"` +} + +// GetStats returns aggregate statistics for the dashboard. +func (s *Store) GetStats() (*DashboardStats, error) { + stats := &DashboardStats{} + err := s.db.QueryRow("SELECT COUNT(*) FROM sessions").Scan(&stats.TotalSessions) + if err != nil { + return nil, err + } + s.db.QueryRow("SELECT COUNT(*) FROM sessions WHERE ended_at IS NULL").Scan(&stats.ActiveSessions) + s.db.QueryRow("SELECT COUNT(*) FROM tool_calls").Scan(&stats.TotalToolCalls) + s.db.QueryRow("SELECT COUNT(*) FROM tool_calls WHERE policy_action = 'flag'").Scan(&stats.FlaggedCalls) + s.db.QueryRow("SELECT COUNT(*) FROM tool_calls WHERE policy_action = 'pause'").Scan(&stats.PausedCalls) + s.db.QueryRow("SELECT COUNT(*) FROM tool_calls WHERE policy_action = 'block'").Scan(&stats.BlockedCalls) + s.db.QueryRow("SELECT COALESCE(AVG(risk_score), 0) FROM tool_calls").Scan(&stats.AvgRiskScore) + s.db.QueryRow("SELECT COALESCE(MAX(risk_score), 0) FROM tool_calls").Scan(&stats.MaxRiskScore) + return stats, nil +} + +// decrypt is a helper that decrypts a string if encryption is enabled, +// falling back to the input on error (for dashboard display). +func (s *Store) decrypt(ciphertext string) string { + if s.enc == nil { + return ciphertext + } + plain, err := s.enc.Decrypt(ciphertext) + if err != nil { + return ciphertext // show as-is if decryption fails + } + return plain +} diff --git a/internal/audit/queries_test.go b/internal/audit/queries_test.go new file mode 100644 index 0000000..d9d38a1 --- /dev/null +++ b/internal/audit/queries_test.go @@ -0,0 +1,295 @@ +package audit + +import ( + "os" + "path/filepath" + "testing" + "time" +) + +func TestListSessions(t *testing.T) { + db := filepath.Join(t.TempDir(), "test.db") + store, err := Open(db) + if err != nil { + t.Fatalf("Open: %v", err) + } + defer store.Close() + + // Empty DB + sessions, err := store.ListSessions() + if err != nil { + t.Fatalf("ListSessions: %v", err) + } + if len(sessions) != 0 { + t.Errorf("expected 0 sessions, got %d", len(sessions)) + } + + // Create sessions with tool calls + id1, err := store.CreateSession("github", "npx github-mcp") + if err != nil { + t.Fatalf("CreateSession: %v", err) + } + + msgID, err := store.LogMessage(id1, "client_to_server", "1", "tools/call", `{"method":"tools/call"}`) + if err != nil { + t.Fatalf("LogMessage: %v", err) + } + + err = store.CreateToolCall(ToolCallRecord{ + ID: "tc-1", + SessionID: id1, + RequestMsgID: msgID, + ToolName: "read_file", + Arguments: `{"path":"test.go"}`, + OperationType: "read", + RiskScore: 10, + RiskReasons: []string{}, + RequestedAt: time.Now().UTC(), + }) + if err != nil { + t.Fatalf("CreateToolCall: %v", err) + } + + sessions, err = store.ListSessions() + if err != nil { + t.Fatalf("ListSessions: %v", err) + } + if len(sessions) != 1 { + t.Fatalf("expected 1 session, got %d", len(sessions)) + } + if sessions[0].ServerName != "github" { + t.Errorf("expected server name 'github', got %q", sessions[0].ServerName) + } + if sessions[0].MessageCount != 1 { + t.Errorf("expected 1 message, got %d", sessions[0].MessageCount) + } + if sessions[0].ToolCallCount != 1 { + t.Errorf("expected 1 tool call, got %d", sessions[0].ToolCallCount) + } +} + +func TestListToolCalls(t *testing.T) { + db := filepath.Join(t.TempDir(), "test.db") + store, err := Open(db) + if err != nil { + t.Fatalf("Open: %v", err) + } + defer store.Close() + + id, err := store.CreateSession("test-server", "echo test") + if err != nil { + t.Fatalf("CreateSession: %v", err) + } + + msgID, err := store.LogMessage(id, "client_to_server", "1", "tools/call", `{}`) + if err != nil { + t.Fatalf("LogMessage: %v", err) + } + + err = store.CreateToolCall(ToolCallRecord{ + ID: "tc-1", + SessionID: id, + RequestMsgID: msgID, + ToolName: "delete_issue", + Arguments: `{"id":42}`, + OperationType: "delete", + RiskScore: 60, + RiskReasons: []string{"delete_operation"}, + RequestedAt: time.Now().UTC(), + }) + if err != nil { + t.Fatalf("CreateToolCall: %v", err) + } + + if err := store.UpdateToolCallPolicy("tc-1", "flag", nil); err != nil { + t.Fatalf("UpdateToolCallPolicy: %v", err) + } + + // No filter + calls, err := store.ListToolCalls("", "", "", 100) + if err != nil { + t.Fatalf("ListToolCalls: %v", err) + } + if len(calls) != 1 { + t.Fatalf("expected 1 call, got %d", len(calls)) + } + if calls[0].ToolName != "delete_issue" { + t.Errorf("tool name = %q, want delete_issue", calls[0].ToolName) + } + if calls[0].PolicyAction != "flag" { + t.Errorf("policy = %q, want flag", calls[0].PolicyAction) + } + if calls[0].ServerName != "test-server" { + t.Errorf("server = %q, want test-server", calls[0].ServerName) + } + if len(calls[0].RiskReasons) != 1 || calls[0].RiskReasons[0] != "delete_operation" { + t.Errorf("risk reasons = %v, want [delete_operation]", calls[0].RiskReasons) + } + + // Filter by policy + calls, err = store.ListToolCalls("", "block", "", 100) + if err != nil { + t.Fatalf("ListToolCalls with filter: %v", err) + } + if len(calls) != 0 { + t.Errorf("expected 0 calls with policy=block, got %d", len(calls)) + } + + // Filter by operation + calls, err = store.ListToolCalls("", "", "delete", 100) + if err != nil { + t.Fatalf("ListToolCalls op filter: %v", err) + } + if len(calls) != 1 { + t.Errorf("expected 1 delete call, got %d", len(calls)) + } +} + +func TestListIntents(t *testing.T) { + db := filepath.Join(t.TempDir(), "test.db") + store, err := Open(db) + if err != nil { + t.Fatalf("Open: %v", err) + } + defer store.Close() + + sessionID, err := store.CreateSession("test", "echo test") + if err != nil { + t.Fatalf("CreateSession: %v", err) + } + + msgID, err := store.LogMessage(sessionID, "client_to_server", "1", "tools/call", `{}`) + if err != nil { + t.Fatalf("LogMessage: %v", err) + } + + err = store.CreateToolCall(ToolCallRecord{ + ID: "tc-1", SessionID: sessionID, RequestMsgID: msgID, + ToolName: "read_file", Arguments: "{}", OperationType: "read", + RiskScore: 0, RiskReasons: []string{}, RequestedAt: time.Now().UTC(), + }) + if err != nil { + t.Fatalf("CreateToolCall: %v", err) + } + + intentID, err := store.CreateIntentContext(sessionID) + if err != nil { + t.Fatalf("CreateIntentContext: %v", err) + } + if err := store.AddToolCallToIntent(intentID, "tc-1", 1); err != nil { + t.Fatalf("AddToolCallToIntent: %v", err) + } + + intents, err := store.ListIntents(sessionID) + if err != nil { + t.Fatalf("ListIntents: %v", err) + } + if len(intents) != 1 { + t.Fatalf("expected 1 intent, got %d", len(intents)) + } + if len(intents[0].ToolCalls) != 1 { + t.Fatalf("expected 1 tool call in intent, got %d", len(intents[0].ToolCalls)) + } + if intents[0].ToolCalls[0].ToolName != "read_file" { + t.Errorf("tool name = %q, want read_file", intents[0].ToolCalls[0].ToolName) + } +} + +func TestGetStats(t *testing.T) { + db := filepath.Join(t.TempDir(), "test.db") + store, err := Open(db) + if err != nil { + t.Fatalf("Open: %v", err) + } + defer store.Close() + + stats, err := store.GetStats() + if err != nil { + t.Fatalf("GetStats: %v", err) + } + if stats.TotalSessions != 0 || stats.TotalToolCalls != 0 { + t.Errorf("expected zeros, got sessions=%d calls=%d", stats.TotalSessions, stats.TotalToolCalls) + } + + id, err := store.CreateSession("s1", "echo") + if err != nil { + t.Fatalf("CreateSession: %v", err) + } + + msgID, err := store.LogMessage(id, "client_to_server", "1", "tools/call", `{}`) + if err != nil { + t.Fatalf("LogMessage: %v", err) + } + + err = store.CreateToolCall(ToolCallRecord{ + ID: "tc-1", SessionID: id, RequestMsgID: msgID, + ToolName: "write_file", Arguments: "{}", OperationType: "write", + RiskScore: 40, RiskReasons: []string{"write_operation"}, RequestedAt: time.Now().UTC(), + }) + if err != nil { + t.Fatalf("CreateToolCall: %v", err) + } + + stats, err = store.GetStats() + if err != nil { + t.Fatalf("GetStats: %v", err) + } + if stats.TotalSessions != 1 { + t.Errorf("sessions = %d, want 1", stats.TotalSessions) + } + if stats.ActiveSessions != 1 { + t.Errorf("active = %d, want 1 (not ended)", stats.ActiveSessions) + } + if stats.TotalToolCalls != 1 { + t.Errorf("tool calls = %d, want 1", stats.TotalToolCalls) + } + if stats.AvgRiskScore != 40 { + t.Errorf("avg risk = %d, want 40", stats.AvgRiskScore) + } +} + +func TestListToolCalls_WithEncryption(t *testing.T) { + db := filepath.Join(t.TempDir(), "test.db") + // Use a 32-byte hex key for AES-256 + key := "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + os.Setenv("BEACON_ENCRYPTION_KEY", key) + defer os.Unsetenv("BEACON_ENCRYPTION_KEY") + + store, err := Open(db, key) + if err != nil { + t.Fatalf("Open: %v", err) + } + defer store.Close() + + id, err := store.CreateSession("encrypted-server", "echo test") + if err != nil { + t.Fatalf("CreateSession: %v", err) + } + + msgID, err := store.LogMessage(id, "client_to_server", "1", "tools/call", `{}`) + if err != nil { + t.Fatalf("LogMessage: %v", err) + } + + err = store.CreateToolCall(ToolCallRecord{ + ID: "tc-1", SessionID: id, RequestMsgID: msgID, + ToolName: "read_file", Arguments: `{"path":"secret.txt"}`, OperationType: "read", + RiskScore: 10, RiskReasons: []string{}, RequestedAt: time.Now().UTC(), + }) + if err != nil { + t.Fatalf("CreateToolCall: %v", err) + } + + // Should decrypt transparently + calls, err := store.ListToolCalls("", "", "", 100) + if err != nil { + t.Fatalf("ListToolCalls: %v", err) + } + if len(calls) != 1 { + t.Fatalf("expected 1 call, got %d", len(calls)) + } + // Arguments should be decrypted (redacted but readable) + if calls[0].Arguments == "" { + t.Error("expected non-empty arguments after decryption") + } +} diff --git a/internal/proxy/proxy.go b/internal/proxy/proxy.go index c11f85e..eec38cb 100644 --- a/internal/proxy/proxy.go +++ b/internal/proxy/proxy.go @@ -15,6 +15,7 @@ import ( "github.com/google/uuid" "github.com/ottojongerius/beacon/internal/audit" "github.com/ottojongerius/beacon/internal/policy" + "github.com/ottojongerius/beacon/internal/web" ) const maxMessageSize = 1 << 20 // 1MB @@ -33,6 +34,7 @@ type Proxy struct { Store *audit.Store Policy *policy.Engine Intent *audit.IntentTracker + Dashboard *web.Server pendingCalls map[string]*pendingCall // keyed by JSON-RPC id pendingMu sync.Mutex @@ -181,6 +183,18 @@ func (p *Proxy) handleToolCallRequest(sessionID, msgID, jsonrpcID string, msg *M return "pass" } + // Broadcast to dashboard + if p.Dashboard != nil { + p.Dashboard.Broadcast(map[string]any{ + "type": "tool_call", + "id": tcID, + "tool_name": params.Name, + "operation_type": opType, + "risk_score": score, + "server_name": p.ServerName, + }) + } + // Track intent grouping if p.Intent != nil { p.Intent.Track(sessionID, tcID, now) diff --git a/internal/web/server.go b/internal/web/server.go new file mode 100644 index 0000000..aced385 --- /dev/null +++ b/internal/web/server.go @@ -0,0 +1,231 @@ +package web + +import ( + "embed" + "encoding/json" + "fmt" + "io/fs" + "log" + "net/http" + "sync" + "time" + + "github.com/ottojongerius/beacon/internal/audit" + "github.com/ottojongerius/beacon/internal/policy" +) + +//go:embed static +var staticFiles embed.FS + +// Server is the dashboard web server. +type Server struct { + store *audit.Store + engine *policy.Engine + hub *wsHub +} + +// NewServer creates a new dashboard server. +func NewServer(store *audit.Store, engine *policy.Engine) *Server { + return &Server{ + store: store, + engine: engine, + hub: newHub(), + } +} + +// Handler returns an http.Handler with all dashboard routes. +func (s *Server) Handler() http.Handler { + mux := http.NewServeMux() + + // API routes + mux.HandleFunc("GET /api/stats", s.handleStats) + mux.HandleFunc("GET /api/sessions", s.handleSessions) + mux.HandleFunc("GET /api/tool-calls", s.handleToolCalls) + mux.HandleFunc("GET /api/sessions/{id}/intents", s.handleIntents) + mux.HandleFunc("GET /api/chain/verify", s.handleVerifyChain) + mux.HandleFunc("GET /api/tool-calls/pending", s.handlePending) + mux.HandleFunc("POST /api/tool-calls/{id}/approve", s.handleApprove) + mux.HandleFunc("POST /api/tool-calls/{id}/deny", s.handleDeny) + mux.HandleFunc("GET /ws/live", s.handleWebSocket) + + // Serve embedded static files (dashboard HTML) + staticSub, _ := fs.Sub(staticFiles, "static") + mux.Handle("GET /", http.FileServer(http.FS(staticSub))) + + return mux +} + +// Broadcast sends a tool call event to all connected WebSocket clients. +func (s *Server) Broadcast(event any) { + data, err := json.Marshal(event) + if err != nil { + return + } + s.hub.broadcast(data) +} + +func (s *Server) handleStats(w http.ResponseWriter, r *http.Request) { + stats, err := s.store.GetStats() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + writeJSON(w, stats) +} + +func (s *Server) handleSessions(w http.ResponseWriter, r *http.Request) { + sessions, err := s.store.ListSessions() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if sessions == nil { + sessions = []audit.SessionSummary{} + } + writeJSON(w, sessions) +} + +func (s *Server) handleToolCalls(w http.ResponseWriter, r *http.Request) { + sessionID := r.URL.Query().Get("session_id") + policyFilter := r.URL.Query().Get("policy") + opFilter := r.URL.Query().Get("operation") + limit := 200 + + calls, err := s.store.ListToolCalls(sessionID, policyFilter, opFilter, limit) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if calls == nil { + calls = []audit.ToolCallSummary{} + } + writeJSON(w, calls) +} + +func (s *Server) handleIntents(w http.ResponseWriter, r *http.Request) { + sessionID := r.PathValue("id") + intents, err := s.store.ListIntents(sessionID) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if intents == nil { + intents = []audit.IntentSummary{} + } + writeJSON(w, intents) +} + +func (s *Server) handleVerifyChain(w http.ResponseWriter, r *http.Request) { + status, err := s.store.VerifyChain() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + writeJSON(w, status) +} + +func (s *Server) handlePending(w http.ResponseWriter, r *http.Request) { + ids := s.engine.PendingApprovals() + writeJSON(w, map[string]any{"pending": ids}) +} + +func (s *Server) handleApprove(w http.ResponseWriter, r *http.Request) { + id := r.PathValue("id") + if err := s.engine.Approve(id, "dashboard-user"); err != nil { + http.Error(w, err.Error(), http.StatusNotFound) + return + } + writeJSON(w, map[string]string{"status": "approved"}) +} + +func (s *Server) handleDeny(w http.ResponseWriter, r *http.Request) { + id := r.PathValue("id") + if err := s.engine.Deny(id); err != nil { + http.Error(w, err.Error(), http.StatusNotFound) + return + } + writeJSON(w, map[string]string{"status": "denied"}) +} + +func writeJSON(w http.ResponseWriter, v any) { + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(v) +} + +// --- WebSocket hub (minimal, no external dependencies) --- +// Uses Server-Sent Events (SSE) as a simpler alternative that requires no +// third-party WebSocket library. The endpoint is still mounted at /ws/live +// for compatibility with the spec, but uses SSE under the hood. + +func (s *Server) handleWebSocket(w http.ResponseWriter, r *http.Request) { + flusher, ok := w.(http.Flusher) + if !ok { + http.Error(w, "streaming not supported", http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "text/event-stream") + w.Header().Set("Cache-Control", "no-cache") + w.Header().Set("Connection", "keep-alive") + w.Header().Set("Access-Control-Allow-Origin", "*") + + ch := s.hub.subscribe() + defer s.hub.unsubscribe(ch) + + // Send initial ping + fmt.Fprintf(w, "data: {\"type\":\"connected\",\"time\":\"%s\"}\n\n", time.Now().UTC().Format(time.RFC3339)) + flusher.Flush() + + for { + select { + case msg, ok := <-ch: + if !ok { + return + } + fmt.Fprintf(w, "data: %s\n\n", msg) + flusher.Flush() + case <-r.Context().Done(): + return + } + } +} + +// wsHub manages SSE subscribers. +type wsHub struct { + mu sync.RWMutex + clients map[chan []byte]struct{} +} + +func newHub() *wsHub { + return &wsHub{ + clients: make(map[chan []byte]struct{}), + } +} + +func (h *wsHub) subscribe() chan []byte { + ch := make(chan []byte, 64) + h.mu.Lock() + h.clients[ch] = struct{}{} + h.mu.Unlock() + return ch +} + +func (h *wsHub) unsubscribe(ch chan []byte) { + h.mu.Lock() + delete(h.clients, ch) + close(ch) + h.mu.Unlock() +} + +func (h *wsHub) broadcast(data []byte) { + h.mu.RLock() + defer h.mu.RUnlock() + + for ch := range h.clients { + select { + case ch <- data: + default: + log.Printf("beacon: dropping event for slow SSE client") + } + } +} diff --git a/internal/web/server_test.go b/internal/web/server_test.go new file mode 100644 index 0000000..2b390d9 --- /dev/null +++ b/internal/web/server_test.go @@ -0,0 +1,223 @@ +package web + +import ( + "encoding/json" + "net/http/httptest" + "os" + "path/filepath" + "testing" + "time" + + "github.com/ottojongerius/beacon/internal/audit" + "github.com/ottojongerius/beacon/internal/policy" +) + +func setupTestServer(t *testing.T) (*Server, *audit.Store) { + t.Helper() + db := filepath.Join(t.TempDir(), "test.db") + store, err := audit.Open(db) + if err != nil { + t.Fatalf("Open: %v", err) + } + t.Cleanup(func() { store.Close() }) + + engine := policy.NewEngine(policy.DefaultRules()) + srv := NewServer(store, engine) + return srv, store +} + +func TestHandleStats_Empty(t *testing.T) { + srv, _ := setupTestServer(t) + req := httptest.NewRequest("GET", "/api/stats", nil) + w := httptest.NewRecorder() + + srv.handleStats(w, req) + + if w.Code != 200 { + t.Fatalf("status = %d, want 200", w.Code) + } + + var stats audit.DashboardStats + if err := json.NewDecoder(w.Body).Decode(&stats); err != nil { + t.Fatalf("decode: %v", err) + } + if stats.TotalSessions != 0 { + t.Errorf("sessions = %d, want 0", stats.TotalSessions) + } +} + +func TestHandleSessions(t *testing.T) { + srv, store := setupTestServer(t) + + _, err := store.CreateSession("github", "npx github-mcp") + if err != nil { + t.Fatalf("CreateSession: %v", err) + } + + req := httptest.NewRequest("GET", "/api/sessions", nil) + w := httptest.NewRecorder() + srv.handleSessions(w, req) + + if w.Code != 200 { + t.Fatalf("status = %d", w.Code) + } + + var sessions []audit.SessionSummary + if err := json.NewDecoder(w.Body).Decode(&sessions); err != nil { + t.Fatalf("decode: %v", err) + } + if len(sessions) != 1 { + t.Fatalf("expected 1 session, got %d", len(sessions)) + } + if sessions[0].ServerName != "github" { + t.Errorf("server name = %q", sessions[0].ServerName) + } +} + +func TestHandleToolCalls_WithFilters(t *testing.T) { + srv, store := setupTestServer(t) + + id, err := store.CreateSession("test", "echo") + if err != nil { + t.Fatalf("CreateSession: %v", err) + } + + msgID, err := store.LogMessage(id, "client_to_server", "1", "tools/call", `{}`) + if err != nil { + t.Fatalf("LogMessage: %v", err) + } + + err = store.CreateToolCall(audit.ToolCallRecord{ + ID: "tc-1", SessionID: id, RequestMsgID: msgID, + ToolName: "delete_repo", Arguments: "{}", OperationType: "delete", + RiskScore: 80, RiskReasons: []string{"delete_operation"}, RequestedAt: time.Now().UTC(), + }) + if err != nil { + t.Fatalf("CreateToolCall: %v", err) + } + + // No filter — should return the call + req := httptest.NewRequest("GET", "/api/tool-calls", nil) + w := httptest.NewRecorder() + srv.handleToolCalls(w, req) + + var calls []audit.ToolCallSummary + if err := json.NewDecoder(w.Body).Decode(&calls); err != nil { + t.Fatalf("decode: %v", err) + } + if len(calls) != 1 { + t.Fatalf("expected 1 call, got %d", len(calls)) + } + + // Filter by op=write — should return 0 + req = httptest.NewRequest("GET", "/api/tool-calls?operation=write", nil) + w = httptest.NewRecorder() + srv.handleToolCalls(w, req) + + calls = nil + if err := json.NewDecoder(w.Body).Decode(&calls); err != nil { + t.Fatalf("decode: %v", err) + } + if len(calls) != 0 { + t.Errorf("expected 0 calls with op=write, got %d", len(calls)) + } +} + +func TestHandleVerifyChain(t *testing.T) { + srv, store := setupTestServer(t) + + id, err := store.CreateSession("test", "echo") + if err != nil { + t.Fatalf("CreateSession: %v", err) + } + if _, err := store.LogMessage(id, "client_to_server", "1", "tools/call", `{"test":"msg"}`); err != nil { + t.Fatalf("LogMessage: %v", err) + } + + req := httptest.NewRequest("GET", "/api/chain/verify", nil) + w := httptest.NewRecorder() + srv.handleVerifyChain(w, req) + + if w.Code != 200 { + t.Fatalf("status = %d", w.Code) + } + + var status audit.ChainStatus + if err := json.NewDecoder(w.Body).Decode(&status); err != nil { + t.Fatalf("decode: %v", err) + } + if !status.Valid { + t.Errorf("chain should be valid, got error: %s", status.Error) + } + if status.Total != 1 { + t.Errorf("total = %d, want 1", status.Total) + } +} + +func TestDashboardServed(t *testing.T) { + srv, _ := setupTestServer(t) + handler := srv.Handler() + + req := httptest.NewRequest("GET", "/", nil) + w := httptest.NewRecorder() + handler.ServeHTTP(w, req) + + if w.Code != 200 { + t.Fatalf("status = %d, want 200", w.Code) + } + + body := w.Body.String() + if len(body) < 100 { + t.Error("expected HTML content from embedded dashboard") + } +} + +func TestSSEEndpoint(t *testing.T) { + srv, _ := setupTestServer(t) + handler := srv.Handler() + + // Just verify the endpoint exists and returns SSE headers + req := httptest.NewRequest("GET", "/ws/live", nil) + w := httptest.NewRecorder() + + // Run in goroutine since SSE blocks; cancel via context + done := make(chan struct{}) + go func() { + handler.ServeHTTP(w, req) + close(done) + }() + + // Give it a moment to write headers, then verify + time.Sleep(50 * time.Millisecond) + + // The SSE handler writes to the response, but httptest.NewRecorder + // doesn't implement http.Flusher properly, so we just check it started + if w.Code != 200 { + t.Logf("SSE endpoint returned %d (may be expected with test recorder)", w.Code) + } +} + +func TestBroadcast(t *testing.T) { + srv, _ := setupTestServer(t) + + ch := srv.hub.subscribe() + defer srv.hub.unsubscribe(ch) + + srv.Broadcast(map[string]string{"type": "test", "data": "hello"}) + + select { + case msg := <-ch: + var data map[string]string + if err := json.Unmarshal(msg, &data); err != nil { + t.Fatalf("unmarshal: %v", err) + } + if data["type"] != "test" { + t.Errorf("type = %q, want test", data["type"]) + } + case <-time.After(time.Second): + t.Fatal("timeout waiting for broadcast") + } +} + +// Ensure unused import doesn't cause issues +var _ = os.DevNull diff --git a/internal/web/static/index.html b/internal/web/static/index.html new file mode 100644 index 0000000..dfd89be --- /dev/null +++ b/internal/web/static/index.html @@ -0,0 +1,860 @@ + + + + + +Beacon — MCP Audit Dashboard + + + +
+

Beacon

+
+ Connecting... +
+
+ +
+
Sessions
-
+
Active
-
+
Tool Calls
-
+
Flagged
-
+
Blocked
-
+
Avg Risk
-
+
+ +
+ + +
+
+ + + + LIVE +
+ +
+ +
+
+ + + + + + + + + +
+ + + + + + + + + + + + + + +
TimeServerToolTypeRiskPolicyDurationActions
+ +
+ + + + +
+
+ + + + From aa73843281204a10f88845248442e46dd7c14bb1 Mon Sep 17 00:00:00 2001 From: Otto Jongerius Date: Fri, 27 Mar 2026 18:42:02 +1300 Subject: [PATCH 2/4] Add traffic generator and dashboard screenshot to README - cmd/beacon-traffic/ generates realistic MCP audit data across github, filesystem, and postgres servers for demo purposes - docs/dashboard.png captured from live dashboard with sample data - README updated with screenshot and demo traffic instructions --- README.md | 12 +++ cmd/beacon-traffic/main.go | 199 +++++++++++++++++++++++++++++++++++++ docs/dashboard.png | Bin 0 -> 145830 bytes 3 files changed, 211 insertions(+) create mode 100644 cmd/beacon-traffic/main.go create mode 100644 docs/dashboard.png diff --git a/README.md b/README.md index 5c67683..d282d94 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,8 @@ beacon-proxy --server-name filesystem -- npx -y @modelcontextprotocol/server-fil Beacon includes a real-time web dashboard at `http://localhost:8080` (configurable via `--port`). +![Beacon Dashboard](docs/dashboard.png) + - **Live tool call stream** — see every MCP action as it happens via SSE - **Session overview** — browse sessions, see tool call counts and max risk per server - **Risk & policy views** — filter by operation type, policy action, or risk level @@ -140,6 +142,16 @@ Beacon includes a real-time web dashboard at `http://localhost:8080` (configurab No build step — the dashboard is a single HTML file embedded in the binary. +### Generate Demo Traffic + +To populate the dashboard with realistic sample data across multiple servers: + +```bash +go run ./cmd/beacon-traffic/ +``` + +This creates sessions for GitHub, filesystem, and PostgreSQL MCP servers with a mix of read/write/delete/execute operations, risk scores, and policy actions (flag, pause, block). + ## Inspecting the Audit Trail The dashboard provides the primary UI. You can also query SQLite directly: diff --git a/cmd/beacon-traffic/main.go b/cmd/beacon-traffic/main.go new file mode 100644 index 0000000..d2f4bc1 --- /dev/null +++ b/cmd/beacon-traffic/main.go @@ -0,0 +1,199 @@ +// beacon-traffic generates realistic MCP audit traffic for dashboard demos. +package main + +import ( + "encoding/json" + "fmt" + "log" + "math/rand" + "os" + "path/filepath" + "strings" + "time" + + "github.com/ottojongerius/beacon/internal/audit" +) + +type scenario struct { + server string + command string + toolCalls []fakeCall +} + +type fakeCall struct { + tool string + args map[string]any + result map[string]any + delayMs int // delay before this call + policySet string +} + +func main() { + home, _ := os.UserHomeDir() + dbPath := filepath.Join(home, ".beacon", "audit.db") + + store, err := audit.Open(dbPath) + if err != nil { + log.Fatalf("failed to open db: %v", err) + } + defer store.Close() + + scenarios := []scenario{ + { + server: "github", + command: "npx -y @modelcontextprotocol/server-github", + toolCalls: []fakeCall{ + {tool: "list_repos", args: m("owner", "ojongerius"), result: m("count", 12), delayMs: 200}, + {tool: "search_issues", args: m("repo", "beacon", "query", "audit"), result: m("count", 3), delayMs: 400}, + {tool: "read_file", args: m("repo", "beacon", "path", "README.md"), result: m("size", 4096), delayMs: 150}, + {tool: "create_issue", args: m("repo", "beacon", "title", "Add SIEM export", "body", "Stream events to Datadog"), result: m("number", 9), delayMs: 800, policySet: "flag"}, + {tool: "update_issue", args: m("repo", "beacon", "number", 5, "labels", []string{"enhancement"}), result: m("updated", true), delayMs: 300, policySet: "flag"}, + }, + }, + { + server: "filesystem", + command: "npx -y @modelcontextprotocol/server-filesystem /Users/otto/projects", + toolCalls: []fakeCall{ + {tool: "list_directory", args: m("path", "/Users/otto/projects"), result: m("entries", 8), delayMs: 100}, + {tool: "read_file", args: m("path", "/Users/otto/projects/beacon/go.mod"), result: m("size", 512), delayMs: 120}, + {tool: "read_file", args: m("path", "/Users/otto/projects/beacon/internal/web/server.go"), result: m("size", 6144), delayMs: 180}, + {tool: "write_file", args: m("path", "/Users/otto/projects/beacon/TODO.md", "content", "# TODO\n- SIEM export\n- Multi-server"), result: m("written", true), delayMs: 500, policySet: "flag"}, + {tool: "delete_file", args: m("path", "/Users/otto/projects/beacon/tmp/old-cache.json"), result: m("deleted", true), delayMs: 400, policySet: "pause"}, + }, + }, + { + server: "postgres", + command: "npx -y @modelcontextprotocol/server-postgres postgres://localhost/app", + toolCalls: []fakeCall{ + {tool: "list_tables", args: m("schema", "public"), result: m("tables", []string{"users", "orders", "products"}), delayMs: 150}, + {tool: "describe_table", args: m("table", "users"), result: m("columns", 8), delayMs: 200}, + {tool: "read_query", args: m("sql", "SELECT COUNT(*) FROM users"), result: m("count", 1847), delayMs: 250}, + {tool: "read_query", args: m("sql", "SELECT email, created_at FROM users ORDER BY created_at DESC LIMIT 5"), result: m("rows", 5), delayMs: 300}, + {tool: "exec_query", args: m("sql", "UPDATE users SET status = 'active' WHERE last_login > NOW() - INTERVAL '30 days'"), result: m("affected", 423), delayMs: 1200, policySet: "pause"}, + {tool: "exec_query", args: m("sql", "DELETE FROM sessions WHERE expired_at < NOW()"), result: m("affected", 89), delayMs: 600, policySet: "block"}, + }, + }, + } + + fmt.Println("🔦 Beacon traffic generator") + fmt.Println(" Generating realistic MCP audit traffic...\n") + + for _, sc := range scenarios { + fmt.Printf(" ▸ %s (%s)\n", sc.server, sc.command) + sessionID, err := store.CreateSession(sc.server, sc.command) + if err != nil { + log.Printf(" ✗ failed to create session: %v", err) + continue + } + + intentID := "" + var lastCallTime time.Time + + for i, tc := range sc.toolCalls { + time.Sleep(time.Duration(tc.delayMs) * time.Millisecond) + + now := time.Now().UTC() + argsJSON, _ := json.Marshal(tc.args) + + // Log request message + reqRaw := fmt.Sprintf(`{"jsonrpc":"2.0","id":%d,"method":"tools/call","params":{"name":"%s","arguments":%s}}`, + i+1, tc.tool, argsJSON) + msgID, err := store.LogMessage(sessionID, "client_to_server", fmt.Sprintf("%d", i+1), "tools/call", reqRaw) + if err != nil { + log.Printf(" ✗ log request: %v", err) + continue + } + + // Classify and score + opType := audit.ClassifyOperation(tc.tool) + score, reasons := audit.ScoreRisk(tc.tool, opType, string(argsJSON)) + + tcID := fmt.Sprintf("tc-%s-%d", sc.server, i+1) + err = store.CreateToolCall(audit.ToolCallRecord{ + ID: tcID, + SessionID: sessionID, + RequestMsgID: msgID, + ToolName: tc.tool, + Arguments: string(argsJSON), + OperationType: opType, + RiskScore: score, + RiskReasons: reasons, + RequestedAt: now, + }) + if err != nil { + log.Printf(" ✗ create tool call: %v", err) + continue + } + + // Set policy if specified + if tc.policySet != "" { + store.UpdateToolCallPolicy(tcID, tc.policySet, nil) + } + + // Simulate response after a brief delay + respDelay := time.Duration(50+rand.Intn(200)) * time.Millisecond + time.Sleep(respDelay) + respTime := time.Now().UTC() + + resultJSON, _ := json.Marshal(tc.result) + respRaw := fmt.Sprintf(`{"jsonrpc":"2.0","id":%d,"result":%s}`, i+1, resultJSON) + respMsgID, err := store.LogMessage(sessionID, "server_to_client", fmt.Sprintf("%d", i+1), "", respRaw) + if err != nil { + log.Printf(" ✗ log response: %v", err) + continue + } + + durationMs := respTime.Sub(now).Milliseconds() + result := string(resultJSON) + store.CompleteToolCall(tcID, respMsgID, &result, nil, respTime, durationMs) + + // Intent grouping: new intent if gap > 2s + if intentID == "" || now.Sub(lastCallTime) > 2*time.Second { + intentID2, err := store.CreateIntentContext(sessionID) + if err == nil { + intentID = intentID2 + } + } + if intentID != "" { + store.AddToolCallToIntent(intentID, tcID, i+1) + } + lastCallTime = now + + policyTag := "" + if tc.policySet != "" { + policyTag = fmt.Sprintf(" [%s]", strings.ToUpper(tc.policySet)) + } + riskBar := riskIndicator(score) + fmt.Printf(" %s %-20s %s %-7s risk:%2d %s%s\n", + "✓", tc.tool, riskBar, opType, score, reasons, policyTag) + } + + // End some sessions (leave last one "live") + if sc.server != "postgres" { + store.EndSession(sessionID) + } + } + + fmt.Println("\n ✅ Done! Refresh the dashboard at http://localhost:8080") +} + +func m(kvs ...any) map[string]any { + out := make(map[string]any) + for i := 0; i < len(kvs)-1; i += 2 { + out[kvs[i].(string)] = kvs[i+1] + } + return out +} + +func riskIndicator(score int) string { + switch { + case score <= 30: + return "🟢" + case score <= 60: + return "🟡" + case score <= 80: + return "🟠" + default: + return "🔴" + } +} diff --git a/docs/dashboard.png b/docs/dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..28dcbb26e9069d0378949305f2cab7c2375300d4 GIT binary patch literal 145830 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ⅈ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 nXJ Date: Fri, 27 Mar 2026 18:48:06 +1300 Subject: [PATCH 3/4] Fix go vet warning in traffic generator Remove redundant newline in fmt.Println call. --- cmd/beacon-traffic/main.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/beacon-traffic/main.go b/cmd/beacon-traffic/main.go index d2f4bc1..6d4d5b5 100644 --- a/cmd/beacon-traffic/main.go +++ b/cmd/beacon-traffic/main.go @@ -76,7 +76,8 @@ func main() { } fmt.Println("🔦 Beacon traffic generator") - fmt.Println(" Generating realistic MCP audit traffic...\n") + fmt.Println(" Generating realistic MCP audit traffic...") + fmt.Println() for _, sc := range scenarios { fmt.Printf(" ▸ %s (%s)\n", sc.server, sc.command) From 269ca80dce01973141830c3e56ab82d6e3efb474 Mon Sep 17 00:00:00 2001 From: Otto Jongerius Date: Fri, 27 Mar 2026 19:00:45 +1300 Subject: [PATCH 4/4] Fix data race in TestSSEEndpoint Cancel context and wait for handler goroutine to finish before reading ResponseRecorder, avoiding concurrent read/write race. --- internal/web/server_test.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/internal/web/server_test.go b/internal/web/server_test.go index 2b390d9..2f99fad 100644 --- a/internal/web/server_test.go +++ b/internal/web/server_test.go @@ -1,6 +1,7 @@ package web import ( + "context" "encoding/json" "net/http/httptest" "os" @@ -176,24 +177,28 @@ func TestSSEEndpoint(t *testing.T) { srv, _ := setupTestServer(t) handler := srv.Handler() - // Just verify the endpoint exists and returns SSE headers - req := httptest.NewRequest("GET", "/ws/live", nil) + // Use a cancellable context so we can cleanly stop the SSE handler + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + req := httptest.NewRequest("GET", "/ws/live", nil).WithContext(ctx) w := httptest.NewRecorder() - // Run in goroutine since SSE blocks; cancel via context + // Run in goroutine since SSE blocks done := make(chan struct{}) go func() { handler.ServeHTTP(w, req) close(done) }() - // Give it a moment to write headers, then verify + // Cancel the context to stop the handler, then wait for it to finish + // before reading the response (avoids data race on ResponseRecorder) time.Sleep(50 * time.Millisecond) + cancel() + <-done - // The SSE handler writes to the response, but httptest.NewRecorder - // doesn't implement http.Flusher properly, so we just check it started if w.Code != 200 { - t.Logf("SSE endpoint returned %d (may be expected with test recorder)", w.Code) + t.Errorf("SSE endpoint returned %d, want 200", w.Code) } }