Describe the problem/error/question
My AI Agent workflow calls the MCP Client tool only once and then stops,
even though the system prompt explicitly defines a 6-step sequential
tool-calling workflow.
The agent calls Step 1 (superset_session_ensure), receives a valid
success response, then treats it as a final answer and never proceeds
to Step 2 onwards.
Expected Behavior
The agent should call MCP tools sequentially across 6 steps:
- superset_session_ensure
- superset_auth_authenticate_user
- superset_dataset_list
- superset_dataset_get_by_id
- superset_chart_detail
- superset_chart_argument_create
Actual Behavior
- Agent calls only Step 1 (superset_session_ensure)
- MCP returns a valid success response
- Agent stops immediately and returns that as the final answer
- Never proceeds to Step 2 onwards
- MCP Client shows only 1 execution in the run log
What I’ve Already Tried
- Upgraded n8n from 2.17.8 to 2.20.9 — same issue persists
- System prompt explicitly lists all 6 steps with HARD GATING rules
- System prompt says “Do NOT stop until Step 6 is complete”
- Max Iterations is set to 10+
What is the error message (if any)?
No error thrown. Agent silently stops after Step 1 and returns
the MCP tool response as if it were the final answer:
{
“message”: “Existing session key is valid”,
“isError”: false
}
Please share your workflow
(Select the nodes on your canvas and use the keyboard shortcuts CMD+C/CTRL+C and CMD+V/CTRL+V to copy and paste the workflow.)
Webhook → AI Agent (Tools Agent)
├── Google Vertex Chat Model (gemini-2.5-flash)
└── MCP Client (executeTool)
{
"name": "mcp_tool",
"nodes": [
{
"parameters": {
"promptType": "define",
"text": "={{ $json.body.user_query }}",
"options": {
"systemMessage": "=## Role\nYou are an MCP agent integrated with Apache Superset via MCP tools. \nYour goal is to create chart json per query — using Superset’s official chart JSON structure (no hallucination or incorrect nesting).\n\nStrict : \nYou must call tools sequentially. After every tool response, \nimmediately call the next tool in the sequence without pausing.\n\n## IMPORTANT\nIf the user query is a greeting, casual chat, or unrelated to the provided dataset/schema/analytics request, immediately stop processing, do not call any MCP tools further, and return exactly: {\"is_valid\":false,\"message\":\"Invalid question\"}\n\n\n## CRITICAL RULES\n- **HARD GATING:** You are strictly forbidden from calling a tool out of order. You MUST call tools exactly in the 1 through 6 sequence as mentioned in Workflow.\n- **NO ASSUMPTIONS:** Do not guess column names, metric names, or chart parameters. You must extract them from the outputs of Step 4 and Step 5.\n- **STRICT METRIC FORMATTING (CRUCIAL):** NEVER invent string-based metrics like \"sum__COLUMN_NAME\". If a metric is not explicitly listed as a saved metric in the dataset schema, you MUST build an Ad-Hoc SQL metric object.\n- For \"bar chart\", x_axis and groupby(dimensions) must not be the same column.\n\n\n## Workflow (Strict Order)\n\n1. **Validate Session Key**: \n Call `superset_session_ensure` tool to Check session key validity. If invalid, create a new `session_key` and store for reuse.\n\n2. **Authenticate**: \n Call the `superset_auth_authenticate_user` tool **without parameters** to get an `access_token`. Retry until successful. Store the token for reuse.\n\n3. **List Datasets**: \n Call `superset_dataset_list` tool **without parameters** for Fuzzy-match query keywords to dataset names/descriptions and store the most relevant `dataset_id`.\n\n4. **Get Dataset Schema (The Data):** Call `superset_dataset_get_by_id` tool using the selected `dataset_id`. Read the returned schema to find the exact technical column names and predefined metrics. You must map the user's natural language request to these exact technical names.\n\n5. **Get Chart Template & Merge (The Structure):** Call `superset_chart_detail` with `chart_type` to retrieve the chart JSON template and rules (default: \"table\"). Store this template.\n Merge the template from this step with the exact column names found in Step 4.\n **CRITICAL MERGE RULES:**\n - Use the exact JSON structure and fields provided by Step 5.\n - Replace placeholders like `<DIMENSION_COLUMN>`, `<METRIC>`, and `<FILTERS>` with the technical names extracted in Step 4.\n - `adhoc_filters` MUST strictly follow the filter rules and SQL expression format provided in Step 5.\n - Do not invent structure; avoid adding unknown or wrong keys that are not in the Step 5 template.\n\n6. **Get Chart JSON (LOCKED PREREQUISITE):** **STOP. DO NOT EXECUTE THIS STEP UNTIL YOU HAVE SUCCESSFULLY RECEIVED THE OUTPUT FROM STEP 4 AND STEP 5.**\n Call `superset_chart_argument_create` with the merged chart JSON (chart template) output to create the chart.\n **Only Use below arguments** to create json:\n slice_name: Chart name/title ,\n datasource_id: Dataset or table ID ,\n datasource_type: 'table' or 'query' ,\n viz_type: Chart type (bar, line, pie,pivot_table_v2 etc.) ,\n params: Chart configuration (metrics, groupby, time_range, adhoc_filters etc.)\n\n\n## STRICT VALIDATION INSTRUCTION (DO NOT VIOLATE):\n\n-Return ONLY ONE valid JSON object.\n-Do NOT include explanation.\n-Do NOT include markdown.\n-Response must start with { and end with }. \n- For metrics: Use valid SQL expressions (e.g., SUM(conversions)/SUM(delivered)*100).\n- For filters: Translate “last X days” into proper adhoc_filters using the dataset’s date column and Superset format you MUST use explicit CAST syntax for intervals. \n- Keep `chart_id`, `access_token`, `session_key`, `dataset_id`, `chart_id`, `formData` in memory for future reuse.\n\n**CRITICAL JSON FORMATTING RULES FOR PARAMS:**\nWhen building the `params` argument, you MUST format nested arrays (like adhoc_filters and metrics) as clean JSON objects. The chart template uses string placeholders (like \"<FILTERS>\") — DO NOT copy this string format.\n- **INCORRECT (Do not wrap object in quotes):** `\"adhoc_filters\": [\"{\\\"expressionType\\\": \\\"SQL\\\", \\\"clause\\\": \\\"WHERE\\\"}\"]`\n- **CORRECT:** `\"adhoc_filters\": [{\"expressionType\": \"SQL\", \"clause\": \"WHERE\"}]`\n\n## FINAL OUTPUT PHASE (ONLY AFTER STEP 6)\n\nYou are strictly forbidden from formatting your response this way until you have successfully executed Step 6. \nOnce Step 6 is complete, your FINAL response to the user must be exactly the output of the `superset_chart_argument_create` tool.\n\n- DO NOT wrap response in ```json or ```\n- DO NOT return as string\n- DO NOT escape quotes (no \\\")\n- DO NOT include \\n, \\t, or formatting characters\n- DO NOT prefix or suffix anything\n\n{\n\t\"slice_name\": \"Chart name/title\",\n\t\"datasource_id\": \"Dataset or table ID\",\n\t\"datasource_type\": \"table or query\",\n\t\"viz_type\": \"Chart type (bar, line, pie, table, pivot_table_v2 etc.)\",\n\t\"params\": { ... }\n}"
}
},
"id": "b2b66a98-a47f-4840-9b48-d16acc73814b",
"name": "AI Agent5",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-3104,
1072
],
"typeVersion": 3
},
{
"parameters": {
"projectId": {
"__rl": true,
"value": "steadfast-rex-495606-p2",
"mode": "id"
},
"modelName": "gemini-2.5-pro",
"options": {
"temperature": 0.7
}
},
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleVertex",
"typeVersion": 1,
"position": [
-3232,
1344
],
"id": "507756e3-6524-4c91-8912-aedf157274e9",
"name": "Google Vertex Chat Model5",
"credentials": {
"googleApi": {
"id": "BFYOTKzqFwio5zVh",
"name": "atul"
}
}
},
{
"parameters": {
"connectionType": "sse",
"operation": "executeTool",
"toolName": "={{ $fromAI(\"tool\",\"the tool selected\") }}",
"toolParameters": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Tool_Parameters', ``, 'json') }}"
},
"type": "n8n-nodes-mcp.mcpClientTool",
"typeVersion": 1,
"position": [
-2896,
1344
],
"id": "0a27ec1f-cd80-474a-a95a-362ec725ff1b",
"name": "MCP Client9",
"credentials": {
"mcpClientSseApi": {
"id": "3N1acS5R7xzkLZny",
"name": "MCP Client (STDIO) account 2"
}
}
},
{
"parameters": {
"httpMethod": "POST",
"path": "79ebe837-a912-4814-90d9-b96d1fa131b3",
"responseMode": "lastNode",
"options": {}
},
"id": "941a98d4-1560-4631-906a-e09390eddabc",
"name": "Webhook1",
"type": "n8n-nodes-base.webhook",
"position": [
-3376,
1072
],
"webhookId": "79ebe837-a912-4814-90d9-b96d1fa131b3",
"typeVersion": 2.1
}
],
"pinData": {},
"connections": {
"Google Vertex Chat Model5": {
"ai_languageModel": [
[
{
"node": "AI Agent5",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"MCP Client9": {
"ai_tool": [
[
{
"node": "AI Agent5",
"type": "ai_tool",
"index": 0
}
]
]
},
"Webhook1": {
"main": [
[
{
"node": "AI Agent5",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"binaryMode": "separate",
"availableInMCP": false,
"timeSavedMode": "fixed",
"callerPolicy": "workflowsFromSameOwner"
},
"versionId": "1a5a603f-551a-4ec8-b51a-75fa40906076",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "222b2f481627b103dedd725016ff99afa115f2d6484c23426f38ae8f5c9d3147"
},
"id": "3JcBdOXjYXyOXeXU",
"tags": []
}
Share the output returned by the last node
{
“structuredContent”: {
“result”: {
“message”: “Existing session key is valid”,
“session_cookie”: “session=.eJwt…”
}
},
“isError”: false
}
This is the output of Step 1 only.
Steps 2 through 6 are never executed.
Information on your n8n setup
- n8n version: 2.20.9
- Database : PostgreSQL (default)
- n8n EXECUTIONS_PROCESS setting (default: own, main): main
- Running n8n via (Docker, npm, n8n cloud, desktop app): Docker
- Operating system: Linux