docs/architecture.md
This document describes the internal architecture of MCPProxy, including the management service, runtime lifecycle, and event system.
The management service (internal/management/) provides a centralized business logic layer for upstream server management operations, eliminating code duplication across CLI, REST API, and MCP interfaces.
┌─────────────────────────────────────────────────────────────┐
│ Client Interfaces │
├───────────────┬─────────────────┬───────────────────────────┤
│ CLI Commands │ REST API │ MCP Protocol │
│ (upstream) │ (/api/v1/*) │ (upstream_servers tool) │
└───────┬───────┴────────┬────────┴───────────┬───────────────┘
│ │ │
└────────────────┼────────────────────┘
│
▼
┌─────────────────────┐
│ Management Service │
│ (internal/mgmt/) │
└──────────┬──────────┘
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Runtime │ │ Config │ │ Events │
│Operations│ │ Gates │ │ Emitter │
└──────────┘ └──────────┘ └──────────┘
Service Interface (service.go:16-102): Defines all management operations
RestartServer(), EnableServer(), DisableServer()RestartAll(), EnableAll(), DisableAll()GetServerHealth(), RunDiagnostics()AddServer(), RemoveServer(), QuarantineServer()GetServerTools(), TriggerOAuthLogin()Configuration Gates: All operations respect centralized configuration guards
disable_management: Blocks all write operations when trueread_only_mode: Blocks all configuration modificationsBulk Operations (service.go:243-388): Efficient multi-server management
BulkOperationResult with success/failure countsEvent Integration: All operations emit events through event bus
servers.changed: Notifies UI of server state changes// CLI usage (cmd/mcpproxy/upstream_cmd.go:547-636)
result, err := client.RestartAll(ctx)
fmt.Printf(" Total servers: %d\n", result.Total)
fmt.Printf(" ✅ Successful: %d\n", result.Successful)
fmt.Printf(" ❌ Failed: %d\n", result.Failed)
// REST API usage (internal/httpapi/server.go:772-866)
mgmtSvc := s.controller.GetManagementService().(ManagementService)
result, err := mgmtSvc.RestartAll(r.Context())
s.writeSuccess(w, result)
// MCP protocol usage (future integration)
result, err := mgmtService.RestartAll(ctx)
return mcpResponse(result)
The runtime package (internal/runtime/) provides core non-HTTP lifecycle management, separating concerns from the HTTP server layer.
The event bus enables real-time communication between runtime and UI components:
Event Types:
servers.changed - Server configuration or state changesconfig.reloaded - Configuration file reloaded from diskEvent Flow:
emitServersChanged() and emitConfigReloaded()/events SSE endpointSSE Integration:
/events endpoint streams both status updates and runtime eventsInitialization:
Background Services:
Shutdown:
Subprocess Shutdown Flow:
| Timeout | Value | Purpose |
|---|---|---|
| MCP Client Close | 10s | Wait for graceful stdin/stdout close |
| SIGTERM → SIGKILL | 9s | Time between graceful and force kill |
| Docker Cleanup | 30s | Container stop/kill timeout |
See Shutdown Behavior for detailed documentation.
The tray application uses a robust state machine architecture for reliable core management.
StateInitializing → StateLaunchingCore → StateWaitingForCore → StateConnectingAPI → StateConnectedStateCoreErrorPortConflict, StateCoreErrorDBLocked, StateCoreErrorGeneral, StateCoreErrorConfigStateReconnecting, StateFailed, StateShuttingDowncmd/mcpproxy-tray/internal/monitor/process.go): Monitors core subprocess lifecyclecmd/mcpproxy-tray/internal/monitor/health.go): Performs socket-aware HTTP health checks on core API (/healthz, /readyz)cmd/mcpproxy-tray/internal/state/machine.go): Manages state transitions and automatic retry logicCore process exit codes are mapped to specific state machine events:
EventPortConflictEventDBLockedEventConfigErrorEventPermissionErrorEventGeneralErrorError states automatically retry core launch with exponential backoff:
StateCoreErrorGeneral: 2 retries with 3s delay (3 total attempts)StateCoreErrorPortConflict: 2 retries with 10s delayStateCoreErrorDBLocked: 3 retries with 5s delayStateFailedMCPPROXY_TRAY_SKIP_CORE=1 - Skip core launch (for development)MCPPROXY_CORE_URL=http://localhost:8085 - Custom core URLMCPPROXY_TRAY_PORT=8090 - Custom tray port