{
  "id": "dBi294X47V7gDxkr",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "K8s Analysis",
  "tags": [],
  "nodes": [
    {
      "id": "69df7205-ee0a-46bf-81e5-3874601a8505",
      "name": "OpenAI K8s Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        448,
        16
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "18eb6ec5-e732-41e4-8840-27264225f102",
      "name": "K8s Query Analyzer",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        448,
        -160
      ],
      "parameters": {
        "text": "=You are a Kubernetes expert assistant that analyzes user queries and generates kubectl commands for execution via MCP tools.\n\n**Your Primary Task:**\nAnalyze the user's query and generate the appropriate kubectl command to fulfill their request.\n\n**Available kubectl operations (read-only only):**\n- `kubectl get` - List resources (pods, deployments, services, nodes, etc.)\n- `kubectl describe` - Show detailed resource information\n- `kubectl explain` - Show resource documentation\n- `kubectl config view` - Show kubeconfig settings\n- `kubectl version` - Show kubectl and cluster versions\n- `kubectl cluster-info` - Show cluster information\n- `kubectl api-resources` - List available API resources\n\n**Critical Instructions:**\n1. **Analyze the user query** to understand what Kubernetes information they need\n2. **Generate ONLY the kubectl command** - do not execute it yourself\n3. **Output MUST be valid JSON only - NO markdown, NO backticks, NO formatting**\n4. **Output format example:**\n{\"command\": \"kubectl get pods --all-namespaces\"}\n\n**Command Generation Guidelines:**\n- Always start commands with \"kubectl\"\n- Use appropriate namespaces (--all-namespaces, -n namespace-name)\n- Use default namespace unless specified.\n- Do not add --cluster flag.\n- Include helpful flags like --field-selector, --label-selector when relevant\n- You can also use grep flag to get accurate output as per user request.\n- For status queries, use field selectors (e.g., status.phase=Running, status.phase=Failed)\n- Include output formatting when helpful (-o wide, -o yaml, -o json)\n- Only use read-only commands (get, describe, explain, config view, version, cluster-info, api-resources)\n\n**Example Transformations:**\n- \"Show me all pods\" \u2192 {\"command\": \"kubectl get pods --all-namespaces\"}\n- \"List failing pods\" \u2192 {\"command\": \"kubectl get pods --all-namespaces --field-selector=status.phase=Failed\"}\n- \"Get pod details in default namespace\" \u2192 {\"command\": \"kubectl get pods -n default -o wide\"}\n- \"Show me deployments in kube-system\" \u2192 {\"command\": \"kubectl get deployments -n kube-system\"}\n- \"What nodes are ready?\" \u2192 {\"command\": \"kubectl get nodes\"}\n- \"Describe pod nginx\" \u2192 {\"command\": \"kubectl describe pod nginx\"}\n- \"Show cluster info\" \u2192 {\"command\": \"kubectl cluster-info\"}\n\n**CRITICAL RULES:**\n- Output ONLY raw JSON - no ```json blocks, no backticks, no explanations\n- Response must be parseable JSON\n- If user asks for modifications/deletions, output: {\"command\": \"echo 'Error: Only read-only operations supported'\"}\n- Ensure kubectl syntax is correct\n\n**User Query:** {{ $('When chat message received').item.json.chatInput }}\n\n**Response (Only JSON):**",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 2.1
    },
    {
      "id": "53bfb274-b4a6-40e8-889f-4964692dbdc8",
      "name": "When chat message received",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "position": [
        -288,
        -160
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "8795dd11-da4d-45d5-97a7-f28ffae285f4",
      "name": "Kubectl MCP Tool",
      "type": "n8n-nodes-mcp.mcpClient",
      "position": [
        768,
        -160
      ],
      "parameters": {
        "toolName": "run_kubectl_command_ro",
        "operation": "executeTool",
        "toolParameters": "={{ $json.output }}"
      },
      "credentials": {
        "mcpClientApi": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1
    },
    {
      "id": "2125c903-bf7d-476a-af42-f915d695bb37",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -96,
        16
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o",
          "cachedResultName": "gpt-4o"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "7ac15f78-2e8d-418e-a34a-65d5d8ad2d50",
      "name": "List K8s Clusters",
      "type": "n8n-nodes-mcp.mcpClientTool",
      "position": [
        48,
        16
      ],
      "parameters": {
        "toolName": "list_clusters",
        "operation": "executeTool",
        "toolParameters": "={}"
      },
      "credentials": {
        "mcpClientApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "b78e3c21-bac7-41d1-b949-d29484d236c3",
      "name": "K8s Cluster Analyzer",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -96,
        -160
      ],
      "parameters": {
        "text": "=You are a Kubernetes multi-cluster assistant that extracts cluster names from user queries using dynamic cluster discovery.\n\n**Your Tasks:**\n1. **Use the List K8s Clusters tool** to get the current available clusters\n2. **Analyze the user query** to extract cluster context\n3. **Match user input** to available cluster names\n4. **Output clean JSON** for context switching\n\n**Workflow Steps:**\n1. Call the List K8s Clusters tool to get current cluster list\n2. Parse the cluster names from the result\n3. Create smart mappings based on cluster naming patterns\n4. Match user query against available clusters\n\n**Smart Cluster Matching Logic:**\n- Extract keywords from cluster names (artemis, hermes, kiwi, dev, prod, staging, etc.)\n- Match partial names (case-insensitive)\n- Handle common abbreviations (prod \u2192 production, dev \u2192 development)\n- Support environment-based matching (staging, production, development)\n\n**Output Rules:**\n- NO markdown, NO backticks, NO code blocks, NO explanations\n- ONLY raw JSON that can be parsed directly\n- If cluster found: {\"context\": \"exact-full-cluster-name-from-list\"}\n- If no cluster specified: {\"message\": \"Please specify which cluster you'd like to work with. Available clusters: [list-short-names]\"}\n- If ambiguous match: {\"message\": \"Multiple clusters found. Please be more specific: [matching-options]\"}\n\n**Examples:**\nUser: \"show pods in artemis\"\n1. Get clusters via List K8s Clusters tool\n2. Find cluster containing \"artemis\" \u2192 \"us-east-1.teleport.cloudservices.acquia.io-csp-artemis2a7\"\n3. Output: {\"context\": \"us-east-1.teleport.cloudservices.acquia.io-csp-artemis2a7\"}\n\nUser: \"list deployments\"\n1. Get clusters via List K8s Clusters tool\n2. No cluster specified in query\n3. Extract short names from cluster list\n4. Output: {\"message\": \"Please specify which cluster you'd like to work with. Available clusters: artemis, hermes, kiwi, dev, saas, tools, minikube\"}\n\n**Critical Instructions:**\n- ALWAYS use List K8s Clusters tool first to get current cluster list\n- Base all cluster matching on the ACTUAL available clusters\n- Never use hardcoded cluster names or mappings\n- Extract meaningful short names from full cluster names for user guidance\n- Match user input against both full names and extracted keywords\n\n**User Query:** {{ $json.chatInput }}\n\n**Start by using the List K8s Clusters tool, then provide your analysis:**",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 2.1
    },
    {
      "id": "2bdd9886-d726-4db4-a039-936f34260482",
      "name": "Switch K8s Context",
      "type": "n8n-nodes-mcp.mcpClient",
      "position": [
        240,
        -160
      ],
      "parameters": {
        "toolName": "switch_context",
        "operation": "executeTool",
        "toolParameters": "={{ $json.output }}"
      },
      "credentials": {
        "mcpClientApi": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": false,
      "typeVersion": 1
    },
    {
      "id": "d8bfc9f4-8ffc-4611-9262-807258bdc159",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -128,
        -352
      ],
      "parameters": {
        "color": 3,
        "width": 496,
        "height": 496,
        "content": "## Cluster context switch\n### - Exit if no cluster name is provided in the chat input\n### - Use `list_clusters` tool to list all the available clusters in ~/.kube/config\n### - Use `switch_context` tool to switch the cluster context"
      },
      "typeVersion": 1
    },
    {
      "id": "eee427c1-7df5-4916-af30-8bbf22e2ba36",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        416,
        -352
      ],
      "parameters": {
        "color": 5,
        "width": 480,
        "height": 496,
        "content": "## kubectl command generate\n### - Analyse chat input\n### - Generate `kubectl` command\n### - Pass command as a parameter to `run_kubectl_command_ro` tool"
      },
      "typeVersion": 1
    },
    {
      "id": "1c7a5100-cdc7-4574-b2b2-8905c703a52d",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -544,
        -208
      ],
      "parameters": {
        "width": 304,
        "height": 208,
        "content": "## Try this out using Chat\n\n### How many pods are showing a Pending status in the `abc` namespace on the production cluster?"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "e45aeee6-2600-4c8d-91c7-0bbd548807da",
  "connections": {
    "OpenAI K8s Model": {
      "ai_languageModel": [
        [
          {
            "node": "K8s Query Analyzer",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "List K8s Clusters": {
      "ai_tool": [
        [
          {
            "node": "K8s Cluster Analyzer",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "K8s Cluster Analyzer",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "K8s Query Analyzer": {
      "main": [
        [
          {
            "node": "Kubectl MCP Tool",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch K8s Context": {
      "main": [
        [
          {
            "node": "K8s Query Analyzer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "K8s Cluster Analyzer": {
      "main": [
        [
          {
            "node": "Switch K8s Context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When chat message received": {
      "main": [
        [
          {
            "node": "K8s Cluster Analyzer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}