Skip to main content
Glama
BenedatLLC

Kubernetes Tools MCP Server

by BenedatLLC

get_logs_for_pod_and_container

Retrieve logs from a Kubernetes pod and container to debug errors, inspect crash loops, or review recent output. Use tail, since_seconds, or previous for targeted analysis.

Instructions

Retrieves logs from a Kubernetes pod and container.

Args:
    pod_name (str): The name of the pod.
    namespace (str): The namespace of the pod.
    container_name (str, optional): The name of the container within the pod.
                                    If None, defaults to the first container.
    tail (int, optional): Number of lines to return from the end of the log.
                          If None, defaults to the last 1000 lines. Pass a
                          larger value to retrieve more history, or a small
                          value for a bounded recent slice.
    since_seconds (int, optional): If set, only return logs newer than this
                          many seconds. Combines with `tail` (both limits
                          apply).
    previous (bool, default False): If True, return logs from the *previous*
                          terminated instance of the container instead of the
                          current one. Indispensable for crashloop analysis,
                          where the current instance's logs are empty or
                          post-restart. Fails if there is no previous instance.

                          Three Kubernetes behaviors make `previous=True`
                          look as though it were ignored or broken; none is a
                          fault in this tool, and all are worth knowing before
                          drawing a conclusion from the output:

                          * While a container sits in CrashLoopBackOff there
                            is no running instance, so the kubelet serves the
                            most recently *terminated* one for `previous=False`
                            as well - both calls then return the same text.
                            Check the container's state with
                            `get_pod_container_statuses` before concluding the
                            flag had no effect.
                          * A restart between two calls shifts the window: the
                            instance that was current becomes the previous one,
                            so a container crash-looping every few seconds can
                            legitimately return identical bytes for both.
                            Compare the log timestamps, not just the flag.
                          * Once the previous instance's log file has been
                            reclaimed, the API answers 200 with the text
                            `unable to retrieve container logs for <id>` -
                            a successful call whose body is an error message,
                            not a raised error.

                          Only the single most recent terminated instance is
                          retained by the kubelet; there is no way to reach
                          further back than one.

Returns:
    str: The log content as text, with real newlines. An empty string if the
         container has produced no log output (never None).

Raises
------
K8sConfigError
    If unable to initialize the K8S API.
K8sApiError
    If the API call to fetch logs fails or an unexpected error occurs.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
tailNo
pod_nameYes
previousNo
namespaceNodefault
since_secondsNo
container_nameNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changedv2.1.0
    • addedInput schema / properties / previous
      Added value: +{
      +  "default": false,
      +  "title": "Previous",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / since_seconds
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Since Seconds"
      +}
    • addedInput schema / properties / tail
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Tail"
      +}
  2. First observed

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral burden and meets it: it documents the CrashLoopBackOff overlap, the restart window shift, the 200-with-error-text-body case, and the one-instance retention limit. It also lists raised errors and return-type guarantees (empty string, never None).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose, args, and returns are front-loaded and clean, but the previous parameter's three-bullet caveat block is long and sits inside the args section rather than after it. The operational warnings are valuable yet could be tightened without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read tool with six parameters and an output schema, the description covers return semantics, error paths, and the subtlest failure modes comprehensively. It omits no critical invocation detail, though the oversized previous section slightly dilutes the overall completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden, and it does: it defines every parameter, documents defaults (first container, last 1000 lines, namespace default not restated), and explains how tail and since_seconds combine. The detailed previous semantics go well beyond a simple enumeration.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource ("Retrieves logs from a Kubernetes pod and container") that unambiguously distinguishes it from siblings such as get_logs_for_job and get_logs_for_cronjob, which target different workload artifacts. The agent can select this tool without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives strong conditional guidance for the previous flag (use it for crashloop analysis, fall back to get_pod_container_statuses if results look identical), which is explicit when-to-use context. It doesn't name the job/cronjob log siblings or explain when to prefer them, but the pod/container scope makes the boundary reasonably clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.