diff --git a/loop/agent.go b/loop/agent.go
index f01e601..8f96924 100644
--- a/loop/agent.go
+++ b/loop/agent.go
@@ -152,8 +152,7 @@
 	// CompactConversation compacts the current conversation by generating a summary
 	// and restarting the conversation with that summary as the initial context
 	CompactConversation(ctx context.Context) error
-	// GetPortMonitor returns the port monitor instance for accessing port events
-	GetPortMonitor() *PortMonitor
+
 	// SkabandAddr returns the skaband address if configured
 	SkabandAddr() string
 }
@@ -460,9 +459,6 @@
 
 	// Track outstanding tool calls by ID with their names
 	outstandingToolCalls map[string]string
-
-	// Port monitoring
-	portMonitor *PortMonitor
 }
 
 // NewIterator implements CodingAgent.
@@ -1071,8 +1067,8 @@
 		stateMachine:         NewStateMachine(),
 		workingDir:           config.WorkingDir,
 		outsideHTTP:          config.OutsideHTTP,
-		portMonitor:          NewPortMonitor(),
-		mcpManager:           mcp.NewMCPManager(),
+
+		mcpManager: mcp.NewMCPManager(),
 	}
 	return agent
 }
@@ -1526,12 +1522,6 @@
 }
 
 func (a *Agent) Loop(ctxOuter context.Context) {
-	// Start port monitoring when the agent loop begins
-	// Only monitor ports when running in a container
-	if a.IsInContainer() {
-		a.portMonitor.Start(ctxOuter)
-	}
-
 	// Set up cleanup when context is done
 	defer func() {
 		if a.mcpManager != nil {
@@ -2540,11 +2530,6 @@
 	return nil
 }
 
-// GetPortMonitor returns the port monitor instance for accessing port events
-func (a *Agent) GetPortMonitor() *PortMonitor {
-	return a.portMonitor
-}
-
 // SkabandAddr returns the skaband address if configured
 func (a *Agent) SkabandAddr() string {
 	if a.config.SkabandClient != nil {
diff --git a/loop/port_monitor.go b/loop/port_monitor.go
deleted file mode 100644
index 105e1e7..0000000
--- a/loop/port_monitor.go
+++ /dev/null
@@ -1,344 +0,0 @@
-package loop
-
-import (
-	"context"
-	"fmt"
-	"log/slog"
-	"net"
-	"os"
-	"os/exec"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
-)
-
-// PortEvent represents a port change event
-type PortEvent struct {
-	Type      string    `json:"type"`      // "opened" or "closed"
-	Port      string    `json:"port"`      // "proto:address:port" format
-	Timestamp time.Time `json:"timestamp"` // when the event occurred
-}
-
-// PortMonitor handles periodic monitoring of listening ports in containers
-type PortMonitor struct {
-	mu        sync.Mutex  // protects following
-	lastPorts string      // last netstat/ss output for comparison
-	events    []PortEvent // circular buffer of recent port events
-	maxEvents int         // maximum events to keep in buffer
-}
-
-// NewPortMonitor creates a new PortMonitor instance
-func NewPortMonitor() *PortMonitor {
-	return &PortMonitor{
-		maxEvents: 100, // keep last 100 events
-		events:    make([]PortEvent, 0, 100),
-	}
-}
-
-// Start begins periodic port monitoring in a background goroutine
-func (pm *PortMonitor) Start(ctx context.Context) {
-	go func() {
-		ticker := time.NewTicker(5 * time.Second) // Check every 5 seconds
-		defer ticker.Stop()
-
-		// Get initial port state
-		pm.updatePortState(ctx)
-
-		for {
-			select {
-			case <-ctx.Done():
-				return
-			case <-ticker.C:
-				pm.updatePortState(ctx)
-			}
-		}
-	}()
-}
-
-// updatePortState runs ss and checks for changes in listening ports
-// Falls back to /proc/net/tcp* parsing if ss is not available
-func (pm *PortMonitor) updatePortState(ctx context.Context) {
-	var currentPorts string
-	var err error
-
-	// Try ss command first
-	cmd := exec.CommandContext(ctx, "ss", "-lntu")
-	output, err := cmd.Output()
-	if err != nil {
-		// ss command failed, try /proc filesystem fallback
-		slog.DebugContext(ctx, "ss command failed, trying /proc fallback", "error", err)
-		currentPorts, err = pm.getListeningPortsFromProc()
-		if err != nil {
-			// Both methods failed - log and return
-			slog.DebugContext(ctx, "Failed to get listening ports", "ss_error", err)
-			return
-		}
-	} else {
-		currentPorts = string(output)
-	}
-
-	pm.mu.Lock()
-	defer pm.mu.Unlock()
-
-	// Check if ports have changed
-	if pm.lastPorts != "" && pm.lastPorts != currentPorts {
-		// Ports have changed, log the difference
-		slog.InfoContext(ctx, "Container port changes detected",
-			slog.String("previous_ports", pm.lastPorts),
-			slog.String("current_ports", currentPorts))
-
-		// Parse and compare the port lists for more detailed logging
-		pm.logPortDifferences(ctx, pm.lastPorts, currentPorts)
-	}
-
-	pm.lastPorts = currentPorts
-}
-
-// logPortDifferences parses ss output and logs specific port changes
-func (pm *PortMonitor) logPortDifferences(ctx context.Context, oldPorts, newPorts string) {
-	oldPortSet := parseSSPorts(oldPorts)
-	newPortSet := parseSSPorts(newPorts)
-	now := time.Now()
-
-	// Find newly opened ports
-	for port := range newPortSet {
-		if !oldPortSet[port] {
-			slog.InfoContext(ctx, "New port detected", slog.String("port", port))
-			pm.addEvent(PortEvent{
-				Type:      "opened",
-				Port:      port,
-				Timestamp: now,
-			})
-		}
-	}
-
-	// Find closed ports
-	for port := range oldPortSet {
-		if !newPortSet[port] {
-			slog.InfoContext(ctx, "Port closed", slog.String("port", port))
-			pm.addEvent(PortEvent{
-				Type:      "closed",
-				Port:      port,
-				Timestamp: now,
-			})
-		}
-	}
-}
-
-// addEvent adds a port event to the circular buffer (must be called with mutex held)
-func (pm *PortMonitor) addEvent(event PortEvent) {
-	// If buffer is full, remove oldest event
-	if len(pm.events) >= pm.maxEvents {
-		// Shift all events left by 1 to remove oldest
-		copy(pm.events, pm.events[1:])
-		pm.events = pm.events[:len(pm.events)-1]
-	}
-	// Add new event
-	pm.events = append(pm.events, event)
-}
-
-// GetRecentEvents returns a copy of recent port events since the given timestamp
-func (pm *PortMonitor) GetRecentEvents(since time.Time) []PortEvent {
-	pm.mu.Lock()
-	defer pm.mu.Unlock()
-
-	// Find events since the given timestamp
-	var result []PortEvent
-	for _, event := range pm.events {
-		if event.Timestamp.After(since) {
-			result = append(result, event)
-		}
-	}
-	return result
-}
-
-// UpdatePortState is a public wrapper for updatePortState for testing purposes
-func (pm *PortMonitor) UpdatePortState(ctx context.Context) {
-	pm.updatePortState(ctx)
-}
-
-// GetAllRecentEvents returns a copy of all recent port events
-func (pm *PortMonitor) GetAllRecentEvents() []PortEvent {
-	pm.mu.Lock()
-	defer pm.mu.Unlock()
-
-	// Return a copy of all events
-	result := make([]PortEvent, len(pm.events))
-	copy(result, pm.events)
-	return result
-}
-
-// parseSSPorts extracts listening ports from ss -lntu output
-// Returns a map with "proto:address:port" as keys
-// ss output format: Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
-func parseSSPorts(output string) map[string]bool {
-	ports := make(map[string]bool)
-	lines := strings.Split(output, "\n")
-
-	for _, line := range lines {
-		fields := strings.Fields(line)
-		if len(fields) < 5 {
-			continue
-		}
-
-		// Skip header line and non-LISTEN states
-		if fields[0] == "Netid" || fields[1] != "LISTEN" {
-			continue
-		}
-
-		proto := fields[0]
-		localAddr := fields[4] // Local Address:Port
-		portKey := fmt.Sprintf("%s:%s", proto, localAddr)
-		ports[portKey] = true
-	}
-
-	return ports
-}
-
-// getListeningPortsFromProc reads /proc/net/tcp and /proc/net/tcp6 to find listening ports
-// Returns output in a format similar to ss -lntu
-func (pm *PortMonitor) getListeningPortsFromProc() (string, error) {
-	var result strings.Builder
-	result.WriteString("Netid State  Recv-Q Send-Q Local Address:Port Peer Address:Port\n")
-
-	// Parse IPv4 listening ports
-	if err := pm.parseProc("/proc/net/tcp", "tcp", &result); err != nil {
-		return "", fmt.Errorf("failed to parse /proc/net/tcp: %w", err)
-	}
-
-	// Parse IPv6 listening ports
-	if err := pm.parseProc("/proc/net/tcp6", "tcp", &result); err != nil {
-		// IPv6 might not be available, log but don't fail
-		slog.Debug("Failed to parse /proc/net/tcp6", "error", err)
-	}
-
-	// Parse UDP ports
-	if err := pm.parseProc("/proc/net/udp", "udp", &result); err != nil {
-		slog.Debug("Failed to parse /proc/net/udp", "error", err)
-	}
-
-	if err := pm.parseProc("/proc/net/udp6", "udp", &result); err != nil {
-		slog.Debug("Failed to parse /proc/net/udp6", "error", err)
-	}
-
-	return result.String(), nil
-}
-
-// parseProc parses a /proc/net/* file for listening sockets
-func (pm *PortMonitor) parseProc(filename, protocol string, result *strings.Builder) error {
-	data, err := os.ReadFile(filename)
-	if err != nil {
-		return err
-	}
-
-	lines := strings.Split(string(data), "\n")
-	for i, line := range lines {
-		if i == 0 || strings.TrimSpace(line) == "" {
-			continue // Skip header and empty lines
-		}
-
-		fields := strings.Fields(line)
-		if len(fields) < 4 {
-			continue
-		}
-
-		// Parse socket state (4th field, index 3)
-		stateHex := fields[3]
-		state, err := strconv.ParseInt(stateHex, 16, 32)
-		if err != nil {
-			continue
-		}
-
-		// Check if socket is in LISTEN state (0x0A for TCP) or bound state for UDP
-		isListening := false
-		if protocol == "tcp" && state == 0x0A {
-			isListening = true
-		} else if protocol == "udp" && state == 0x07 {
-			// UDP sockets in state 0x07 (TCP_CLOSE) are bound/listening
-			isListening = true
-		}
-
-		if !isListening {
-			continue
-		}
-
-		// Parse local address (2nd field, index 1)
-		localAddr := fields[1]
-		addr, port, err := pm.parseAddress(localAddr, strings.Contains(filename, "6"))
-		if err != nil {
-			continue
-		}
-
-		// Format similar to ss output
-		result.WriteString(fmt.Sprintf("%s   LISTEN 0      0          %s:%d        0.0.0.0:*\n",
-			protocol, addr, port))
-	}
-
-	return nil
-}
-
-// parseAddress parses hex-encoded address:port from /proc/net files
-func (pm *PortMonitor) parseAddress(addrPort string, isIPv6 bool) (string, int, error) {
-	parts := strings.Split(addrPort, ":")
-	if len(parts) != 2 {
-		return "", 0, fmt.Errorf("invalid address:port format: %s", addrPort)
-	}
-
-	// Parse port (stored in hex, big-endian)
-	portHex := parts[1]
-	port, err := strconv.ParseInt(portHex, 16, 32)
-	if err != nil {
-		return "", 0, fmt.Errorf("invalid port hex: %s", portHex)
-	}
-
-	// Parse IP address
-	addrHex := parts[0]
-	var addr string
-
-	if isIPv6 {
-		// IPv6: 32 hex chars representing 16 bytes
-		if len(addrHex) != 32 {
-			return "", 0, fmt.Errorf("invalid IPv6 address hex length: %d", len(addrHex))
-		}
-		// Convert hex to IPv6 address
-		var ipBytes [16]byte
-		for i := 0; i < 16; i++ {
-			b, err := strconv.ParseInt(addrHex[i*2:(i+1)*2], 16, 8)
-			if err != nil {
-				return "", 0, fmt.Errorf("invalid IPv6 hex: %s", addrHex)
-			}
-			ipBytes[i] = byte(b)
-		}
-		// /proc stores IPv6 in little-endian 32-bit chunks, need to reverse each chunk
-		for i := 0; i < 16; i += 4 {
-			ipBytes[i], ipBytes[i+1], ipBytes[i+2], ipBytes[i+3] = ipBytes[i+3], ipBytes[i+2], ipBytes[i+1], ipBytes[i]
-		}
-		addr = net.IP(ipBytes[:]).String()
-	} else {
-		// IPv4: 8 hex chars representing 4 bytes in little-endian
-		if len(addrHex) != 8 {
-			return "", 0, fmt.Errorf("invalid IPv4 address hex length: %d", len(addrHex))
-		}
-		// Parse as little-endian 32-bit integer
-		addrInt, err := strconv.ParseInt(addrHex, 16, 64)
-		if err != nil {
-			return "", 0, fmt.Errorf("invalid IPv4 hex: %s", addrHex)
-		}
-		// Convert to IP address (reverse byte order for little-endian)
-		addr = fmt.Sprintf("%d.%d.%d.%d",
-			addrInt&0xFF,
-			(addrInt>>8)&0xFF,
-			(addrInt>>16)&0xFF,
-			(addrInt>>24)&0xFF)
-	}
-
-	// Handle special addresses
-	if addr == "0.0.0.0" {
-		addr = "*"
-	} else if addr == "::" {
-		addr = "*"
-	}
-
-	return addr, int(port), nil
-}
diff --git a/loop/port_monitor_test.go b/loop/port_monitor_test.go
deleted file mode 100644
index e0f7ff1..0000000
--- a/loop/port_monitor_test.go
+++ /dev/null
@@ -1,388 +0,0 @@
-package loop
-
-import (
-	"context"
-	"os"
-	"strings"
-	"testing"
-	"time"
-)
-
-// TestPortMonitoring tests the port monitoring functionality
-func TestPortMonitoring(t *testing.T) {
-	// Test with ss output format
-	ssOutput := `Netid State  Recv-Q Send-Q Local Address:Port  Peer Address:PortProcess
-tcp   LISTEN 0      1024       127.0.0.1:40975      0.0.0.0:*          
-tcp   LISTEN 0      4096               *:22               *:*          
-tcp   LISTEN 0      4096               *:80               *:*          
-udp   UNCONN 0      0               127.0.0.1:123            0.0.0.0:*          
-`
-
-	expected := map[string]bool{
-		"tcp:127.0.0.1:40975": true,
-		"tcp:*:22":            true,
-		"tcp:*:80":            true,
-	}
-
-	result := parseSSPorts(ssOutput)
-
-	// Check that all expected ports are found
-	for port := range expected {
-		if !result[port] {
-			t.Errorf("Expected port %s not found in ss parsed output", port)
-		}
-	}
-
-	// Check that UDP port is not included (since it's UNCONN, not LISTEN)
-	if result["udp:127.0.0.1:123"] {
-		t.Errorf("UDP UNCONN port should not be included in listening ports")
-	}
-
-	// Check that no extra ports are found
-	for port := range result {
-		if !expected[port] {
-			t.Errorf("Unexpected port %s found in parsed output", port)
-		}
-	}
-}
-
-// TestPortMonitoringLogDifferences tests the port difference logging
-func TestPortMonitoringLogDifferences(t *testing.T) {
-	ctx := context.Background()
-
-	oldPorts := `Netid State  Recv-Q Send-Q Local Address:Port  Peer Address:PortProcess
-tcp   LISTEN 0      4096               *:22               *:*          
-tcp   LISTEN 0      1024       127.0.0.1:8080      0.0.0.0:*          
-`
-
-	newPorts := `Netid State  Recv-Q Send-Q Local Address:Port  Peer Address:PortProcess
-tcp   LISTEN 0      4096               *:22               *:*          
-tcp   LISTEN 0      1024       127.0.0.1:9090      0.0.0.0:*          
-`
-
-	// Create a port monitor to test the logPortDifferences method
-	pm := NewPortMonitor()
-
-	// This test mainly ensures the method doesn't panic and processes the differences
-	// The actual logging output would need to be captured via a test logger to verify fully
-	pm.logPortDifferences(ctx, oldPorts, newPorts)
-
-	// Test with no differences
-	pm.logPortDifferences(ctx, oldPorts, oldPorts)
-}
-
-// TestPortMonitorCreation tests creating a new port monitor
-func TestPortMonitorCreation(t *testing.T) {
-	pm := NewPortMonitor()
-	if pm == nil {
-		t.Error("NewPortMonitor() returned nil")
-	}
-
-	// Verify initial state
-	pm.mu.Lock()
-	defer pm.mu.Unlock()
-	if pm.lastPorts != "" {
-		t.Error("NewPortMonitor() should have empty lastPorts initially")
-	}
-}
-
-// TestParseSSPortsEdgeCases tests edge cases in ss output parsing
-func TestParseSSPortsEdgeCases(t *testing.T) {
-	tests := []struct {
-		name     string
-		output   string
-		expected map[string]bool
-	}{
-		{
-			name:     "empty output",
-			output:   "",
-			expected: map[string]bool{},
-		},
-		{
-			name:     "header only",
-			output:   "Netid State  Recv-Q Send-Q Local Address:Port  Peer Address:PortProcess",
-			expected: map[string]bool{},
-		},
-		{
-			name:     "non-listen states filtered out",
-			output:   "tcp   ESTAB  0      0       127.0.0.1:8080      127.0.0.1:45678\nudp   UNCONN 0      0       127.0.0.1:123       0.0.0.0:*",
-			expected: map[string]bool{},
-		},
-		{
-			name:     "insufficient fields",
-			output:   "tcp LISTEN 0",
-			expected: map[string]bool{},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			result := parseSSPorts(test.output)
-			if len(result) != len(test.expected) {
-				t.Errorf("Expected %d ports, got %d", len(test.expected), len(result))
-			}
-			for port := range test.expected {
-				if !result[port] {
-					t.Errorf("Expected port %s not found", port)
-				}
-			}
-			for port := range result {
-				if !test.expected[port] {
-					t.Errorf("Unexpected port %s found", port)
-				}
-			}
-		})
-	}
-}
-
-// TestPortEventStorage tests the new event storage functionality
-func TestPortEventStorage(t *testing.T) {
-	pm := NewPortMonitor()
-
-	// Initially should have no events
-	allEvents := pm.GetAllRecentEvents()
-	if len(allEvents) != 0 {
-		t.Errorf("Expected 0 events initially, got %d", len(allEvents))
-	}
-
-	// Simulate port changes that would add events
-	ctx := context.Background()
-	oldPorts := "Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port\ntcp   LISTEN 0      128    0.0.0.0:8080         0.0.0.0:*"
-	newPorts := "Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port\ntcp   LISTEN 0      128    0.0.0.0:9090         0.0.0.0:*"
-
-	pm.logPortDifferences(ctx, oldPorts, newPorts)
-
-	// Should now have events
-	allEvents = pm.GetAllRecentEvents()
-	if len(allEvents) != 2 {
-		t.Errorf("Expected 2 events (1 opened, 1 closed), got %d", len(allEvents))
-	}
-
-	// Check event types
-	foundOpened := false
-	foundClosed := false
-	for _, event := range allEvents {
-		if event.Type == "opened" && event.Port == "tcp:0.0.0.0:9090" {
-			foundOpened = true
-		}
-		if event.Type == "closed" && event.Port == "tcp:0.0.0.0:8080" {
-			foundClosed = true
-		}
-	}
-
-	if !foundOpened {
-		t.Error("Expected to find 'opened' event for port tcp:0.0.0.0:9090")
-	}
-	if !foundClosed {
-		t.Error("Expected to find 'closed' event for port tcp:0.0.0.0:8080")
-	}
-}
-
-// TestPortEventFiltering tests the time-based filtering
-func TestPortEventFiltering(t *testing.T) {
-	pm := NewPortMonitor()
-	ctx := context.Background()
-
-	// Record time before adding events
-	beforeTime := time.Now()
-	time.Sleep(1 * time.Millisecond) // Small delay to ensure timestamp difference
-
-	// Add some events
-	oldPorts := "Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port\ntcp   LISTEN 0      128    0.0.0.0:8080         0.0.0.0:*"
-	newPorts := "Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port\ntcp   LISTEN 0      128    0.0.0.0:9090         0.0.0.0:*"
-	pm.logPortDifferences(ctx, oldPorts, newPorts)
-
-	// Get events since beforeTime - should get all events
-	recentEvents := pm.GetRecentEvents(beforeTime)
-	if len(recentEvents) != 2 {
-		t.Errorf("Expected 2 recent events, got %d", len(recentEvents))
-	}
-
-	// Get events since now - should get no events
-	nowTime := time.Now()
-	recentEvents = pm.GetRecentEvents(nowTime)
-	if len(recentEvents) != 0 {
-		t.Errorf("Expected 0 recent events since now, got %d", len(recentEvents))
-	}
-}
-
-// TestParseAddress tests the hex address parsing for /proc/net files
-func TestParseAddress(t *testing.T) {
-	pm := NewPortMonitor()
-
-	tests := []struct {
-		name       string
-		addrPort   string
-		isIPv6     bool
-		expectIP   string
-		expectPort int
-		expectErr  bool
-	}{
-		{
-			name:       "IPv4 localhost:80",
-			addrPort:   "0100007F:0050", // 127.0.0.1:80 in little-endian hex
-			isIPv6:     false,
-			expectIP:   "127.0.0.1",
-			expectPort: 80,
-			expectErr:  false,
-		},
-		{
-			name:       "IPv4 any:22",
-			addrPort:   "00000000:0016", // 0.0.0.0:22
-			isIPv6:     false,
-			expectIP:   "*",
-			expectPort: 22,
-			expectErr:  false,
-		},
-		{
-			name:       "IPv4 high port",
-			addrPort:   "0100007F:1F90", // 127.0.0.1:8080
-			isIPv6:     false,
-			expectIP:   "127.0.0.1",
-			expectPort: 8080,
-			expectErr:  false,
-		},
-		{
-			name:       "IPv6 any port 22",
-			addrPort:   "00000000000000000000000000000000:0016", // [::]:22
-			isIPv6:     true,
-			expectIP:   "*",
-			expectPort: 22,
-			expectErr:  false,
-		},
-		{
-			name:      "Invalid format - no colon",
-			addrPort:  "0100007F0050",
-			isIPv6:    false,
-			expectErr: true,
-		},
-		{
-			name:      "Invalid port hex",
-			addrPort:  "0100007F:ZZZZ",
-			isIPv6:    false,
-			expectErr: true,
-		},
-		{
-			name:      "Invalid IPv4 hex length",
-			addrPort:  "0100:0050",
-			isIPv6:    false,
-			expectErr: true,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			ip, port, err := pm.parseAddress(test.addrPort, test.isIPv6)
-			if test.expectErr {
-				if err == nil {
-					t.Errorf("Expected error but got none")
-				}
-				return
-			}
-
-			if err != nil {
-				t.Errorf("Unexpected error: %v", err)
-				return
-			}
-
-			if ip != test.expectIP {
-				t.Errorf("Expected IP %s, got %s", test.expectIP, ip)
-			}
-
-			if port != test.expectPort {
-				t.Errorf("Expected port %d, got %d", test.expectPort, port)
-			}
-		})
-	}
-}
-
-// TestParseProcData tests parsing of mock /proc/net data
-func TestParseProcData(t *testing.T) {
-	pm := NewPortMonitor()
-
-	// Test TCP data with listening sockets
-	tcpData := `  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
-   0: 0100007F:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0        1
-   1: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0        2
-   2: 0100007F:1F90 0200007F:C350 01 00000000:00000000 00:00000000 00000000     0        0        3`
-
-	var result strings.Builder
-	result.WriteString("Netid State  Recv-Q Send-Q Local Address:Port Peer Address:Port\n")
-
-	// Create temp file with test data
-	tmpFile := "/tmp/test_tcp"
-	err := os.WriteFile(tmpFile, []byte(tcpData), 0o644)
-	if err != nil {
-		t.Fatalf("Failed to create temp file: %v", err)
-	}
-	defer os.Remove(tmpFile)
-
-	err = pm.parseProc(tmpFile, "tcp", &result)
-	if err != nil {
-		t.Fatalf("parseProc failed: %v", err)
-	}
-
-	output := result.String()
-	t.Logf("Generated output:\n%s", output)
-
-	// Should contain listening ports (state 0A = LISTEN)
-	if !strings.Contains(output, "127.0.0.1:80") {
-		t.Error("Expected to find 127.0.0.1:80 in output")
-	}
-	if !strings.Contains(output, "*:22") {
-		t.Error("Expected to find *:22 in output")
-	}
-	// Should not contain established connection (state 01)
-	if strings.Contains(output, "127.0.0.1:8080") {
-		t.Error("Should not find established connection 127.0.0.1:8080 in output")
-	}
-}
-
-// TestGetListeningPortsFromProcFallback tests the complete /proc fallback
-func TestGetListeningPortsFromProcFallback(t *testing.T) {
-	pm := NewPortMonitor()
-
-	// This test verifies the method runs without error
-	// The actual files may or may not exist, but it should handle both cases gracefully
-	output, err := pm.getListeningPortsFromProc()
-	if err != nil {
-		t.Logf("getListeningPortsFromProc failed (may be expected if /proc/net files don't exist): %v", err)
-		// Don't fail the test - this might be expected in some environments
-		return
-	}
-
-	t.Logf("Generated /proc fallback output:\n%s", output)
-
-	// Should at least have a header
-	if !strings.Contains(output, "Netid State") {
-		t.Error("Expected header in /proc fallback output")
-	}
-}
-
-// TestUpdatePortStateWithFallback tests updatePortState with both ss and /proc fallback
-func TestUpdatePortStateWithFallback(t *testing.T) {
-	pm := NewPortMonitor()
-	ctx := context.Background()
-
-	// Call updatePortState - should try ss first, then fall back to /proc if ss fails
-	pm.updatePortState(ctx)
-
-	// The method should complete without panicking
-	// We can't easily test the exact behavior without mocking, but we can ensure it runs
-	// Check if any port state was captured
-	pm.mu.Lock()
-	lastPorts := pm.lastPorts
-	pm.mu.Unlock()
-
-	t.Logf("Captured port state (length %d):", len(lastPorts))
-	if len(lastPorts) > 0 {
-		t.Logf("First 200 chars: %s", lastPorts[:min(200, len(lastPorts))])
-	}
-}
-
-func min(a, b int) int {
-	if a < b {
-		return a
-	}
-	return b
-}
diff --git a/loop/server/loophttp.go b/loop/server/loophttp.go
index 7f31401..b6e2259 100644
--- a/loop/server/loophttp.go
+++ b/loop/server/loophttp.go
@@ -307,44 +307,6 @@
 		io.WriteString(w, "{}\n")
 	})
 
