homelab-evidence-mcp

Salt okunur stdio MCP sunucusu; Gatus, Docker, Loki, Healthchecks, Beszel ve ntfy genelinde homelab olay kanıtlarını ilişkilendirir. Hedefler başlangıçta kilitlenir; yalnızca HTTP GET; zaman çizelgeleri kök neden uydurmadan gerçeklere dayalı kalır.

Dokümantasyon

homelab-evidence-mcp

CI License: MIT

Collect read-only incident evidence from six homelab sources through MCP. One Go binary uses stdio and joins source identities through a configured service_id.

Six GET-only source adapters feed a service registry and a redacted, timestamped evidence timeline.

The server orders evidence by observation time. Each item includes its source, timestamps, freshness, redaction count, and truncation state. Correlation presents facts; it does not establish a root cause. Destinations remain fixed after startup, and every upstream request uses HTTP GET.

Installation

Prerequisite: Go 1.26.9 is the minimum version.

go install github.com/ThomasCrouzet/homelab-evidence-mcp/cmd/homelab-evidence-mcp@latest

To build from the repository:

make build
./bin/homelab-evidence-mcp --version

Quick start

  1. Copy config.example.yaml to a directory that is not in the repository.
  2. Restrict access to the owner with chmod 600 /path/config.yaml. On Windows, use a user-only ACL.
  3. Configure source URLs and service bindings.
  4. Set each required token through token_env or a private token_file.
  5. Validate the configuration before you add it to the MCP client.
homelab-evidence-mcp --config /path/config.yaml --validate

Validation resolves token references and checks destination settings. It sends no HTTP requests. Unknown YAML keys cause an error. A base_url cannot contain query strings, fragments, or userinfo. For Healthchecks, use a read-only API key.

Registration with an MCP client:

{
  "mcpServers": {
    "homelab-evidence": {
      "command": "/path/homelab-evidence-mcp",
      "args": ["--config", "/path/config.yaml"]
    }
  }
}

This example uses token files or inherited environment variables. The server reserves stdout for JSON-RPC and writes logs and audit events to stderr. It can also write a configured rotating audit file. See MCP client configuration and the integration example.

Source adapters

The server has these source adapters:

  • Gatus: The adapter uses GET /api/v1/endpoints/statuses. It selects the result with the greatest timestamp.
  • Docker Engine: The adapter uses GET /containers/json?all=true. It filters fields and does not include Config.Env.
  • Loki: The adapter uses GET /loki/api/v1/query_range. The configuration supplies the selector.
  • Healthchecks: The adapter uses GET /api/v3/checks/. It uses a read-only key and does not include ping URLs in its output.
  • Beszel: The adapter uses GET /api/systems and compatible routes. It can give a host snapshot.
  • ntfy: The adapter uses GET /{topic}/json?poll=1&since=<unix>. The configuration supplies the topic.

Destinations use only http and https. For Docker, use a read-limited socket proxy. The Docker Unix socket is not compatible with the server. The server ignores HTTP_PROXY and HTTPS_PROXY.

You can use a path prefix in base_url. For example, use https://proxy.example/gatus for Gatus. The server keeps /gatus before each Gatus API route.

Set the source cache TTL with limits.source_cache_ttl. The default is 15s; 0 disables it. Cache keys use a process-local HMAC instead of clear-text authentication values. Cache hits retain observed_at; retrieved_at records the new read time. Thus, freshness reflects the snapshot's age.

MCP tools

  • evidence_capabilities gives the version, active sources, limits, and statistics.
  • list_services gives services in the canonical service registry.
  • service_status gives a Gatus, Docker, Healthchecks, and Beszel snapshot.
  • incident_context gives a multi-source timeline with configuration limits.
  • search_logs examines Loki with the selector in the configuration.
  • failed_crons gives checks in the down, grace, or paused state.
  • get_evidence reads temporary evidence again by its opaque identifier.

All tool annotations identify the tools as read-only. Global limits control windows, HTTP body sizes, evidence counts, and concurrency.

Evidence model

Each evidence item contains its source and its observation and collection timestamps. It also contains severity, freshness state, truncation, and the redaction count. Responses give the ok, absent, skipped, error, and timeout state of each source.

See the evidence model and tested API contracts.

Security

Read SECURITY.md for guarantees and remaining risks. The primary security controls are:

  • Destinations cannot change after startup.
  • The server does not accept HTTP redirects.
  • MCP calls cannot supply a URL or stream selector.
  • Log content is hostile data.
  • The server uses built-in redaction and optional local rules.
  • On Unix, give only the owner access to configuration and token files. Use mode 0600.
  • On Windows, use a user-only ACL. The binary does not examine Windows ACLs.

Local demo

go run ./demo

The demo uses local HTTP fixtures and an in-memory MCP session. It checks source errors, redaction, instruction markers, and GET-only requests. It does not start the stdio executable or contact a homelab.

Development

make test          # tests with race detection
make test-quick    # fast tests
make lint-docs     # Markdown checks
make lint          # formatting, go vet, and golangci-lint
make coverage
make build

CI builds Linux, macOS, and Windows binaries. The primary targets are headless Linux and macOS systems.

Documentation

License

MIT. See LICENSE.