Skip to content

Local POC

Run a cost POC straight from kubectl logs when you don't want to plug log analyzer credentials into the MCP yet.

Returns three things:

  • a sample-composition table by pod,
  • an industry-pricing projection at Datadog / Splunk / CloudWatch / Sumo / Elastic / OpenSearch list rates,
  • the top patterns in the sample.

The pricing is a list-rate matrix, not a prediction of a specific bill; for that, use POC submit once credentials are in the env.

fleet_default sets the limit for every service the plan gives no row, from this capture: the largest statement the plan keeps per node, times headroom (default 2). The report states it in lines a day, and fleet_default.cap_bytes_per_window_per_node in the result is the value log10x_advise_install writes into the Receiver. On Datadog, check_dependencies (on by default) prints beside each service line the log monitors and log-based metrics whose query reads its moved lines, the error monitors of the services the fleet default covers included.

Example

You

cost POC from kubectl, namespace production, 1h

Log10x

Pulled 38,420 lines (62 MB) across 17 pods over the last 1h.

Sample composition. Confirm this matches production before trusting the projection:

Pod Bytes % of sample
production/checkout-svc-7f9d-xk2z 24 MB 39%
production/payments-svc-5b3c-h7n1 12 MB 19%
production/cart-svc-2a8e-q4r6 8 MB 13%

Projected savings at industry list pricing (extrapolated to 1.5 TB/day):

Vendor Rate Annual cost Annual savings
CloudWatch $0.50/GB $274K $76K

Top patterns: Payment_Gateway_Timeout 18% of bytes · DB_Connection_Refused 11% · Cart_Eviction_Replay 9%.

More to ask

  • "cost POC from kubectl, all namespaces, 24h"
  • "local POC against default, top-10 pods only"
  • "local POC, 6h window, max 50 pods"

Prerequisites

kubectl on PATH with a working kubeconfig. The local 10x engine runs the analysis, so it also needs:

  • the tenx CLI (install for macOS/Linux/Windows), or
  • a local Docker container (LOG10X_TENX_MODE=docker, auto-detected and preferred when the mode is unset).

There is no automatic fallthrough from POC submit when log analyzer credentials are missing. The two paths frame cost differently.

Submit predicts the prospect's actual bill; this tool emits an industry matrix. Switching framing silently would be a bait-and-switch, so the call is always explicit.

Schema and samples

Input example

Real call against the demo env (captured by scripts/capture-tool-envelopes.mjs).

{
  "source": "kubectl",
  "namespace": "*",
  "window": "1h",
  "per_pod_limit": 5000,
  "max_pods": 20
}
Input schema

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

