{
  "id": "Jb2lUfC5rSPhiA4S",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "n8n nirvana inbox parser",
  "tags": [],
  "nodes": [
    {
      "id": "82d38c07-a29e-433b-a4ad-0d4e70e643c8",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1072,
        432
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5-nano",
          "cachedResultName": "gpt-5-nano"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "48531bcb-330b-439c-add8-a9ea2e4847df",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        352,
        0
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "6ecc9f17-8cdc-4688-87f2-f0293c47684c",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -32,
        -240
      ],
      "parameters": {
        "width": 320,
        "height": 848,
        "content": "### What this workflow does\nThis workflow automates the pre-clarification of a Nirvana GTD inbox. It pulls unclarified tasks from Nirvana via the Model Context Protocol (MCP), utilizes an AI Agent to optimize and rewrite the task names and descriptions, and updates them back in Nirvana.\n\n### How it works\n1. **Trigger:** Activated manually via the **When clicking 'Execute workflow'** trigger.\n2. **Data Retrieval:** The **Nirvana MCP Get** node fetches tasks directly from your Nirvana inbox.\n3. **Data Splitting:** The **Split Out Nirvana Tasks** node isolates individual items for batch processing.\n4. **AI Processing:** An **AI Agent - Process Name...** node powered by the **OpenAI Chat Model** uses the **Structured Output Parser to Match...** node to format the cleaned task data.\n5. **Formatting & Update:** The **Edit Fields To Match Nirvana Reqs** node maps the AI's response into the correct payload format, which the **Nirvana MCP Update** node then commits back to Nirvana.\n\n### Setup instructions\n1. Configure the **OpenAI Chat Model** node with your OpenAI API credentials.\n2. Ensure your local or remote MCP server for Nirvana is running, and that both the **Nirvana MCP Get** and **Nirvana MCP Update** nodes are properly connected to it.\n3. Adjust the schema inside the **Structured Output Parser to Match...** node if you want to customize how the AI structures your updated task names and notes."
      },
      "typeVersion": 1
    },
    {
      "id": "af624895-0124-4c44-a338-3944a7b528f2",
      "name": "Nirvana MCP Get",
      "type": "@n8n/n8n-nodes-langchain.mcpClient",
      "position": [
        544,
        0
      ],
      "parameters": {
        "tool": {
          "__rl": true,
          "mode": "list",
          "value": "get_tasks",
          "cachedResultName": "get_tasks"
        },
        "options": {},
        "parameters": {
          "value": {
            "limit": 10,
            "state": "inbox",
            "offset": 0,
            "overdue": false,
            "starred": false,
            "include_notes": true
          },
          "schema": [
            {
              "id": "state",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "state",
              "defaultMatch": false
            },
            {
              "id": "type",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "type",
              "defaultMatch": false
            },
            {
              "id": "tags",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "tags",
              "defaultMatch": false
            },
            {
              "id": "query",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "query",
              "defaultMatch": false
            },
            {
              "id": "starred",
              "type": "boolean",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "starred",
              "defaultMatch": false
            },
            {
              "id": "overdue",
              "type": "boolean",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "overdue",
              "defaultMatch": false
            },
            {
              "id": "due_before",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "due_before",
              "defaultMatch": false
            },
            {
              "id": "due_after",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "due_after",
              "defaultMatch": false
            },
            {
              "id": "include_notes",
              "type": "boolean",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "include_notes",
              "defaultMatch": false
            },
            {
              "id": "limit",
              "type": "number",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "limit",
              "defaultMatch": false
            },
            {
              "id": "offset",
              "type": "number",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "offset",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "endpointUrl": "https://mcp.nirvanahq.com/mcp",
        "authentication": "bearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": false
    },
    {
      "id": "210e3f96-86c4-4018-b907-8d490daaa8d0",
      "name": "Split Out Nirvana Tasks",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        768,
        0
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "structuredContent.tasks"
      },
      "typeVersion": 1
    },
    {
      "id": "8ac37b3e-7613-4c38-9743-6e050193fb1f",
      "name": "AI Agent - Process Name & Notes",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        992,
        0
      ],
      "parameters": {
        "text": "=Please triage the following individual item from my inbox:\n\nTask Name: {{ $json.name }}\nEmail Content: {{ $json.note || 'No extra details provided.' }}",
        "options": {
          "systemMessage": "You are a precision GTD task-grooming assistant. Your sole job is to analyze incoming task data from my Nirvana inbox and suggest optimal, structured task renames following strict formatting rules.\n\nRules for renaming:\n1. **Identify the Owner & Company:** Look through the email details/headers to find the external contact person and company (e.g., \"Kila\" from \"Digicelpacific\"). Format this exactly as `Owner/Company - `.\n2. **Clarify the Core Action:** Condense the technical discussion into a crisp, human-readable core action verb and context (e.g., instead of \"Re: Change in the...\", use \"Confirm CNN International EPG output format\").\n3. **Format:** The final suggested title must strictly be: `Owner/Company - Clarified Core Action`.\n4. Extract the core body text from the incoming email notes. Completely strip out all legal disclaimers, email routing signatures, forwarded headers, and automated system text. Output only a clean, concise summary of the actual human conversation in the cleaned_note field. At the top of the cleaned note on a separate line include a date stamp using this format \"dd/mm\" with a note stating \"n8n parsed\". Insert a blank line. On the following line, include the original email subject (as-is) preceeded by \"Subject: \". Put a spacer line after that.\n\nOutput constraint: You must only output the structured data. Do not include any conversational text, pleasantries, or explanations.\n"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "11027266-be8e-4a0d-a9a3-d13a3fe7914d",
      "name": "Structured Output Parser to Match Nirvana Reqs",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1072,
        224
      ],
      "parameters": {
        "autoFix": true,
        "jsonSchemaExample": "{\n  \"current_name\": \"Re: Change in the CNN International EPG Delivery system\",\n  \"suggested_name\": \"Kila/Digicelpacific - Confirm CNN International EPG output format\",\n  \"cleaned_note\": \"\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "dd07e07b-3cdc-4394-a221-7ab0b3530515",
      "name": "Edit Fields To Match Nirvana Reqs",
      "type": "n8n-nodes-base.set",
      "position": [
        1440,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "0fca6030-55c2-4f91-bd44-02ab5cf18c7b",
              "name": "id",
              "type": "string",
              "value": "={{ $('Split Out Nirvana Tasks').item.json.id }}"
            },
            {
              "id": "b1f49cfc-81ac-49be-a6a2-8b39ab452b74",
              "name": "name",
              "type": "string",
              "value": "={{ $json.output.suggested_name }}"
            },
            {
              "id": "ea8caaf5-1b68-409b-b14f-98d076df0310",
              "name": "note",
              "type": "string",
              "value": "={{ $json.output.cleaned_note }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a5a146d1-55dd-48c7-ba19-a6fae9cde8b2",
      "name": "Nirvana MCP Update",
      "type": "@n8n/n8n-nodes-langchain.mcpClient",
      "position": [
        1664,
        0
      ],
      "parameters": {
        "tool": {
          "__rl": true,
          "mode": "list",
          "value": "update_tasks",
          "cachedResultName": "update_tasks"
        },
        "options": {},
        "inputMode": "json",
        "jsonInput": "={\n  \"updates\": [\n    {\n      \"id\": \"{{ $json.id }}\",\n      \"name\": \"{{ JSON.stringify($json.name).slice(1, -1) }}\",\n      \"note\": \"{{ JSON.stringify($json.note).slice(1, -1) }}\",\n      \"tags\": [ \"work\" ]\n    }\n  ],\n  \"task_progress\": \"- [x] Updated via n8n automated inbox grooming loop\"\n}",
        "endpointUrl": "https://mcp.nirvanahq.com/mcp",
        "authentication": "bearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d81893c9-2529-4e9b-ac09-96ba088da09a",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        704,
        -240
      ],
      "parameters": {
        "color": "#FFFFFF",
        "width": 896,
        "height": 848,
        "content": "## Process Tasks\n\nThe Chat Model (Open AI in this case) API credentials need to be set, and a model needs selecting. I've used gpt-5-nano."
      },
      "typeVersion": 1
    },
    {
      "id": "3128de11-6383-45a4-84b5-4976dacda8b0",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        512,
        -240
      ],
      "parameters": {
        "color": "#FFFFFF",
        "width": 176,
        "height": 848,
        "content": "## Get Tasks\nAuthentication needs setting to \"Bearer Auth\". Use a token generated on the Nirvana dashboard: https://mcp.nirvanahq.com/tokens"
      },
      "typeVersion": 1
    },
    {
      "id": "703358a7-3d6d-4afd-ab9f-95013f25e951",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1616,
        -240
      ],
      "parameters": {
        "color": "#FFFFFF",
        "width": 208,
        "height": 848,
        "content": "## Update Tasks\n\nThe bearer auth token should be entered here too (same token as previously)."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "ca05ef0a-6419-470b-9b49-7bc9375ab640",
  "connections": {
    "Nirvana MCP Get": {
      "main": [
        [
          {
            "node": "Split Out Nirvana Tasks",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent - Process Name & Notes",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "Structured Output Parser to Match Nirvana Reqs",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Split Out Nirvana Tasks": {
      "main": [
        [
          {
            "node": "AI Agent - Process Name & Notes",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent - Process Name & Notes": {
      "main": [
        [
          {
            "node": "Edit Fields To Match Nirvana Reqs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields To Match Nirvana Reqs": {
      "main": [
        [
          {
            "node": "Nirvana MCP Update",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Nirvana MCP Get",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser to Match Nirvana Reqs": {
      "ai_outputParser": [
        [
          {
            "node": "AI Agent - Process Name & Notes",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    }
  }
}