Table of Contents

Setup

This page documents Orleans.Lattice.Api.Mcp.Telemetry 9.9.0, in the documentation for Orleans.Lattice 9.9.0 (release line 9.9), built 2026-10-04. It is also published as markdown, with every table and list, at setup.md, and llms.txt lists every page.

Registering the Orleans.Lattice.Api.Mcp.Telemetry tool module on an MCP host, pointing it at a metrics backend, and configuring the credential, guardrails, and metric-access allow-list.

Prerequisites

The telemetry tools plug into the Orleans.Lattice.Api.Mcp binding, so the host must:

  • Have called AddLatticeMcp(...) (co-hosted) or AddLatticeMcpRemote(...) (remote) to register the MCP front door - see MCP setup.
  • Reach a read-only Prometheus / PromQL-compatible HTTP backend that scrapes the cluster's orleans.lattice metrics - see Metrics.

The telemetry tools call no Orleans.Lattice.Api.* facade and need no in-silo activation: they proxy the metrics backend directly, so the module can run co-hosted on a silo or on a remote head. Discovery still needs the caller's effective permissions, as for every group - the auth facade (AddLatticeAuthApi()) when co-hosted, or the Auth endpoint on a remote head (see MCP setup).

Register the tool module

AddTelemetryTools(...) binds and validates LatticeApiMcpTelemetryOptions, registers the default HTTP-backed backend client (unless the host registered its own IPrometheusQueryClient first) and the metric-access policy (the policy is built once, with its wildcard patterns precompiled), registers the TelemetryAccessAuthorizer every tool consults at call time, and registers the telemetry tool group so its tools are advertised to a caller holding a cluster-wide LatticeOperation.Telemetry grant. It is idempotent: calling it twice registers exactly one tool group and one backend client.

using Orleans.Lattice.Api.Mcp.Telemetry;

var services = new ServiceCollection();
services.AddLatticeMcp();

services.AddTelemetryTools(o =>
{
    o.BackendAddress = new Uri("https://prometheus.internal:9090/");
    o.RequestTimeout = TimeSpan.FromSeconds(30);
    o.MaxRange = TimeSpan.FromHours(24);
    o.MaxStep = TimeSpan.FromHours(1);
});

Options

LatticeApiMcpTelemetryOptions (populated through the AddTelemetryTools delegate):

Option Type Default Purpose
BackendAddress Uri? none The absolute base address of the read-only Prometheus / PromQL-compatible backend. A host that opts telemetry in must supply one.
AuthMode LatticeTelemetryBackendAuthMode None How the proxy authenticates to the backend: None, Bearer, Basic, MutualTls, or DynamicBearer. The static modes require the matching Credential member; DynamicBearer instead requires a registered ITelemetryBackendTokenProvider.
Credential LatticeTelemetryBackendCredential? null The backend credential secret, consulted per AuthMode. Carries the backend credential only - never the caller's Lattice credential.
RequestTimeout TimeSpan 30s The per-request timeout for a backend call. Must be strictly positive and no longer than int.MaxValue milliseconds (about 24.8 days), the longest finite timeout HttpClient accepts.
MaxRange TimeSpan 24h The largest window (end - start) a single range query may span. Must be strictly positive.
MaxStep TimeSpan 1h The largest resolution step a single range query may request. Must be strictly positive.
MetricAccess LatticeTelemetryMetricAccessMode ReadAll ReadAll exposes every backend metric; DenyAllExceptAllowed restricts the surface to AllowedMetrics.
AllowedMetrics IList<string> empty Exact names and/or *-wildcard patterns permitted under DenyAllExceptAllowed. Ignored under ReadAll.

The options are validated when they are first resolved - the binding registers no start-up validation, so a misconfiguration surfaces as an OptionsValidationException on first use rather than at host start: the backend address must be an absolute URI, the timeouts and range guardrails must be strictly positive (and the request timeout no longer than HttpClient accepts), each static non-None auth mode must carry its matching credential member (DynamicBearer carries no static credential and instead resolves a token provider at request time), and DenyAllExceptAllowed must list at least one allowed metric, with no null, empty, or whitespace entry.

Backend authentication

Pick the mode that matches the backend and supply the matching Credential member:

using Orleans.Lattice.Api.Mcp.Telemetry;

var services = new ServiceCollection();
services.AddLatticeMcp();

// HTTP basic authentication to the backend.
services.AddTelemetryTools(o =>
{
    o.BackendAddress = new Uri("https://prometheus.internal:9090/");
    o.AuthMode = LatticeTelemetryBackendAuthMode.Basic;
    o.Credential = new LatticeTelemetryBackendCredential
    {
        BasicUsername = "lattice-reader",
        BasicPassword = "backend-secret",
    };
});
  • Bearer stamps Authorization: Bearer <token> from Credential.BearerToken.
  • Basic stamps Authorization: Basic <base64(user:password)> from Credential.BasicUsername / Credential.BasicPassword.
  • MutualTls presents Credential.ClientCertificate on the transport handler (no Authorization header).
  • None sends no credential.
  • DynamicBearer stamps a rotating Authorization: Bearer token fetched per request from a registered ITelemetryBackendTokenProvider, instead of a static Credential. Use it when the backend needs a short-lived token that rotates (for example an Entra token for Azure Monitor managed Prometheus). Register a provider that implements the seam - the Orleans.Lattice.Api.Mcp.Telemetry.Azure companion supplies an Azure managed-identity one. The proxy fails closed if DynamicBearer is selected with no provider registered, or if the provider returns an empty token - it never sends an unauthenticated backend query.

Restrict the metric surface

By default the proxy reads any metric the backend exposes. To limit it to an explicit allow-list, switch to DenyAllExceptAllowed and list the exact names and/or * patterns:

using Orleans.Lattice.Api.Mcp.Telemetry;

var services = new ServiceCollection();
services.AddLatticeMcp();

services.AddTelemetryTools(o =>
{
    o.BackendAddress = new Uri("https://prometheus.internal:9090/");
    o.MetricAccess = LatticeTelemetryMetricAccessMode.DenyAllExceptAllowed;
    o.AllowedMetrics.Add("orleans_lattice_shard_writes_total"); // exact name
    o.AllowedMetrics.Add("orleans_lattice_wal_*");              // wildcard pattern
});

Wildcard patterns are precompiled once when the policy is built, so a per-call admission check never recompiles a pattern. See Security for how the allow-list is enforced across the four tools.

Next

  • Tools - the four telemetry tools and their arguments and results.
  • Security - the dual-credential trust boundary and the metric-access allow-list.