Recommend
After Discover env ran, pick the right Log10x app to deploy and get its plan. Returns a ranked comparison across Reporter, Receiver, and Retriever when no goal is set, or a single concrete checklist when a goal is given (cut-cost, compact, archive, just-metrics).
Example
You
ranked install paths for snap-abc123
Log10x
Top pick: Reporter (standalone DaemonSet). No forwarder changes required.
| Path | Status | Why |
|---|---|---|
| Reporter standalone | ✓ ready | parallel DaemonSet, no forwarder edits |
| Receiver inline (filter) | ✓ ready | fluent-bit detected, Helm-managed |
| Receiver inline (compact) | ✓ ready | fluent-bit + Helm + verified path |
| Retriever | ✗ blocked | missing S3 bucket, SQS queues, IRSA role |
Re-run with goal=cut-cost (or compact / archive / just-metrics) for a concrete plan instead of a comparison.
More to ask
- "concrete plan: cut logging costs"
- "compact-mode plan, fluent-bit"
- "archive plan with
lx_live_...key"
Prerequisites
A fresh snapshot_id from Discover env. No Log10x components needed.
Schema and samples
Input example
Representative call (synthetic, not captured from the live demo env).
Input schema
Agent-facing JSON Schema (the canonical shape the MCP server publishes via tools/list):
{
"type": "object",
"properties": {
"snapshot_id": {
"type": "string",
"description": "ID returned by `log10x_discover_env`. The snapshot is cached for 30 min."
},
"app": {
"type": "string",
"enum": [
"reporter",
"receiver"
],
"description": "Which Log10x app to install. **reporter** = a dedicated DaemonSet forwarder (zero-touch, runs alongside your existing forwarder); **receiver** = a sidecar plugged into your existing forwarder (filters/samples/compacts events in-flight). When omitted, the wizard asks the user."
},
"forwarder": {
"type": "string",
"enum": [
"fluentbit",
"fluentd",
"filebeat",
"logstash",
"otel-collector",
"vector"
],
"description": "Receiver-only: which detected forwarder kind to sidecar into. Auto-uses the snapshot's detected forwarder when there's exactly one; the wizard asks when there are multiple."
},
"backends": {
"type": "array",
"items": {
"type": "string",
"enum": [
"log10x",
"datadog",
"elastic",
"cloudwatch",
"signalfx",
"prometheus"
]
},
"description": "Where the engine emits TenXSummary metrics. Multi-destination — a user can report to log10x SaaS AND their own backend simultaneously, e.g. `[\"log10x\", \"datadog\"]`. Choices: **log10x** (Log10x-managed Prometheus — recommended; no infra to run), **datadog**, **elastic**, **cloudwatch**, **signalfx**, **prometheus** (customer-owned). The wizard pre-fills detected backends from the snapshot. The only mutual exclusion is `airgapped: true` + `\"log10x\"` in this list."
},
"airgapped": {
"type": "boolean",
"description": "When true, the Log10x agents send nothing to log10x.com — engine metrics, license re-validation, and update checks all go silent. Use to reduce CISO friction. Conflicts with `\"log10x\"` in `backends` (the wizard surfaces the conflict). **Demo licenses cannot actually run airgapped** — the engine downgrades to online mode with a warning. The wizard surfaces this softly when both are picked."
},
"backend_credentials": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"secretName": {
"type": "string",
"description": "Name of the Kubernetes Secret holding sensitive env vars for this backend."
},
"plainValues": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Non-sensitive env var overrides keyed by env var name (e.g., `{ DD_SITE: \"us5.datadoghq.com\" }`)."
}
},
"required": [
"secretName"
],
"additionalProperties": false
},
"propertyNames": {
"enum": [
"log10x",
"datadog",
"elastic",
"cloudwatch",
"signalfx",
"prometheus"
]
},
"description": "Per-backend credential configuration, keyed by backend kind (must be one of: log10x, datadog, elastic, cloudwatch, signalfx, prometheus). **Only set for non-`log10x` backends** — `log10x` SaaS uses the license JWT and needs no extra credentials. Each entry has a `secretName` (the Kubernetes Secret the user creates out-of-band holding sensitive env vars like `DD_API_KEY`; default per backend is `<backend>-credentials`) and optional `plainValues` (overrides for non-sensitive env vars like `DD_SITE`). Example: `{ \"datadog\": { \"secretName\": \"datadog-secret\", \"plainValues\": { \"DD_SITE\": \"us5.datadoghq.com\" } } }`."
},
"license_source": {
"type": "string",
"enum": [
"signin",
"demo",
"paste"
],
"default": "signin",
"description": "How the wizard should acquire the engine's license JWT. **Defaults to `\"signin\"`** when omitted — the wizard tries to mint a user-scoped license via the user's Auth0 session, and emits `signin_required` mode (chain through `log10x_signin_start` then re-invoke) when no session exists. Pass **`\"demo\"`** ONLY when the user explicitly asks for a quick 14-day anonymous demo (transient, can't run airgapped). Pass **`\"paste\"`** with `license_jwt_paste: \"<jwt>\"` when the user already has a JWT."
},
"license_jwt_paste": {
"type": "string",
"description": "License JWT supplied by the user when `license_source: \"paste\"`. Mints from `POST /api/v1/license` (signed-in) or `POST /api/v1/license/demo` (anonymous). Maps to the chart's license Secret."
},
"namespace": {
"type": "string",
"description": "Target namespace. Default: snapshot.recommendations.suggestedNamespace."
},
"release_name": {
"type": "string",
"description": "Helm release name. Default: `my-<app>` (e.g., `my-reporter`)."
},
"action": {
"type": "string",
"enum": [
"install",
"verify",
"teardown",
"all"
],
"description": "Plan scope when the wizard is ready to emit. Default: `all`."
}
},
"required": [
"snapshot_id"
],
"additionalProperties": false
}
Source: src/tools/advise-install.ts.
Output example
Representative envelope (synthetic, not captured from the live demo env). view: "summary" returns the full StructuredOutput with typed data.
Headline (the 1-line agent-facing answer):
receiver all plan on fluentbit: 6 install / 4 verify / 3 teardown, release "my-receiver" in namespace "logging".
{
"schema_version": "1.0",
"schema_epoch": "engine-1.0.9",
"tool": "log10x_advise_install",
"view": "summary",
"summary": {
"headline": "receiver all plan on fluentbit: 6 install / 4 verify / 3 teardown, release \"my-receiver\" in namespace \"logging\"."
},
"data": {
"mode": "plan",
"ok": true,
"app": "receiver",
"snapshot_id": "snap-abc123",
"release_name": "my-receiver",
"namespace": "logging",
"forwarder": "fluentbit",
"action": "all",
"preflight": [
{ "name": "namespace exists", "status": "ok", "detail": "logging present" },
{ "name": "helm release detected", "status": "ok", "detail": "fluent-bit v0.46.0" }
],
"preflight_summary": { "ok": 2, "warn": 0, "fail": 0, "unknown": 0 },
"install_step_count": 6,
"install_file_count": 2,
"install_requires_chmod": false,
"license_kind": "user-scoped",
"install_mode": "upgrade-existing",
"existing_helm_release": { "name": "fluent-bit", "namespace": "logging" },
"verify_probe_count": 4,
"verify_probes": [
{
"name": "engine pod Ready",
"question": "Is the Log10x sidecar Ready?",
"commands": ["kubectl -n logging get pods -l app=fluent-bit"],
"expectOutput": "1/1 Running",
"timeoutSec": 60
}
],
"teardown_step_count": 3,
"blockers": [],
"notes": [
"license JWT pre-filled from signed-in user session",
"metrics emit to log10x SaaS via license JWT"
],
"has_gitops_section": false,
"human_summary": "Install wizard produced a receiver all plan on fluentbit for release \"my-receiver\" in namespace \"logging\". 6 install steps across 2 files, 4 verify probes. Preflight: 2 ok, 0 warn, 0 fail.",
"markdown": "# Receiver install plan\n\n..."
},
"actions": [
{
"tool": "log10x_doctor",
"args": {},
"reason": "verify the install once the helm release rolls out, checks engine pods Ready, metrics flowing, license-Secret mounted",
"role": "optional-followup"
},
{
"tool": "log10x_top_patterns",
"args": {},
"reason": "once events are flowing, see which patterns dominate cost and offer mitigation via log10x_pattern_mitigate",
"role": "optional-followup"
}
],
"warnings": [],
"truncated": false
}
Output schema
The data block inside the StructuredOutput envelope:
interface ToolData {
// Discriminated union over every wizard outcome. Agents read
// `data.mode` and narrow to the per-mode shape.
mode:
| 'plan'
| 'next_question'
| 'missing_snapshot'
| 'session_error'
| 'cancelled'
| 'license_error'
| 'signin_required'
| 'demo_airgapped_warning'
| 'unknown_args';
ok: boolean;
snapshot_id?: string;
markdown: string;
human_summary: string;
// mode === 'next_question'
question_id?:
| 'app'
| 'forwarder'
| 'no-forwarder'
| 'backends'
| 'airgapped-log10x-conflict'
| 'backend-credentials'
| 'airgapped'
| 'license-paste';
shape?: unknown;
// mode === 'license_error'
error_message?: string;
// mode === 'demo_airgapped_warning'
is_signed_in?: boolean;
// mode === 'unknown_args'
unknown_keys?: string[];
suggestions?: Array<{ unknown: string; did_you_mean: string | null }>;
valid_keys?: string[];
// mode === 'plan', fields below come from AdvisePlanSummary.
app?: 'reporter' | 'receiver' | 'retriever';
release_name?: string;
namespace?: string;
forwarder?: string;
action?: 'install' | 'verify' | 'teardown' | 'all';
preflight?: Array<{
name: string;
status: 'ok' | 'warn' | 'fail' | 'unknown';
detail: string;
}>;
preflight_summary?: { ok: number; warn: number; fail: number; unknown: number };
install_step_count?: number;
install_file_count?: number;
install_requires_chmod?: boolean;
license_kind?: 'user-scoped' | 'demo' | 'user-pasted' | 'placeholder';
install_mode?: 'upgrade-existing' | 'fresh-release';
existing_helm_release?: { name: string; namespace: string };
verify_probe_count?: number;
verify_probes?: Array<{
name: string;
question: string;
commands: string[];
expectOutput?: string;
timeoutSec?: number;
}>;
teardown_step_count?: number;
blockers?: string[];
notes?: string[];
has_gitops_section?: boolean;
}
Envelope-level fields the agent should also read: summary.headline (1-line answer), actions[] (next-call chain hints as {tool, args, reason}, e.g. log10x_doctor post-install, log10x_signin_start when signin is required), truncated: boolean, warnings[] (plan blockers, demo-license caveats), schema_epoch (engine-ID stability boundary).