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 →
{
"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.
googlePalmApihttpBearerAuthmattermostApiopenRouterApiqdrantApi
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 →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
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
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
Your AI workforce is ready. Are you?
Tetra_Blind_Eval_RAG_TEST+Ejentum_Harness. Uses embeddingsGoogleGemini, vectorStoreQdrant, httpRequestTool, agent. Event-driven trigger; 37 nodes.
Build a Multi-Agent system with n8n, Qdrant, Gmail & OpenAI. Uses vectorStoreQdrant, toolWorkflow, executeWorkflowTrigger, googleDrive. Event-driven trigger; 29 nodes.