{
  "type": "object",
  "properties": {
    "source": {
      "type": "string",
      "enum": [
        "kubectl",
        "file"
      ],
      "default": "kubectl",
      "description": "Where to pull log lines from. `kubectl` samples pod logs; `file` samples local logs — pass `paths` (files, directories, globs) or `path` (one file; fluentd/k8s/docker-wrapped JSONL is detected and normalized before the engine sees it). `docker` and `journald` are follow-up work."
    },
    "path": {
      "type": "string",
      "description": "One local log file to analyse (source=`file`). Wrapped JSONL is normalized so the engine patterns payloads, not wrappers. For many files or globs use `paths` instead."
    },
    "siem": {
      "type": "string",
      "enum": [
        "cloudwatch",
        "datadog",
        "sumo",
        "gcp-logging",
        "elasticsearch",
        "azure-monitor",
        "splunk",
        "clickhouse",
        "coralogix",
        "elastic-serverless"
      ],
      "description": "The destination SIEM, used for the report header chip and command selection. When absent the analysis assumes CloudWatch and the report labels the assumption."
    },
    "forwarder": {
      "type": "string",
      "description": "Forwarder in the pipeline (fluentd, fluent-bit, filebeat, logstash, otel-collector, vector, hec). Used to pick verified apply/undo commands. Not guessed when absent — the report says commands are unavailable."
    },
    "workload": {
      "type": "string",
      "description": "Forwarder workload name (daemonset/deployment) for the apply commands. Not guessed when absent."
    },
    "report_annotations": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      },
      "description": "Optional one-sentence annotations keyed by evidence statement identifier, rendered under the matching action. Hard cap 140 chars each; over-cap or unknown-hash input refuses the render (nothing is truncated)."
    },
    "namespace": {
      "type": "string",
      "default": "default",
      "description": "Kubernetes namespace to sample from (`source: kubectl` only). Pass `*` to sample across all namespaces. Default `default`."
    },
    "paths": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Required for `source: file`: files, directories, or glob patterns (`*`, `**`, `?`) to sample, e.g. `[\"/var/log/app/*.log\", \"./bundle/**\"]`. A directory is read one level deep; use `dir/**` for the tree."
    },
    "window": {
      "type": "string",
      "description": "How far back to read per pod (`source: kubectl`, default `1h`). For `source: file`, the time span the files cover: read from the first and last record timestamps when the records carry them, and from `window` when they do not. With neither, a file run refuses rather than assume a span. Accepts `30m`, `10h`, `7d`, etc."
    },
    "per_pod_limit": {
      "type": "number",
      "minimum": 100,
      "maximum": 50000,
      "default": 5000,
      "description": "Cap on log lines pulled per pod. Default 5000."
    },
    "max_pods": {
      "type": "number",
      "minimum": 1,
      "maximum": 200,
      "default": 20,
      "description": "Cap on number of pods sampled. Default 20."
    },
    "fleet_default": {
      "type": "object",
      "properties": {
        "headroom": {
          "type": "number",
          "minimum": 1,
          "maximum": 10,
          "description": "Multiplier on the largest kept per-node cell of the capture. Default 2."
        },
        "action": {
          "type": "string",
          "enum": [
            "tier_down",
            "offload"
          ],
          "description": "Where a statement above the limit goes: `tier_down` (Flex on Datadog, the default) or `offload` (S3)."
        },
        "error_floor": {
          "type": "number",
          "minimum": 0,
          "maximum": 1,
          "description": "Share of ERROR and CRITICAL lines above the limit kept in Standard. Default 0.5 with offload, 0 with tier_down."
        }
      },
      "additionalProperties": false,
      "description": "Set the fleet default from this capture: the limit for every service the plan gives no row, the largest statement the plan keeps per node times the headroom. The report states it in lines a day, and `fleet_default.cap_bytes_per_window_per_node` in the result is the value `log10x_advise_install` writes. On Datadog, the dependency check also lists the log monitors and log-based metrics of the services it covers, error monitors included."
    },
    "check_dependencies": {
      "type": "boolean",
      "description": "Datadog only, default true: before the plan moves statements off Standard, read the account's log monitors and log-based metrics (read-only GETs, needs DD_API_KEY + DD_APP_KEY in the session) and print beside each service line the ones whose query reads its moved lines. Set false to skip the read."
    },
    "retriever_installed": {
      "type": "boolean",
      "default": false,
      "description": "Whether the prospect will install the S3 retriever. Gates the offload rung of the plan ladder: without it offloaded events would be unreachable, so the plan stops at the in-SIEM levers and the gap names \"install the retriever\" as the lossless remedy. Set from conversation."
    },
    "allow_lossy": {
      "type": "boolean",
      "default": false,
      "description": "Permit sample/drop (lossy) to close a keep-everything shortfall. Default false: the plan stops at the keep-everything ceiling and reports the gap. Only set after the user explicitly chooses loss."
    },
    "target_percent_reduction": {
      "type": "number",
      "minimum": 0,
      "maximum": 100,
      "description": "Customer-specified target reduction percent. If absent, POC produces a recommendation-only output. If present, POC produces a feasibility verdict + a pre-deploy commitment artifact stub the agent can surface alongside the per-pod savings matrix. The cap CSV is attached by a later change."
    },
    "budget_usd_monthly": {
      "type": "number",
      "exclusiveMinimum": 0,
      "description": "DOLLAR BUDGET: keep the projected monthly bill on the assumed SIEM at or under this $/mo. The sample is scaled to a 30-day month (kubectl window, or the file span) before solving, so the budget and the bill share a denominator. Mutually exclusive with target_percent_reduction and budget_gb_monthly."
    },
    "budget_gb_monthly": {
      "type": "number",
      "exclusiveMinimum": 0,
      "description": "VOLUME BUDGET: keep projected monthly ingest at or under this many GB/mo. BYTE accounting: tier_down keeps every byte and is excluded from the ladder for this target. Sample scaled to a 30-day month before solving. Mutually exclusive with target_percent_reduction and budget_usd_monthly."
    },
    "exception_services": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Services / pods flagged by the customer to stay in the log analyzer with full retention (action=pass). Their bytes are subtracted from the achievable reduction pool used for the feasibility verdict. Matched case-insensitively against the pod / source name."
    },
    "pin_services": {
      "type": "object",
      "additionalProperties": {
        "type": "string",
        "enum": [
          "pass",
          "sample",
          "compact",
          "tier_down",
          "offload",
          "drop"
        ]
      },
      "description": "Primary per-pod/source override surface. Map of pod / source name to action. Pins are applied AFTER the destination default and AFTER exception_services. Feasibility reruns with the pins; max_achievable shifts and reason cites the pins."
    },
    "pin_patterns": {
      "type": "object",
      "additionalProperties": {
        "type": "string",
        "enum": [
          "pass",
          "sample",
          "compact",
          "tier_down",
          "offload",
          "drop"
        ]
      },
      "description": "Advanced — most customers will not need this. Map of pattern_hash to action for rare per-pattern overrides within a pod / source. Applied AFTER pin_services."
    }
  },
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}

