cluster_query
Structured SQL-backed lookup against the agent's synced resource index (the k8s_resources cache): a Postgres read, NOT a live cluster read - it never contacts the agent and never escalates on its own. Sub-50ms. Use it for exact lookups, label selectors, and JSONB-path filters, and prefer it over the get_pods / get_deployments / get_services / get_configmaps wrappers for inventory and filtering questions. When you need the live object - verifying a change you just made, or confirming state a write depends on - read through the agent with those wrappers or describe_resource. Every item carries last_seen_at and staleness_seconds: seconds since the sync last CONFIRMED the row, not since it changed (unchanged rows are re-confirmed on a heartbeat, K8S_LAST_SEEN_REFRESH_SECONDS, default 480, so a few hundred seconds is healthy). The payload carries an advisory stale_fallback_required, set when any returned row is older than K8S_CACHE_MAX_STALENESS_SECONDS (default 300). Reads ONE cluster: the conversation's, or the one cluster_name / cluster_id names. It never spans the organisation; off-cluster with several readable clusters it refuses and lists them. A list that names no namespace reads every namespace of the cluster and says so in a note; pass namespace to narrow it. Returns one summary row per match - name, namespace and the kind's status fields (phase, ready, restarts, node and reason for a Pod; ready/desired and the first unmet condition for a workload; type, reason, object and message for an Event) - failed and not-ready objects first, with total (every match, before the limit), returned, truncated, scope and a citation marker. Labels, annotations and the full status are one cluster_describe away.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | Kubernetes Kind (e.g. 'Pod', 'Deployment', 'Service', 'CustomResourceDefinition'). | |
| name | No | Optional exact resource name. | |
| limit | No | Maximum rows to return (default 100, max 500). | |
| namespace | No | Namespace filter. Omit it to read every namespace, and for cluster-scoped kinds. | |
| cluster_id | Yes | Ankra cluster id (UUID) the call targets. Discover ids with list_clusters. | |
| all_namespaces | No | Set true to read every namespace on the cluster. A list with neither namespace nor this flag reads every namespace too, and its payload carries a note saying so. | |
| field_selector | No | Optional exact-match field filters against the resource index. Each dotted path is routed to the column that stores it: 'status.<field>' reads the status document (example: {"status.phase": "Running"}), 'spec.<field>' and a bare '<field>' read the spec document (example: {"spec.nodeName": "worker-1"}), and 'metadata.name' / 'metadata.namespace' match the identity columns. Nested fields keep their dots ({"spec.template.spec.serviceAccountName": "api"}). Any other path is rejected with an error; filter on labels with label_selector. | |
| label_selector | No | Optional label selector (k8s syntax: 'app=foo,tier=frontend'). |