AutomationFlowsAI & RAG › Answer Infrastructure Questions in Mattermost with Openrouter and Qdrant

Answer Infrastructure Questions in Mattermost with Openrouter and Qdrant

BySergei Byvshev @javdet on n8n.io

AI-powered sub-workflow that answers questions about a your infrastructure configuration directly in a Mattermost channel or thread OpenRouter/OpenAI/Anthropic API key Google Gemini API key — for embeddings Jira API credentials — Cloud or Server. Mattermost API credentials — to…

Event trigger★★★★☆ complexityAI-powered23 nodesExecute Workflow TriggerAgentOpenRouter ChatMcp Client ToolQdrant Vector StoreGoogle Gemini EmbeddingsMattermostHTTP Request Tool
AI & RAG Trigger: Event Nodes: 23 Complexity: ★★★★☆ AI nodes: yes Added:
Answer Infrastructure Questions in Mattermost with Openrouter and Qdrant — n8n workflow card showing Execute Workflow Trigger, Agent, OpenRouter Chat integration

This workflow corresponds to n8n.io template #15629 — we link there as the canonical source.

This workflow follows the Agent → Google Gemini Embeddings recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "8PCnUzN5pYCCHwNH",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "QuestionAssistant",
  "tags": [],
  "nodes": [
    {
      "id": "68343974-fef4-4495-81c7-84dcdd623e29",
      "name": "When Executed by Another Workflow",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        -64,
        64
      ],
      "parameters": {
        "inputSource": "jsonExample",
        "jsonExample": "{\n  \"message\": \"...\",\n  \"post_id\": \"...\",\n  \"channel_id\": \"...\",\n  \"is_thread\": false,\n  \"thread_root_id\": \"...\",\n  \"user_name\": \"...\",\n  \"category\": \"question\",\n  \"confidence\": 0.95,\n  \"summary\": \"...\",\n  \"on_call_user\": \"...\",\n  \"channel_name\": \"...\",\n  \"file_ids\": [\"x4t1k...\", \"9bzqm...\"]}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "f7c6dd43-65f9-4b96-94cd-e6c8e6839fd5",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        304,
        432
      ],
      "parameters": {
        "color": 5,
        "width": 640,
        "height": 752,
        "content": "## Overview\nAI-powered sub-workflow that answers questions about your infrastructure configuration directly in a Mattermost channel or thread\n\n## Requirements\n* OpenRouter/OpenAI/Anthropic API key\n* Google Gemini API key \u2014 for embeddings\n* Jira API credentials \u2014 Cloud or Server. \n* Mattermost API credentials \u2014 to post the reply back to the channel\n* Qdrant instance\n* Remote MCP servers  (see MCP section)\n* A sub-workflow that analyses attachments \n* A [parent workflow](https://n8n.io/workflows/15051-classify-and-route-devops-chat-requests-with-mattermost-openrouter-and-google-calendar/) that triggers this one via \"Execute Workflow\" with a properly shaped payload\n\n## How it works\n1. The workflow is triggered by another workflow\n1. `ReadIncidentContext` logs the request and forwards the payload\n1. Call '`attachmentsAnalyzer` invokes a vision sub-workflow with the file_ids\n1. `SetVars` sets workflow-level constants\n1. `AI agent` generates a response based on the system prompt, knowledge base, and access to repositories.\n1. The agent's response is posted back to Mattermost via the `Post a message` node\n\n## How to use\n* Upload your infrastructure documentation (Markdown, YAML, runbooks) into Qdrant\n* Import the attachmentsAnalyzer sub-workflow and update the workflow\nreference inside\n* Deploy or point to your MCP servers\n* Configure credentials\n* Edit the AI Agent system message to describe your infrastructure\n* In SetVars, replace the example \n* Wire this workflow up to an upstream router "
      },
      "typeVersion": 1
    },
    {
      "id": "4408b0b2-f702-45a7-adbf-60a96813ca0a",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1152,
        64
      ],
      "parameters": {
        "text": "=Please provide information on our infrastructure from {{ $json.user_name }}\nin channel {{ $json.channel_name }}{{ $json.is_thread ? ' (message is in a thread, thread_root_id=' + $json.thread_root_id + ' \u2014 read the story through Mattermost get_thread first)' : '' }}\n\n{{ $json.message }}{{ $json.attachments_context && $json.attachments_context.trim().length > 0 ? '\\n\\nAdditional information from attachments:\\n' + $json.attachments_context : '' }}",
        "options": {
          "maxIterations": 20,
          "systemMessage": "=You are an senior Devops/SRE assistant for your organization's infrastructure. Your main goal is to assist in answer to questions about our infrastructure configuration.\n\n## Message context\n\nThe request can come either from a main channel message or from a thread reply.\n\n- channel_id: {{ $json.channel_id }}\n- post_id: {{ $json.post_id }}\n- is_thread: {{ $json.is_thread }}\n- thread_root_id: {{ $json.thread_root_id }}\n\nIf `is_thread` is true, the user's question is part of an ongoing thread.\nBefore investigating, call Mattermost `get_thread` with `thread_root_id`\nexactly ONCE to load the full conversation. Earlier messages in the thread\noften contain critical context: links to failing jobs, error logs, repository\nnames, previous hypotheses, or clarifications from the user.\n\nRules for reading the thread:\n- Call `get_thread` only once, at the very start, before any other tool.\n- Do not call `get_channel_messages` for thread context \u2014 use `get_thread`.\n- Ignore posts authored by the bot itself (previous assistant replies) when\n  extracting the problem description. Focus on messages from human users.\n- Treat the user prompt (the message below) as the LATEST question \u2014\n  prior thread messages are background context, not the current ask.\n\nIf `is_thread` is false, skip this step. The message in the user prompt\nis the entire request; do not fetch thread history.\n\nProject name: ``\nProject description: \nEnvironments: `dev/stage` and `prod`\nGitHub organization: ``\nMain cloud providers: DigitalOcean\n\n## Important rules\n- Don't ask anything, analyze it yourself\n\n## Determine which part of the infrastructure the question concerns\n- Proxy traffic routing settings\n- Kuberntes cluster settings\n- Datastore settings\n- Monitoring/Alerting\n- Logging settings\n- CI/CD settings\n- Resource consumption\n\n### Main infrastructure repositories\n* List of repos\n\n### Datastore settings\n<Description of how databases are deployed and where their code is located>\n\n- Use Github MCP for access to IaC. Read README.md in the root repository to learn more about its structure\n- Use digitalocean MCP tools if you need to check current Droplet, Volume, Object storage configuration\n- If you can't find the required settings in the code, look for the default settings in the official documentation for the resource.\nExample:\n\"What logging level is set in valkey?\"\n\"The loglevel parameter was not found in the Ansible role valkey, meaning the default value notice from the official documentation is used. https://github.com/valkey-io/valkey/blob/9.0/valkey.conf\"\n\n### Kubernetes cluster settings\nWe use managed kuberntes clusters in our `Main cloud providers`\nThe cluster configuration -.\nCluster context naming:\n<environment>-<region>\nenvironment: dev, prod\nregions: \n- Use Github MCP for access to IaC\n- Use kubernetes MCP tools if you need to check current resource configuration: configmaps, secrets, deployments, etc\n- If you can't find the required settings in the code, look for the default settings in the chart documentation.\n\n### Monitoring/Alerting\nWe use kube-prometheus-stack. \nIf your question is related to monitoring, metrics, or alerts, you can find details in the repository - \nThere're Alert rules in - \n\n### Logging\nIf your question is related to logs, Loki , you can find details in the repository -\nWe use grafana alloy as logs shipper from droplets. Ansible alloy role is in -\n\n### CI/CD settings\nDetermine which repository the issue belongs to and check its workflow settings in .github/workflows/\nWorkflows from a repository - are often used in other repositories.\n- Use Github MCP\n\n### Resource consumption\nIf the question concerns current resource consumption, look for data for the last 30 minutes.\nWe use standart prometheus node_exporter.\nProduction metrics stored in prometheus datasource name: prod\nDev/stage metrics stored in prometheus datasource name: dev\nUseful prometheus labels:\n- instance - name of instance, see naming convention\n- region - \n- job - redis, postgres, redpanda\n- namespace - monitoring, logging\n- pod - name of pod in k8s cluster\n- ingress - name of ingress\n\nUse Grafana MCP for request metrics\n\n## Grafana Tools  \nUse these to query metrics, logs, dashboards:\n- **Prometheus**: query_prometheus for PromQL queries (CPU, memory, request rates, error rates). Datasource uid: {{ $('SetVars').first().json.prometheus_uid }}\n- **Loki**: query_loki_logs for LogQL log searches. Datasource uid: {{ $('SetVars').first().json.loki_uid }}\n- **Dashboards**: search_dashboards, get_dashboard_summary to find relevant dashboards\n\n## Vector store MCP tools\n- Read infromation about infratructure, service commuication, trafic balancing, useful tags and labels. Naming convention\n\n## Mattermost tools\n- Use `get_thread` to read the full thread context when `is_thread` is true.\n- Use `get_user_by_username` / `get_user` to resolve author identities if needed.\n- Do not use Mattermost tools to post replies \u2014 replies are sent by the\n  workflow after your response.\n\n## Critical Rules for Tool Usage\n1. **Never retry a failed tool call more than once.** If a Kubernetes resource (pod, deployment, node) is not found on the first attempt, it likely no longer exists. Do NOT retry the same query.\n2. **If any tool returns an error or empty result**, acknowledge it and move on.\n3.  Don't make any changes to anything through mcp.\n4.  Avoid queries that return all elements; filter and grep.\n5.  When working with metrics, logs, and traces, always specify a limited time range in your queries.\n6. Never try to get all the events from the Kubernetes without filtering by a specific object, for example certain pod, job, deployment\n\n\n## Output format\nDescribe the current settings or state of affairs.\nIf we are talking about settings, write where they are defined."
        },
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "5e3300db-8eb1-4b85-b16e-3de0db533690",
      "name": "OpenRouter Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        1088,
        224
      ],
      "parameters": {
        "model": "openai/gpt-5.3-codex",
        "options": {}
      },
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "b3edaa4b-9b37-4718-a69b-2842e440ce56",
      "name": "Grafana",
      "type": "@n8n/n8n-nodes-langchain.mcpClientTool",
      "position": [
        1616,
        528
      ],
      "parameters": {
        "include": "selected",
        "options": {},
        "endpointUrl": "https://<your-mcp-gateway-host>/grafana/mcp",
        "includeTools": [
          "get_datasource",
          "get_panel_image",
          "list_datasources",
          "list_loki_label_names",
          "list_loki_label_values",
          "query_loki_logs",
          "query_loki_patterns",
          "query_loki_stats",
          "list_prometheus_label_names",
          "list_prometheus_label_values",
          "list_prometheus_metric_metadata",
          "list_prometheus_metric_names",
          "query_prometheus",
          "query_prometheus_histogram",
          "search_dashboards",
          "search_folders"
        ]
      },
      "typeVersion": 1.2
    },
    {
      "id": "4beaddfe-08bf-4432-b9f0-40881be4890a",
      "name": "DigitalOcean",
      "type": "@n8n/n8n-nodes-langchain.mcpClientTool",
      "position": [
        1392,
        528
      ],
      "parameters": {
        "include": "selected",
        "options": {},
        "endpointUrl": "https://<your-mcp-gateway-host>/digitalocean/mcp",
        "includeTools": [
          "apps-get-deployment-status",
          "apps-get-info",
          "apps-get-logs",
          "apps-list",
          "byoip-prefix-resources-get",
          "byoip-prefix-list",
          "certificate-get",
          "certificate-list",
          "doks-get-cluster",
          "doks-get-nodepool",
          "doks-list-clusters",
          "doks-list-nodepools",
          "doks-list-options",
          "domain-get",
          "domain-list",
          "domain-record-get",
          "domain-record-list",
          "droplet-get",
          "droplet-list",
          "firewall-get",
          "firewall-list",
          "lb-get",
          "lb-list",
          "region-list",
          "reserved-ip-list",
          "reserved-ip-get",
          "size-list",
          "vpc-get",
          "vpc-list"
        ]
      },
      "typeVersion": 1.2
    },
    {
      "id": "1df7681c-9051-4ac5-b0a9-7e1d0cb7eaef",
      "name": "K8S",
      "type": "@n8n/n8n-nodes-langchain.mcpClientTool",
      "position": [
        1280,
        528
      ],
      "parameters": {
        "include": "selected",
        "options": {},
        "endpointUrl": "http://<your-kubernetes-mcp-host>:<port>/mcp",
        "includeTools": [
          "configuration_view",
          "events_list",
          "namespaces_list",
          "nodes_log",
          "nodes_top",
          "pods_get",
          "pods_list",
          "pods_list_in_namespace",
          "pods_log",
          "pods_top",
          "resources_get",
          "resources_list"
        ]
      },
      "typeVersion": 1.2
    },
    {
      "id": "09371f2e-86a2-4d50-bd0e-091083f9481c",
      "name": "Qdrant Vector Store",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant",
      "position": [
        1744,
        528
      ],
      "parameters": {
        "mode": "retrieve-as-tool",
        "options": {},
        "toolDescription": "Use this tool to fetch knowledge our IT infrastructure. ",
        "qdrantCollection": {
          "__rl": true,
          "mode": "list",
          "value": "<your-qdrant-collection-name>",
          "cachedResultName": "<your-qdrant-collection-name>"
        }
      },
      "credentials": {
        "qdrantApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "806a75dc-4181-40bb-8287-e4fc50ace4f9",
      "name": "Embeddings Google Gemini",
      "type": "@n8n/n8n-nodes-langchain.embeddingsGoogleGemini",
      "position": [
        1744,
        736
      ],
      "parameters": {
        "modelName": "models/gemini-embedding-2-preview"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "4c66aba3-43d9-4117-a55c-19042026c76e",
      "name": "Github",
      "type": "@n8n/n8n-nodes-langchain.mcpClientTool",
      "position": [
        1152,
        528
      ],
      "parameters": {
        "include": "selected",
        "options": {},
        "endpointUrl": "https://<your-mcp-gateway-host>/github/mcp",
        "includeTools": [
          "actions_get",
          "actions_list",
          "get_commit",
          "get_file_contents",
          "get_gist",
          "get_job_logs",
          "list_commits",
          "list_branches",
          "list_pull_requests",
          "pull_request_read",
          "search_code",
          "search_pull_requests",
          "search_repositories"
        ],
        "authentication": "bearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "f44bf8a4-7c6e-4ac3-bca3-ac3eaabf468c",
      "name": "Post a message",
      "type": "n8n-nodes-base.mattermost",
      "position": [
        1792,
        64
      ],
      "parameters": {
        "message": "={{ $json.output }}",
        "channelId": "={{ $('ReadIncidentContext').first().json.channel_id }}",
        "attachments": [],
        "otherOptions": {
          "root_id": "={{ $('SetVars').first().json.reply_root_id }}"
        }
      },
      "credentials": {
        "mattermostApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "9039084d-89ac-4741-aa25-e9821517a20b",
      "name": "ReadIncidentContext",
      "type": "n8n-nodes-base.code",
      "position": [
        128,
        64
      ],
      "parameters": {
        "jsCode": "// Read the classification object passed from the parent router workflow\n// Available fields: message, post_id, channel_id, user_name, user_id,\n// team_domain, channel_name, timestamp, category, confidence, summary\n\nconst data = $input.first().json;\n\n// Log for debugging\nconsole.log(`Request received: ${data.summary}`);\nconsole.log(`From: ${data.user_name} in #${data.channel_name}`);\nconsole.log(`Confidence: ${data.confidence}`);\n\nreturn [{ json: data }];"
      },
      "typeVersion": 2
    },
    {
      "id": "e1446cf3-3abb-4577-823f-be3ad59b6862",
      "name": "SetVars",
      "type": "n8n-nodes-base.set",
      "position": [
        912,
        64
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "a8cb35fa-467e-4060-9f95-6386dc27a5b5",
              "name": "GITHUB_ORG",
              "type": "string",
              "value": "<your-github-org>"
            },
            {
              "id": "8471f4ad-0bdc-421b-887c-8bd7b2c4528e",
              "name": "K8S_NAMESPACE",
              "type": "string",
              "value": "<your-primary-k8s-namespace>"
            },
            {
              "id": "dfc64c71-82a9-4e67-b91b-7fd675256448",
              "name": "K8S_CLUSTERS",
              "type": "string",
              "value": "<your-dev-cluster-context>,<your-prod-cluster-context>"
            },
            {
              "id": "996995b9-a0a0-41ee-8e5f-498cad759f96",
              "name": "reply_root_id",
              "type": "string",
              "value": "={{ $('ReadIncidentContext').item.json.is_thread ? $('ReadIncidentContext').item.json.thread_root_id : $('ReadIncidentContext').item.json.post_id}}"
            },
            {
              "id": "c4d1bc7f-5d84-48b6-99ce-091d332ece58",
              "name": "prometheus_uid",
              "type": "string",
              "value": "<your-prometheus-datasource-uid>"
            },
            {
              "id": "be454984-d00d-45cd-8895-34edd7b3d681",
              "name": "loki_uid",
              "type": "string",
              "value": "<your-loki-datasource-uid>"
            },
            {
              "id": "11fc1058-387b-4ff7-90c4-d94fbff27878",
              "name": "post_id",
              "type": "string",
              "value": "={{ $('ReadIncidentContext').item.json.post_id }}"
            },
            {
              "id": "62195f74-7c07-4b5d-8d34-2412d5cfa515",
              "name": "user_name",
              "type": "string",
              "value": "={{ $('ReadIncidentContext').item.json.user_name }}"
            },
            {
              "id": "61c3c787-7d85-4a4d-b33e-afb20fe7a5a6",
              "name": "on_call_user",
              "type": "string",
              "value": "={{ $('ReadIncidentContext').item.json.on_call_user }}"
            },
            {
              "id": "ef65e662-a7c2-48fa-9932-250a6c55ccac",
              "name": "channel_id",
              "type": "string",
              "value": "={{ $('ReadIncidentContext').item.json.channel_id }}"
            },
            {
              "id": "aece7ba5-4604-40cc-aee2-53b24450ed21",
              "name": "is_thread",
              "type": "string",
              "value": "={{ $('ReadIncidentContext').item.json.is_thread }}"
            },
            {
              "id": "0123093b-cff9-4533-8755-e38f1c02dbae",
              "name": "message",
              "type": "string",
              "value": "={{ $('ReadIncidentContext').item.json.message }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "1cfae412-6008-4f56-8e97-c8c73d7aef26",
      "name": "Mattermost",
      "type": "@n8n/n8n-nodes-langchain.mcpClientTool",
      "position": [
        1024,
        528
      ],
      "parameters": {
        "include": "selected",
        "options": {},
        "endpointUrl": "https://<your-mcp-gateway-host>/mattermost/mcp",
        "includeTools": [
          "get_channel",
          "get_channel_by_name",
          "get_channel_messages",
          "get_thread",
          "get_user",
          "get_user_by_username",
          "search_messages"
        ]
      },
      "typeVersion": 1.2
    },
    {
      "id": "8ed688b0-0f09-4c65-bcd4-a29b1e996174",
      "name": "HTTP Request",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        1504,
        528
      ],
      "parameters": {
        "url": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('URL', ``, 'string') }}",
        "options": {
          "timeout": 10000
        },
        "toolDescription": "Makes an HTTP request to documentation and returns the response data"
      },
      "typeVersion": 4.4
    },
    {
      "id": "6f8da415-0369-481f-8168-6acf09f06f35",
      "name": "Set: empty attachments",
      "type": "n8n-nodes-base.set",
      "position": [
        560,
        224
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "61a657aa-156d-4f78-806b-6ba865062183",
              "name": "attachments_context",
              "type": "string",
              "value": ""
            },
            {
              "id": "e652b32b-371f-4918-a774-d23f939a8026",
              "name": "attachments_count",
              "type": "string",
              "value": "0"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "726e136f-62b9-4b88-923e-0f051fe8a3b1",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        752,
        64
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "aa531b35-7a5d-4f37-8bb6-05db403ef6e3",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1056,
        0
      ],
      "parameters": {
        "color": 6,
        "width": 496,
        "height": 368,
        "content": "## AI agent"
      },
      "typeVersion": 1
    },
    {
      "id": "b63c049a-4e54-4135-8645-2ea9b128517e",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1696,
        0
      ],
      "parameters": {
        "width": 304,
        "height": 368,
        "content": "## Output chain"
      },
      "typeVersion": 1
    },
    {
      "id": "a4d8631e-6955-475c-bbe4-c6ba008a11de",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -112,
        0
      ],
      "parameters": {
        "width": 384,
        "height": 656,
        "content": "## Input chain\n\n\n\n\n\n\n\n\n\n\n\n\n\n```\n[\n  {\n    \"message\": ,\n    \"post_id\": ,\n    \"channel_id\": ,\n    \"channel_name\": ,\n    \"user_name\": ,\n    \"user_id\": ,\n    \"file_ids\":,\n    \"category\": ,\n    \"confidence\": ,\n    \"summary\": ,\n    \"acknowledge\": ,\n    \"is_thread\":,\n    \"parent_post\": ,\n    \"thread_root_id\": ,\n    \"on_call_user\": \n  }\n]\n```"
      },
      "typeVersion": 1
    },
    {
      "id": "d2224fe9-00d5-4cbc-95d6-cb43f011d679",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        304,
        0
      ],
      "parameters": {
        "color": 2,
        "width": 720,
        "height": 368,
        "content": "## Check attachments"
      },
      "typeVersion": 1
    },
    {
      "id": "447b8a9e-bc96-4502-8818-af90573b39a1",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        976,
        432
      ],
      "parameters": {
        "color": 4,
        "width": 1024,
        "height": 448,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n# MCP servers\nAdd correct URLs for remote MCPs\nUse following mcp:\n* [grafana-mcp](https://github.com/grafana/mcp-grafana)\n* [github-mcp](https://github.com/github/github-mcp-server)\n* [kubernetes-mcp-server](https://github.com/containers/kubernetes-mcp-server)\n* [mattermost-mcp](https://github.com/cloud-ru-tech/mcp-server-mattermost)\n* [digitalocean-mcp](https://github.com/digitalocean/digitalocean-mcp)"
      },
      "typeVersion": 1
    },
    {
      "id": "09b5cd22-4337-4f92-9a08-bfca0962b0ed",
      "name": "Call 'attachmentsAnalyzer'",
      "type": "n8n-nodes-base.executeWorkflow",
      "onError": "continueErrorOutput",
      "position": [
        368,
        64
      ],
      "parameters": {
        "options": {},
        "workflowId": {
          "__rl": true,
          "mode": "list",
          "value": "<your-attachments-analyzer-subworkflow-id>",
          "cachedResultUrl": "/workflow/<your-attachments-analyzer-subworkflow-id>",
          "cachedResultName": "<your-attachments-analyzer-workflow-name>"
        },
        "workflowInputs": {
          "value": {
            "file_ids": "={{ $json.file_ids }}"
          },
          "schema": [
            {
              "id": "file_ids",
              "type": "array",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "file_ids",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "file_ids"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        }
      },
      "typeVersion": 1.3
    }
  ],
  "active": true,
  "settings": {
    "binaryMode": "separate",
    "callerPolicy": "workflowsFromSameOwner",
    "errorWorkflow": "",
    "timeSavedMode": "fixed",
    "availableInMCP": true,
    "executionOrder": "v1",
    "executionTimeout": -1
  },
  "versionId": "dcdc58db-03b2-4c46-9897-c82531a42457",
  "connections": {
    "K8S": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "SetVars",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Github": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Grafana": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "SetVars": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Post a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mattermost": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "DigitalOcean": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Qdrant Vector Store": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "ReadIncidentContext": {
      "main": [
        [
          {
            "node": "Call 'attachmentsAnalyzer'",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Set: empty attachments": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Embeddings Google Gemini": {
      "ai_embedding": [
        [
          {
            "node": "Qdrant Vector Store",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Call 'attachmentsAnalyzer'": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Set: empty attachments",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Executed by Another Workflow": {
      "main": [
        [
          {
            "node": "ReadIncidentContext",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

AI-powered sub-workflow that answers questions about a your infrastructure configuration directly in a Mattermost channel or thread OpenRouter/OpenAI/Anthropic API key Google Gemini API key — for embeddings Jira API credentials — Cloud or Server. Mattermost API credentials — to…

Source: https://n8n.io/workflows/15629/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

AI-powered SRE sub-workflow that investigates user-reported incidents coming from a Mattermost channel and posts a structured diagnostic report back into the same thread. The result is a four-section

Execute Workflow Trigger, Agent, OpenRouter Chat +4
AI & RAG

This is a sub-workflow that converts a free-form DevOps request posted in Mattermost into a properly formatted Jira task OpenRouter/OpenAI/Anthropic API key Google Gemini API key — for embeddings Jira

Execute Workflow Trigger, Agent, OpenRouter Chat +6
AI & RAG

Your AI workforce is ready. Are you?

Google Sheets Tool, Mcp Trigger, Google Drive +29
AI & RAG

Tetra_Blind_Eval_RAG_TEST+Ejentum_Harness. Uses embeddingsGoogleGemini, vectorStoreQdrant, httpRequestTool, agent. Event-driven trigger; 37 nodes.

Google Gemini Embeddings, Qdrant Vector Store, HTTP Request Tool +4
AI & RAG

Build a Multi-Agent system with n8n, Qdrant, Gmail & OpenAI. Uses vectorStoreQdrant, toolWorkflow, executeWorkflowTrigger, googleDrive. Event-driven trigger; 29 nodes.

Qdrant Vector Store, Tool Workflow, Execute Workflow Trigger +11