Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions internal/server/health.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package server

import (
"encoding/json"
"net/http"
)

// HealthResponse represents the JSON structure for the /health endpoint response
// as defined in MCP Gateway Specification section 8.1.1
type HealthResponse struct {
Status string `json:"status"` // "healthy" or "unhealthy"
SpecVersion string `json:"specVersion"` // MCP Gateway Specification version
GatewayVersion string `json:"gatewayVersion"` // Gateway implementation version
Servers map[string]ServerStatus `json:"servers"` // Map of server names to their health status
}

// BuildHealthResponse constructs a HealthResponse from the unified server's status
func BuildHealthResponse(unifiedServer *UnifiedServer) HealthResponse {
// Get server status
serverStatus := unifiedServer.GetServerStatus()

// Determine overall health based on server status
overallStatus := "healthy"
for _, status := range serverStatus {
if status.Status == "error" {
overallStatus = "unhealthy"
break
}
}

return HealthResponse{
Status: overallStatus,
SpecVersion: MCPGatewaySpecVersion,
GatewayVersion: gatewayVersion,
Servers: serverStatus,
}
}

// HandleHealth returns an http.HandlerFunc that handles the /health endpoint
// This function is used by both routed and unified modes to ensure consistent behavior
func HandleHealth(unifiedServer *UnifiedServer) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)

response := BuildHealthResponse(unifiedServer)
json.NewEncoder(w).Encode(response)
}
}
24 changes: 1 addition & 23 deletions internal/server/routed.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,29 +110,7 @@ func CreateHTTPServerForRoutedMode(addr string, unifiedServer *UnifiedServer, ap
}

// Health check (spec 8.1.1)
healthHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")

// Get server status
serverStatus := unifiedServer.GetServerStatus()

// Determine overall health based on server status
overallStatus := "healthy"
for _, status := range serverStatus {
if status.Status == "error" {
overallStatus = "unhealthy"
break
}
}

w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]interface{}{
"status": overallStatus,
"specVersion": MCPGatewaySpecVersion,
"gatewayVersion": gatewayVersion,
"servers": serverStatus,
})
})
healthHandler := HandleHealth(unifiedServer)
mux.Handle("/health", withResponseLogging(healthHandler))

// Close endpoint for graceful shutdown (spec 5.1.3)
Expand Down
24 changes: 1 addition & 23 deletions internal/server/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,29 +158,7 @@ func CreateHTTPServerForMCP(addr string, unifiedServer *UnifiedServer, apiKey st
mux.Handle("/mcp", finalHandler)

// Health check (spec 8.1.1)
healthHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")

// Get server status
serverStatus := unifiedServer.GetServerStatus()

// Determine overall health based on server status
overallStatus := "healthy"
for _, status := range serverStatus {
if status.Status == "error" {
overallStatus = "unhealthy"
break
}
}

w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]interface{}{
"status": overallStatus,
"specVersion": MCPGatewaySpecVersion,
"gatewayVersion": gatewayVersion,
"servers": serverStatus,
})
})
healthHandler := HandleHealth(unifiedServer)
mux.Handle("/health", withResponseLogging(healthHandler))

// Close endpoint for graceful shutdown (spec 5.1.3)
Expand Down