-	// Handler for /port-events - returns recent port change events
-	s.mux.HandleFunc("/port-events", func(w http.ResponseWriter, r *http.Request) {
-		if r.Method != http.MethodGet {
-			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
-			return
-		}
-
-		w.Header().Set("Content-Type", "application/json")
-
-		// Get the 'since' query parameter for filtering events
-		sinceParam := r.URL.Query().Get("since")
-		var events []loop.PortEvent
-
-		// Get port monitor from agent
-		portMonitor := agent.GetPortMonitor()
-		if portMonitor == nil {
-			// Return empty array if port monitor not available
-			events = []loop.PortEvent{}
-		} else if sinceParam != "" {
-			// Parse the since timestamp
-			sinceTime, err := time.Parse(time.RFC3339, sinceParam)
-			if err != nil {
-				http.Error(w, fmt.Sprintf("Invalid 'since' timestamp format: %v", err), http.StatusBadRequest)
-				return
-			}
-			events = portMonitor.GetRecentEvents(sinceTime)
-		} else {
-			// Return all recent events
-			events = portMonitor.GetAllRecentEvents()
-		}
-
-		// Encode and return the events
-		if err := json.NewEncoder(w).Encode(events); err != nil {
-			slog.ErrorContext(r.Context(), "Error encoding port events response", slog.Any("err", err))
-			http.Error(w, "Internal server error", http.StatusInternalServerError)
-		}
-	})
-
 	// Handler for /messages?start=N&end=M (start/end are optional)
 	s.mux.HandleFunc("/messages", func(w http.ResponseWriter, r *http.Request) {
 		w.Header().Set("Content-Type", "application/json")
diff --git a/loop/server/loophttp_test.go b/loop/server/loophttp_test.go
index adda4e3..f6ec8c7 100644
--- a/loop/server/loophttp_test.go
+++ b/loop/server/loophttp_test.go
@@ -3,7 +3,6 @@
 import (
 	"bufio"
 	"context"
-	"encoding/json"
 	"net/http"
 	"net/http/httptest"
 	"slices"
@@ -261,10 +260,9 @@
 	m.retryNumber++
 }
 
-func (m *mockAgent) GetPortMonitor() *loop.PortMonitor { return loop.NewPortMonitor() }
-func (m *mockAgent) SkabandAddr() string               { return m.skabandAddr }
-func (m *mockAgent) LinkToGitHub() bool                { return false }
-func (m *mockAgent) DiffStats() (int, int)             { return 0, 0 }
+func (m *mockAgent) SkabandAddr() string   { return m.skabandAddr }
+func (m *mockAgent) LinkToGitHub() bool    { return false }
+func (m *mockAgent) DiffStats() (int, int) { return 0, 0 }
 
 // TestSSEStream tests the SSE stream endpoint
 func TestSSEStream(t *testing.T) {
@@ -512,76 +510,6 @@
 	t.Log("Mock CompactConversation works correctly")
 }
 
-// TestPortEventsEndpoint tests the /port-events HTTP endpoint
-func TestPortEventsEndpoint(t *testing.T) {
-	// Create a mock agent that implements the CodingAgent interface
-	agent := &mockAgent{
-		branchPrefix: "sketch/",
-	}
-
-	// Create a server with the mock agent
-	server, err := server.New(agent, nil)
-	if err != nil {
-		t.Fatalf("Failed to create server: %v", err)
-	}
-
-	// Test GET /port-events
-	req, err := http.NewRequest("GET", "/port-events", nil)
-	if err != nil {
-		t.Fatalf("Failed to create request: %v", err)
-	}
-
-	rr := httptest.NewRecorder()
-	server.ServeHTTP(rr, req)
-
-	// Should return 200 OK
-	if status := rr.Code; status != http.StatusOK {
-		t.Errorf("Expected status code %d, got %d", http.StatusOK, status)
-	}
-
-	// Should return JSON content type
-	contentType := rr.Header().Get("Content-Type")
-	if contentType != "application/json" {
-		t.Errorf("Expected Content-Type application/json, got %s", contentType)
-	}
-
-	// Should return valid JSON (empty array since mock returns no events)
-	var events []any
-	if err := json.Unmarshal(rr.Body.Bytes(), &events); err != nil {
-		t.Errorf("Failed to parse JSON response: %v", err)
-	}
-
-	// Should be empty array for mock agent
-	if len(events) != 0 {
-		t.Errorf("Expected empty events array, got %d events", len(events))
-	}
-}
-
-// TestPortEventsEndpointMethodNotAllowed tests that non-GET requests are rejected
-func TestPortEventsEndpointMethodNotAllowed(t *testing.T) {
-	agent := &mockAgent{
-		branchPrefix: "sketch/",
-	}
-	server, err := server.New(agent, nil)
-	if err != nil {
-		t.Fatalf("Failed to create server: %v", err)
-	}
-
-	// Test POST /port-events (should be rejected)
-	req, err := http.NewRequest("POST", "/port-events", nil)
-	if err != nil {
-		t.Fatalf("Failed to create request: %v", err)
-	}
-
-	rr := httptest.NewRecorder()
-	server.ServeHTTP(rr, req)
-
-	// Should return 405 Method Not Allowed
-	if status := rr.Code; status != http.StatusMethodNotAllowed {
-		t.Errorf("Expected status code %d, got %d", http.StatusMethodNotAllowed, status)
-	}
-}
-
 func TestParsePortProxyHost(t *testing.T) {
 	tests := []struct {
 		name     string