Source: src/tools/poc-from-local.ts.

Output example

Real envelope from the demo env. view: "summary" returns the full StructuredOutput with typed data. Long arrays + base64 PNG bodies trimmed for readability; the real call returns them in full.

Headline (the 1-line agent-facing answer):

POC from kubectl: 84,210 lines from 18 pods → 142 distinct patterns, projected $86-$1,025/day across vendors.

{
  "schema_version": "1.0",
  "schema_epoch": "2026-05-25",
  "tool": "log10x_poc_from_local",
  "view": "summary",
  "summary": {
    "headline": "POC from kubectl: 84,210 lines from 18 pods → 142 distinct patterns, projected $86-$1,025/day across vendors."
  },
  "data": {
    "ok": true,
    "source": "kubectl",
    "namespace": "*",
    "window": "1h",
    "pods_sampled": 18,
    "pods_failed": 2,
    "events_pulled": 84210,
    "total_bytes": 32814220,
    "distinct_patterns": 142,
    "daily_gb_projection": 0.732,
    "daily_dollar_projection_low": 86,
    "daily_dollar_projection_high": 1025,
    "notes": [
      "18 pods read; 2 pods failed (access denied)"
    ]
  },
  "actions": [
    {
      "tool": "log10x_resolve_batch",
      "args": {
        "source": "text",
        "text": "..."
      },
      "reason": "run the same sample through resolve_batch for per-pattern variable concentration + next actions"
    }
  ],
  "generated_at": "2026-05-26T00:00:00.000Z"
}
Output schema

The data block inside the StructuredOutput envelope:

interface ToolData {
  ok: boolean;
  source: string;
  namespace: string;
  window: string;
  pods_sampled: number;
  pods_failed: number;
  events_pulled: number;
  total_bytes: number;
  distinct_patterns: number;
  daily_gb_projection: number;
  daily_dollar_projection_low: number;
  daily_dollar_projection_high: number;
  notes: string[];
}

Envelope-level fields the agent should also read: summary.headline (1-line answer), actions[] (next-call chain hints as {tool, args, reason}), truncated: boolean, images[] (PNG attachments where applicable), schema_epoch (engine-ID stability boundary).