Skip to main content
Glama

ssh_kubectl_read

Read-only

Run one allowlisted, read-only kubectl command INSIDE an Ankra-provisioned cluster (Hetzner, OVH, UpCloud, DigitalOcean or Scaleway) by executing it on a control-plane node over SSH-via-bastion, using that node's own admin kubeconfig. REACH FOR THIS ONLY WHEN THE CLUSTER'S AGENT IS NOT ANSWERING. While the agent is checking in, a get, describe, logs or events call here is REFUSED and names the tool to use instead: get_pods or cluster_query, describe_resource, get_pod_logs, get_events. Those answer the same question in one call, while this one dials the bastion, runs kubectl as cluster-admin and holds a scheduler job for up to 90 seconds. When the agent stops checking in they stop being an option - get_pod_logs and query_logs refuse outright, and the resource reads fall back to a cached inventory from before the outage - and this becomes the only live view left, because it does not use the agent at all; every result is stamped source=break_glass_ssh with executed_at. That is the state to use it in: to find out what is actually wrong with the agent itself - is its Deployment rolled out, is its pod Pending or CrashLoopBackOff or bound to a dead node, what do its logs and events say. If the agent IS checking in and you still need this, it is because an agent-path read already failed this turn (CLUSTER_OFFLINE, NO_AGENT or AGENT_TIMEOUT) or the tool it named refuses what you asked it for - get_pod_logs serves previous=true only on agent 2.1.1058 or newer, and refuses below it: set agent_path_unavailable=true, which is honoured and recorded. Verbs: get, describe, logs, events, top, version, api_resources, rollout_status. This is an allowlist, not a shell: there is no exec, port-forward, apply, patch, edit, create, scale, drain, cp, --raw, jsonpath or go-template, and no way to pass raw flags. Structured output (yaml/json) of Secrets is refused, though get and describe of them still report names, types and key names. Output is capped and credential-shaped strings are redacted. The command runs on a control-plane node, chosen automatically unless you pass node_id/node_name. Not available for imported or managed-Kubernetes clusters (they have no bastion), nor (yet) Proxmox/HPE Morpheus. Read-only: use ssh_kubectl_recover to change anything.

Input Schema

NameRequiredDescriptionDefault
kindNoResource type, e.g. 'pods', 'deployments', 'nodes', 'deployments.apps'. Required by get, describe, top and rollout_status. MUST BE OMITTED for logs, events, version and api_resources - for logs the pod name goes in 'name'. Naming the kind a verb already implies (kind=pods on logs, kind=events on events) is accepted and ignored; a kind that contradicts the verb is refused.
nameNoObject name. For get and describe it narrows to one object (omit for a listing); for logs it is the pod name; for rollout_status it is required.
verbYesWhich read to perform. get lists or shows resources; describe gives the detailed view including a pod's events and container statuses; logs reads container logs; events lists namespace events newest-last; top reports resource usage (nodes or pods); version reports the server version; api_resources lists available kinds; rollout_status reports whether a rollout completed (it waits up to 30s).
outputNoOutput format for get. Omit for a table. 'wide' adds node and IP columns and is usually the right choice. yaml/json of Secrets is refused.
node_idNoUUID of the control-plane node to run the command on (from list_cluster_nodes). Optional: a healthy control-plane node is chosen automatically.
previousNoRead the PREVIOUS container instance's logs. This is what shows why a CrashLoopBackOff pod died, since the current instance has usually not started.
selectorNoLabel selector in k=v[,k=v] form with NO spaces, e.g. 'app.kubernetes.io/name=ankra-agent'. For logs it selects the pods to read.
containerNoContainer name, for logs on a multi-container pod.
namespaceNoNamespace to scope to. Mutually exclusive with all_namespaces.
node_nameNoExact name of the control-plane node to run the command on. Alternative to node_id.
cluster_idNoUUID of the cluster. Optional when a cluster is selected.
tail_linesNoHow many log lines to return (default 200, maximum 2000).
cluster_nameNoExact name of the cluster. Optional when a cluster is selected.
since_secondsNoOnly return log lines from the last N seconds.
all_namespacesNoQuery every namespace. Mutually exclusive with namespace.
field_selectorNoField selector in path=value[,path=value] form with no spaces, e.g. 'involvedObject.name=ankra-agent-xyz' to get the events for one object, or 'status.phase=Pending' to list only pending pods.
agent_path_unavailableNoSet true ONLY when the cluster's agent is checking in but the agent path still cannot answer: an agent-path read already failed this turn with CLUSTER_OFFLINE, NO_AGENT or AGENT_TIMEOUT, or you need previous=true (a crashed container's earlier logs) on a cluster whose agent is older than 2.1.1058, where get_pod_logs refuses it. It bypasses the refusal that otherwise sends get/describe/logs/events calls to get_pods, describe_resource, get_pod_logs or get_events, and every call is logged with this flag set.

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

A4.8/5.0
Behavior5/5

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

With only readOnlyHint=true in annotations, the description carries the load and does so richly: runs kubectl as cluster-admin over a bastion, holds a scheduler job up to 90s, results stamped source=break_glass_ssh with executed_at, output capped and credential-shaped strings redacted, Secrets yaml/json refused, no raw flags or exec/apply, and unsupported cluster types (imported/managed, Proxmox/Morpheus). This is far beyond what the annotation declares.

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

Conciseness4/5

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

The routing decision is front-loaded in the first sentence and the refusal/fallback logic follows in priority order, so an agent can act after one line. It is still very long and dense with some restatement (the refusal target tools are named twice), which costs a point but the length is largely earned by the tool's unusual gating.

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

Completeness5/5

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

For a 17-parameter, one-required, allowlist-gated diagnostic tool with no output schema, the description covers the mechanism, preconditions, failure modes, refusals, redaction, and cluster-type exclusions. Nothing an agent needs to decide whether and how to call it is missing.

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

Parameters4/5

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

Schema description coverage is 100%, so the per-parameter contract is already documented and the baseline is 3. The description does add genuine cross-parameter meaning: it frames the verb list as an allowlist rather than a shell (no exec/port-forward/apply/patch/jsonpath), clarifies that control-plane node selection is automatic unless node_id/node_name is passed, and ties agent_path_unavailable to a logged override, which the schema only states narrowly.

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?

States a specific verb+resource+mechanism: it runs one allowlisted read-only kubectl command inside a provisioned cluster over SSH-via-bastion on a control-plane node. It explicitly enumerates the sibling tools it is not (get_pods, cluster_query, describe_resource, get_pod_logs, get_events), so an agent can route without opening any schema.

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

Usage Guidelines5/5

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

Gives an explicit gating condition ('REACH FOR THIS ONLY WHEN THE CLUSTER'S AGENT IS NOT ANSWERING'), explains the refusal behavior while the agent is checking in, describes the fallback semantics once the agent stops checking in, and names the exact override flag (agent_path_unavailable=true) plus the trigger conditions (CLUSTER_OFFLINE, NO_AGENT, AGENT_TIMEOUT, previous=true on pre-2.1.1058 agents).

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources