Skip to main content
Glama
rad-security

RAD Security

Official
by rad-security

radql_query

Execute RadQL queries to filter, search, and analyze security data in Kubernetes environments for investigations and aggregations.

Instructions

Execute RadQL queries for security investigations. Supports: list (filter/search), get_by_id (single item), stats (aggregations).

WORKFLOW: radql_list_data_types -> radql_get_type_metadata -> radql_query

COMMON FIELDS BY DATA TYPE: containers: name, image_name, image_repo, owner_kind, cluster_id, created_at Example: image_name:nginx AND owner_kind:Pod

finding_groups: type, source_kind, source_name, rule_title, severity, event_timestamp Types: k8s_misconfiguration, k8s_audit_logs_anomaly, threat_vector Example: type:k8s_misconfiguration AND severity:critical

inbox_items: severity (High|Medium|Low), type, title, archived, false_positive, created_at Example: severity:High AND archived:false

kubernetes_resources: kind, name, namespace, cluster_id, owner_kind, created_at Example: kind:Deployment AND namespace:production

CRITICAL QUOTING RULES: MUST quote when value contains:

  • Dates/timestamps: created_at>"2024-01-01" (NOT created_at>2024-01-01)

  • Hyphens: cluster_id:"abc-123-def", name:"kube-system"

  • UUIDs: id:"550e8400-e29b-41d4-a716-446655440000"

  • Spaces: title:"my alert"

  • Special chars: :, =, <, >, !, (, )

  • Wildcards with hyphens: name:"kube-*"

OK to leave unquoted:

  • Simple strings: status:active, kind:Pod

  • Numbers: count:123

  • Booleans: archived:true

  • Simple wildcards: name:nginx*

For complete schema: call radql_get_type_metadata with target data_type

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
data_typeYesThe data type to query (e.g., 'containers', 'kubernetes_resources', 'inbox_items'). Use radql_list_data_types to discover available types.
operationYesThe operation to perform: 'list' for filtering/searching, 'get_by_id' for single item, 'stats' for aggregations
filters_queryNoRadQL filter query (e.g., 'severity:High AND type:misconfiguration'). Used for filtering results.
stats_queryNoRadQL analytics query (e.g., 'count() by severity'). Used for aggregations and grouping.
idNoThe ID of a specific item to retrieve (for get_by_id operation)
limitNoMaximum number of results to return
offsetNoPagination offset
include_relationsNoRelations to include (e.g., ['owner'] for containers to include Kubernetes owner resource)

Implementation Reference

  • Core handler function that executes the RadQL query logic by dispatching to listDataItems, getDataItemById, or getDataStats based on the operation type, with error handling.
    export async function executeRadQLQuery(
      client: RadSecurityClient,
      args: z.infer<typeof RadQLQuerySchema>
    ): Promise<any> {
      const { operation, data_type, ...params } = args;
    
      try {
        switch (operation) {
          case "list":
            return await listDataItems(client, data_type, params);
    
          case "get_by_id":
            if (!params.id) {
              throw new Error("id is required for get_by_id operation");
            }
            return await getDataItemById(client, data_type, params.id);
    
          case "stats":
            if (!params.stats_query) {
              throw new Error("stats_query is required for stats operation");
            }
            return await getDataStats(client, data_type, params);
    
          default:
            throw new Error(`Unknown operation: ${operation}`);
        }
      } catch (error: any) {
        throw handleRadQLError(error, data_type);
      }
    }
  • Zod input schema defining parameters for the radql_query tool: data_type, operation (list/get_by_id/stats), filters_query, stats_query, id, limit, offset, include_relations.
    export const RadQLQuerySchema = z.object({
      data_type: z.string()
        .describe("The data type to query (e.g., 'containers', 'kubernetes_resources', 'inbox_items'). Use radql_list_data_types to discover available types."),
    
      operation: z.enum([
        "list",
        "get_by_id",
        "stats"
      ]).describe("The operation to perform: 'list' for filtering/searching, 'get_by_id' for single item, 'stats' for aggregations"),
    
      filters_query: z.string().optional()
        .describe("RadQL filter query (e.g., 'severity:High AND type:misconfiguration'). Used for filtering results."),
    
      stats_query: z.string().optional()
        .describe("RadQL analytics query (e.g., 'count() by severity'). Used for aggregations and grouping."),
    
      id: z.string().optional()
        .describe("The ID of a specific item to retrieve (for get_by_id operation)"),
    
      limit: z.number().optional().default(20)
        .describe("Maximum number of results to return"),
    
      offset: z.number().optional().default(0)
        .describe("Pagination offset"),
    
      include_relations: z.array(z.string()).optional()
        .describe("Relations to include (e.g., ['owner'] for containers to include Kubernetes owner resource)")
    });
  • src/index.ts:599-636 (registration)
    Tool registration in the ListToolsRequest handler: defines name 'radql_query', detailed description with examples and quoting rules, and inputSchema from RadQLQuerySchema.
                {
                  name: "radql_query",
                  description: `Execute RadQL queries for security investigations. Supports: list (filter/search), get_by_id (single item), stats (aggregations).
    
    WORKFLOW: radql_list_data_types -> radql_get_type_metadata -> radql_query
    
    COMMON FIELDS BY DATA TYPE:
    containers: name, image_name, image_repo, owner_kind, cluster_id, created_at
      Example: image_name:*nginx* AND owner_kind:Pod
    
    finding_groups: type, source_kind, source_name, rule_title, severity, event_timestamp
      Types: k8s_misconfiguration, k8s_audit_logs_anomaly, threat_vector
      Example: type:k8s_misconfiguration AND severity:critical
    
    inbox_items: severity (High|Medium|Low), type, title, archived, false_positive, created_at
      Example: severity:High AND archived:false
    
    kubernetes_resources: kind, name, namespace, cluster_id, owner_kind, created_at
      Example: kind:Deployment AND namespace:production
    
    CRITICAL QUOTING RULES:
    MUST quote when value contains:
      - Dates/timestamps: created_at>"2024-01-01" (NOT created_at>2024-01-01)
      - Hyphens: cluster_id:"abc-123-def", name:"kube-system"
      - UUIDs: id:"550e8400-e29b-41d4-a716-446655440000"
      - Spaces: title:"my alert"
      - Special chars: :, =, <, >, !, (, )
      - Wildcards with hyphens: name:"kube-*"
    
    OK to leave unquoted:
      - Simple strings: status:active, kind:Pod
      - Numbers: count:123
      - Booleans: archived:true
      - Simple wildcards: name:nginx*
    
    For complete schema: call radql_get_type_metadata with target data_type`,
                  inputSchema: zodToJsonSchema(radql.RadQLQuerySchema),
                },
  • src/index.ts:1565-1573 (registration)
    Handler dispatch in the CallToolRequest switch: parses arguments with RadQLQuerySchema and invokes executeRadQLQuery(client, args).
    case "radql_query": {
      const args = radql.RadQLQuerySchema.parse(request.params.arguments);
      const response = await radql.executeRadQLQuery(client, args);
      return {
        content: [
          { type: "text", text: JSON.stringify(response, null, 2) },
        ],
      };
    }
  • Helper function that provides natural language explanation of RadQL filter queries, used in query responses.
    function explainRadQLQuery(query: string | undefined): string {
      if (!query) return "No filters applied - returning all items";
    
      const explanations: string[] = [];
    
      // Parse common patterns
      if (query.includes(" AND ")) {
        explanations.push("All conditions must be true");
      }
      if (query.includes(" OR ")) {
        explanations.push("Any condition can be true");
      }
      if (query.includes("NOT ")) {
        explanations.push("Excluding items matching certain conditions");
      }
      if (query.includes(":")) {
        explanations.push("Filtering by exact field values");
      }
      if (query.includes("*")) {
        explanations.push("Using wildcard pattern matching");
      }
      if (query.includes(">") || query.includes("<")) {
        explanations.push("Comparing numeric or date values");
      }
      if (query.includes("(") && query.includes(")")) {
        explanations.push("Using grouped conditions");
      }
    
      return explanations.length > 0
        ? explanations.join("; ")
        : "Applying custom filter conditions";
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rad-security/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server