Skip to content

API: Health endpoints for MCP servers #34

@peteski22

Description

@peteski22

Is your feature request related to a problem? Please describe.

I'd like a way to see the health of my mcpd hosted MCP servers, this way I can better understand if there's a problem with a particular MCP server.

Describe the solution you'd like

API endpoints

Method Endpoint Description
GET /api/v1/health/servers Health of all MCP servers
GET /api/v1/health/servers/{server_name} Health of a specified MCP server

This leaves /api/v1/health free for mcpd to later implement it's own health endpoint.

HTTP response status codes

Status code Meaning Description
200 OK Always for successful API responses
404 Not Found Only if the server name is invalid (not known to mcpd)

Object schema

ServerHealth

Field Type Description
name string Server identifier (e.g. time, fetch, elevenlabs)
status enum HealthStatus: ok | timeout | unreachable | unknown
latency string | null Duration string (e.g., "41ms") if successful; null if not
last_checked RFC3339 | null Time when ping was last attempted
last_successful RFC3339 | null Time of most recent successful ping

HealthStatus

Value Meaning
ok Ping succeeded, server is healthy
timeout Ping failed due to timeout (e.g. context deadline)
unreachable Network/DNS failure or connection refused
unknown No health data recorded yet (e.g. new server/just started)

Sample JSON responses

Get health for a specific server

GET /api/v1/health/servers/time

{
  "name": "time",
  "status": "ok",
  "latency": "2ms",
  "last_checked": "2025-06-27T14:10:25Z",
  "last_successful": "2025-06-27T14:10:25Z"
}

Get health for all servers

GET /api/v1/health/servers

{
  "servers": [
    {
      "name": "time",
      "status": "ok",
      "latency": "37ms",
      "last_checked": "2025-06-27T14:13:00Z",
      "last_successful": "2025-06-27T14:13:00Z"
    },
    {
      "name": "fetch",
      "status": "timeout",
      "latency": null,
      "last_checked": "2025-06-27T14:12:58Z",
      "last_successful": "2025-06-27T13:45:11Z"
    },
    {
      "name": "foo",
      "status": "unreachable",
      "latency": null,
      "last_checked": "2025-06-27T14:12:45Z",
      "last_successful": "2025-06-27T12:02:18Z"
    },
    {
      "name": "bar",
      "status": "unknown",
      "latency": null,
      "last_checked": null,
      "last_successful": null
    }
  ]
}

Go implementation

internal/daemon/health_tracker.go

Types

type HealthStatus string

const (
	HealthStatusOK          HealthStatus = "ok"
	HealthStatusTimeout     HealthStatus = "timeout"
	HealthStatusUnreachable HealthStatus = "unreachable"
	HealthStatusUnknown     HealthStatus = "unknown"
)
type ServerHealth struct {
	Name           string         `json:"name"`
	Status         HealthStatus   `json:"status"`
	Latency        *time.Duration  `json:"latency"`         // nil if unavailable
	LastChecked    *time.Time     `json:"last_checked"`     // nil if never checked
	LastSuccessful *time.Time     `json:"last_successful"`  // nil if never succeeded
}
type HealthTracker struct {
	mu     sync.RWMutex
	statuses map[string]ServerHealth
}

HealthTracker can provide the abstraction for updating the health status of an MCP server, and can be composed as part of Daemon alongside the ClientManager.

internal/daemon/daemon.go

type Daemon struct {
	apiServer         *ApiServer
	logger            hclog.Logger
	clientManager     *ClientManager
	healthTracker     *HealthTracker
	supportedRuntimes map[runtime.Runtime]struct{}
	cfgLoader         config.Loader
}

Describe alternatives you've considered

No alternatives considered at present.

Additional Context

No response

Self-Checklist

  • I have read the Contributing Guidelines.
  • I have searched the existing issues and found no duplicate.
  • I have provided a clear and concise description of the problem.
  • I have provided a clear and concise description of the proposed solution.

Metadata

Metadata

Assignees

Labels

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions