---
title: "Advise"
description: "Picks among the three app-specific advisors, returning a ranked list of install paths or a concrete plan for the best match."
icon: material/compass-outline
---

After [Discover env](discover-env.md) ran, pick the right Log10x app to deploy and get its plan.

It returns a ranked comparison across Reporter, Receiver, and [Retriever](advise-retriever.md) when no goal is set, or a single concrete checklist when a goal is given (`cut-cost`, `compact`, `archive`, `just-metrics`).

On a serverless snapshot (Lambda functions running an OTel collector extension, no reachable cluster) the Kubernetes wizard is skipped entirely: the tool returns the [Extension](../../../../engine/launcher/extension.md) plan, collector splice, engine environment, CDK construct, and the Coralogix TCO policy path.

An Azure serverless snapshot (Function Apps, no cluster, no Lambda) returns the [Streams](../../../../engine/launcher/streams.md) plan instead: Event Hub setup, the certified collector configuration, and the engine environment. Function Apps offer no process slot, so regulation runs centrally.

## :material-code-braces: Example

!!! tenx-ask "You"

    ranked install paths for `snap-abc123`

!!! tenx-answer "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.

## :material-chat-question-outline: More to ask

- *"concrete plan: cut logging costs"*
- *"compact-mode plan, fluent-bit"*
- *"archive plan with `lx_live_...` key"*

## :material-check-decagram-outline: Prerequisites

A fresh `snapshot_id` from [Discover env](discover-env.md). No Log10x components needed.

## :material-code-json: Schema and samples

??? tenx-input-example "Input example"

    Representative call (synthetic, not captured from the live demo env).

    ```json
    {
      "snapshot_id": "snap-abc123",
      "app": "receiver",
      "forwarder": "fluentbit",
      "backends": ["log10x"]
    }
    ```

??? tenx-input-schema "Input schema"

    Agent-facing JSON Schema (the canonical shape the MCP server publishes via `tools/list`):

    ```json
    {
      "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",
              "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** (optional Log10x-hosted backend, for evaluation), **datadog**, **elastic**, **cloudwatch**, **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",
              "prometheus"
            ]
          },
          "description": "Per-backend credential configuration, keyed by backend kind (must be one of: log10x, datadog, elastic, cloudwatch, 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,
      "$schema": "http://json-schema.org/draft-07/schema#"
    }
    ```

    Source: [`src/tools/advise-install.ts`](https://github.com/log-10x/log10x-mcp/blob/main/src/tools/advise-install.ts).

??? tenx-output-example "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"._

    ```json
    {
      "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
    }
    ```

??? tenx-output-schema "Output schema"

    The `data` block inside the [StructuredOutput envelope](../index.md#json-by-default-output):

    ```typescript
    interface ToolData {
      // Discriminated union over every wizard outcome. Agents read
      // `data.mode` and narrow to the per-mode shape.
      mode:
        | 'plan'
        | 'serverless_plan'
        | 'azure_serverless_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 === 'serverless_plan'
      estate?: 'serverless';
      function_count?: number;
      functions_with_otel_extension?: number;
      log_groups_unsubscribed?: number;

      // mode === 'azure_serverless_plan'
      function_app_count?: number;
      container_app_count?: number;
      event_hub_namespace_count?: number;

      // 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).
