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) orAddLatticeMcpRemote(...)(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.latticemetrics - 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",
};
});
BearerstampsAuthorization: Bearer <token>fromCredential.BearerToken.BasicstampsAuthorization: Basic <base64(user:password)>fromCredential.BasicUsername/Credential.BasicPassword.MutualTlspresentsCredential.ClientCertificateon the transport handler (noAuthorizationheader).Nonesends no credential.DynamicBearerstamps a rotatingAuthorization: Bearertoken fetched per request from a registeredITelemetryBackendTokenProvider, instead of a staticCredential. 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 - theOrleans.Lattice.Api.Mcp.Telemetry.Azurecompanion supplies an Azure managed-identity one. The proxy fails closed ifDynamicBeareris 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.