This workflow corresponds to n8n.io template #4231 — we link there as the canonical source.
This workflow follows the Execute Workflow Trigger → Toolworkflow 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": "aiKrExd0rAxJO6xi",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "MCP_google_calendar",
"tags": [],
"nodes": [
{
"id": "17ccfdbf-d121-4ff0-95d4-bb38644d2bb1",
"name": "MCP Server Trigger",
"type": "@n8n/n8n-nodes-langchain.mcpTrigger",
"position": [
80,
-40
],
"parameters": {
"path": "c734cf98-3d5a-4cbd-af97-8ad2da760944"
},
"typeVersion": 1
},
{
"id": "174a13be-04f1-417c-8510-26798dae3447",
"name": "When Executed by Another Workflow",
"type": "n8n-nodes-base.executeWorkflowTrigger",
"position": [
1060,
220
],
"parameters": {
"workflowInputs": {
"values": [
{
"name": "operation"
},
{
"name": "startDate"
},
{
"name": "endDate"
},
{
"name": "eventId"
},
{
"name": "timeZone"
}
]
}
},
"typeVersion": 1.1
},
{
"id": "f74799f0-67b4-4247-905c-46adb1be4739",
"name": "Operation",
"type": "n8n-nodes-base.switch",
"position": [
1460,
180
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "getEvent",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "81b134bc-d671-4493-b3ad-8df9be3f49a6",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.operation }}",
"rightValue": "getEvent"
}
]
},
"renameOutput": true
},
{
"outputKey": "deleteEvent",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "8d57914f-6587-4fb3-88e0-aa1de6ba56c1",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.operation }}",
"rightValue": "deleteEvent"
}
]
},
"renameOutput": true
},
{
"outputKey": "createEvent",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "7c38f238-213a-46ec-aefe-22e0bcb8dffc",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.operation }}",
"rightValue": "createEvent"
}
]
},
"renameOutput": true
},
{
"outputKey": "updateEvent",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "ee9b6783-a0f2-4848-9166-aba6645c1ebc",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.operation }}",
"rightValue": "updateEvent"
}
]
},
"renameOutput": true
},
{
"outputKey": "getEventData",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "9ea6980d-a7be-4dec-8ddf-d2fcffb00af1",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "getEventData",
"rightValue": "getEventData"
}
]
},
"renameOutput": true
}
]
},
"options": {}
},
"typeVersion": 3.2
},
{
"id": "b8007362-0d41-4875-872b-877f33b74bf8",
"name": "validate_busy_time",
"type": "@n8n/n8n-nodes-langchain.toolWorkflow",
"position": [
-80,
240
],
"parameters": {
"name": "validate_busy_time",
"workflowId": {
"__rl": true,
"mode": "list",
"value": "aiKrExd0rAxJO6xi",
"cachedResultName": "MCP_google_calendar"
},
"description": "Call this tool to validate if the gap of time is already busy. it is useful to validate before creating a new event",
"workflowInputs": {
"value": {
"endDate": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('endDate', ``, 'string') }}",
"eventId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('eventId', ``, 'string') }}",
"timeZone": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('timeZone', ``, 'string') }}",
"operation": "=getEvent",
"startDate": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('startDate', ``, 'string') }}"
},
"schema": [
{
"id": "operation",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "operation",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "startDate",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "startDate",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "endDate",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "endDate",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "eventId",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "eventId",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "timeZone",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "timeZone",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
}
},
"typeVersion": 2.1
},
{
"id": "51f39673-4657-401b-b1bf-34e816318acf",
"name": "create_new_event",
"type": "@n8n/n8n-nodes-langchain.toolWorkflow",
"position": [
80,
240
],
"parameters": {
"name": "create_new_event",
"workflowId": {
"__rl": true,
"mode": "list",
"value": "aiKrExd0rAxJO6xi",
"cachedResultName": "MCP_google_calendar"
},
"description": "Use this tool to create a new event; always validate if the gap of time is available before creating a new event ",
"workflowInputs": {
"value": {
"endDate": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('endDate', ``, 'string') }}",
"eventId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('eventId', ``, 'string') }}",
"timeZone": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('timeZone', ``, 'string') }}",
"operation": "createEvent",
"startDate": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('startDate', ``, 'string') }}"
},
"schema": [
{
"id": "operation",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "operation",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "startDate",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "startDate",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "endDate",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "endDate",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "eventId",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "eventId",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "timeZone",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "timeZone",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
}
},
"typeVersion": 2.1
},
{
"id": "3587c022-2f57-4bf6-8066-c292bcab5399",
"name": "delete_event",
"type": "@n8n/n8n-nodes-langchain.toolWorkflow",
"position": [
360,
240
],
"parameters": {
"name": "delete_event",
"workflowId": {
"__rl": true,
"mode": "list",
"value": "aiKrExd0rAxJO6xi",
"cachedResultName": "MCP_google_calendar"
},
"description": "Call this tool to delete a event, to delete a event you need the even id. it is required",
"workflowInputs": {
"value": {
"endDate": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('endDate', ``, 'string') }}",
"eventId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('eventId', ``, 'string') }}",
"timeZone": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('timeZone', ``, 'string') }}",
"operation": "deleteEvent",
"startDate": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('startDate', ``, 'string') }}"
},
"schema": [
{
"id": "operation",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "operation",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "startDate",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "startDate",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "endDate",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "endDate",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "eventId",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "eventId",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "timeZone",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "timeZone",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
}
},
"typeVersion": 2.1
},
{
"id": "1da9a808-b478-47cd-b129-2a11d83d8735",
"name": "update_event",
"type": "@n8n/n8n-nodes-langchain.toolWorkflow",
"position": [
220,
240
],
"parameters": {
"name": "update_event",
"workflowId": {
"__rl": true,
"mode": "list",
"value": "aiKrExd0rAxJO6xi",
"cachedResultName": "MCP_google_calendar"
},
"description": "Call this tool to update the event name, startDate or endDate. Validate with validate_busy_time before any action",
"workflowInputs": {
"value": {
"endDate": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('endDate', ``, 'string') }}",
"eventId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('eventId', ``, 'string') }}",
"timeZone": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('timeZone', ``, 'string') }}",
"operation": "updateEvent",
"startDate": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('startDate', ``, 'string') }}"
},
"schema": [
{
"id": "operation",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "operation",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "startDate",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "startDate",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "endDate",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "endDate",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "eventId",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "eventId",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "timeZone",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "timeZone",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
}
},
"typeVersion": 2.1
},
{
"id": "f3105e5b-0dec-44d0-ba5c-5bd91b0887d1",
"name": "validate_availability_event",
"type": "n8n-nodes-base.googleCalendar",
"position": [
2100,
-220
],
"parameters": {
"options": {},
"timeMax": "={{ $json.endDate }}",
"timeMin": "={{ $json.startDate }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "user@example.com"
},
"resource": "calendar"
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "43f2125b-85ea-455d-92ed-b84d0eb4a566",
"name": "check_availability_to_create",
"type": "n8n-nodes-base.googleCalendar",
"position": [
1780,
220
],
"parameters": {
"options": {},
"timeMax": "={{ $('map_data').item.json.endDate }}",
"timeMin": "={{ $('map_data').item.json.startDate }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "user@example.com"
},
"resource": "calendar"
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "7f2e1fef-79cb-4728-aa63-1afe038598ab",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
2000,
220
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "4ee8a84d-c48a-416f-aa31-0633ee59124b",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.available }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "b2523fe9-526b-4617-b404-59a0b0e6d0e0",
"name": "Stop and Error",
"type": "n8n-nodes-base.stopAndError",
"position": [
2220,
320
],
"parameters": {
"errorMessage": "The time you are trying to create the event is busy"
},
"typeVersion": 1
},
{
"id": "c72026c4-820d-4be0-9bbd-37b9ec6d2bf1",
"name": "create_event",
"type": "n8n-nodes-base.googleCalendar",
"position": [
2220,
160
],
"parameters": {
"end": "={{ $('map_data').item.json.endDate }}",
"start": "={{ $('map_data').item.json.startDate }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "user@example.com"
},
"additionalFields": {}
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "61f84fdb-768e-4b5f-9df9-21316dfa7678",
"name": "delete_event1",
"type": "n8n-nodes-base.googleCalendar",
"position": [
2120,
-20
],
"parameters": {
"eventId": "={{ $('map_data').item.json.eventId }}",
"options": {},
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "user@example.com"
},
"operation": "delete"
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "2544e1e6-e620-4794-b1d4-898b2e9722ad",
"name": "Edit Fields",
"type": "n8n-nodes-base.set",
"position": [
2320,
-220
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "973dfb96-eeda-45be-bc93-668c9118677f",
"name": "available",
"type": "boolean",
"value": "={{ $json.available }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "966dc7bb-b2c8-40b1-95d9-ad10b232d1b2",
"name": "get_event_in_time_gap",
"type": "n8n-nodes-base.googleCalendar",
"position": [
1860,
700
],
"parameters": {
"options": {},
"timeMax": "={{ $('map_data').item.json.endDate }}",
"timeMin": "={{ $('map_data').item.json.startDate }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "user@example.com"
},
"operation": "getAll"
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3,
"alwaysOutputData": true
},
{
"id": "7010b476-f500-4891-a795-30c75f0f077c",
"name": "update_calendar",
"type": "n8n-nodes-base.googleCalendar",
"position": [
1860,
480
],
"parameters": {
"eventId": "={{ $json.eventId }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "user@example.com"
},
"operation": "update",
"updateFields": {
"end": "={{ $json.endDate }}",
"start": "={{ $json.startDate }}"
}
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "933163a6-5597-48da-95de-7067dd55ad84",
"name": "get_events_in_gap_time",
"type": "@n8n/n8n-nodes-langchain.toolWorkflow",
"position": [
520,
240
],
"parameters": {
"name": "get_events_in_gap_time",
"workflowId": {
"__rl": true,
"mode": "list",
"value": "aiKrExd0rAxJO6xi",
"cachedResultName": "MCP_google_calendar"
},
"description": "Use this tool to get event data in a gap of time. but if you have just validate the availibity of the time use \"validate_busy_time\" tool this is tool is to get data",
"workflowInputs": {
"value": {
"endDate": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('endDate', ``, 'string') }}",
"eventId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('eventId', ``, 'string') }}",
"timeZone": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('timeZone', ``, 'string') }}",
"operation": "getEventData",
"startDate": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('startDate', ``, 'string') }}"
},
"schema": [
{
"id": "operation",
"type": "string",
"display": true,
"required": false,
"displayName": "operation",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "startDate",
"type": "string",
"display": true,
"required": false,
"displayName": "startDate",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "endDate",
"type": "string",
"display": true,
"required": false,
"displayName": "endDate",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "eventId",
"type": "string",
"display": true,
"required": false,
"displayName": "eventId",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "timeZone",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "timeZone",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
}
},
"typeVersion": 2.1
},
{
"id": "01c9435e-0258-4048-a3ad-cf84424fad6c",
"name": "map_data",
"type": "n8n-nodes-base.set",
"position": [
1240,
220
],
"parameters": {
"mode": "raw",
"options": {},
"jsonOutput": "={\n \"operation\": \"{{ $json.operation }}\",\n \"startDate\": \"{{ DateTime.fromISO($json.startDate).setZone($json.timeZone).toISO() }}\",\n \"endDate\": \"{{ DateTime.fromISO($json.endDate).setZone($json.timeZone).toISO() }}\",\n \"eventId\": \"{{ $json.eventId }}\",\n \"timeZone\": \"{{ $json.timeZone }}\"\n}\n"
},
"typeVersion": 3.4
},
{
"id": "0e3a8817-7485-499c-9692-7b920bb34b3f",
"name": "response_data_get_data",
"type": "n8n-nodes-base.set",
"position": [
2080,
700
],
"parameters": {
"mode": "raw",
"options": {},
"jsonOutput": "={\n \"isAvailableTime\":{{$json.values().length === 0}},\n\"eventData\":{\nid:\"{{ $json.id }}\"\n}\n}\n"
},
"typeVersion": 3.4
}
],
"active": true,
"settings": {
"executionOrder": "v1"
},
"versionId": "fbb67adf-7d52-4b42-8b61-a3c01470a1f9",
"connections": {
"If": {
"main": [
[
{
"node": "create_event",
"type": "main",
"index": 0
}
],
[
{
"node": "Stop and Error",
"type": "main",
"index": 0
}
]
]
},
"map_data": {
"main": [
[
{
"node": "Operation",
"type": "main",
"index": 0
}
]
]
},
"Operation": {
"main": [
[
{
"node": "validate_availability_event",
"type": "main",
"index": 0
}
],
[
{
"node": "delete_event1",
"type": "main",
"index": 0
}
],
[
{
"node": "check_availability_to_create",
"type": "main",
"index": 0
}
],
[
{
"node": "update_calendar",
"type": "main",
"index": 0
}
],
[
{
"node": "get_event_in_time_gap",
"type": "main",
"index": 0
}
]
]
},
"delete_event": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
},
"update_event": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
},
"create_new_event": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
},
"validate_busy_time": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
},
"get_event_in_time_gap": {
"main": [
[
{
"node": "response_data_get_data",
"type": "main",
"index": 0
}
]
]
},
"get_events_in_gap_time": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
},
"validate_availability_event": {
"main": [
[
{
"node": "Edit Fields",
"type": "main",
"index": 0
}
]
]
},
"check_availability_to_create": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"When Executed by Another Workflow": {
"main": [
[
{
"node": "map_data",
"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.
googleCalendarOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This n8n template implements an MCP (Model Context Protocol)-compliant module for managing Google Calendar events in a context-aware, conflict-free manner.
Source: https://n8n.io/workflows/4231/ — 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.
Googledrivetool Extractfromfile. Uses stickyNote, executeWorkflowTrigger, mcpTrigger, googleDrive. Event-driven trigger; 17 nodes.
Stickynote Executeworkflow. Uses executeWorkflowTrigger, stickyNote, mcpTrigger, toolCode. Event-driven trigger; 16 nodes.
Executeworkflow Executecommandtool. Uses stickyNote, mcpTrigger, executeCommandTool, executeWorkflowTrigger. Event-driven trigger; 14 nodes.
Workflow 3630. Uses mcpTrigger, executeCommandTool, executeWorkflowTrigger, executeCommand. Event-driven trigger; 14 nodes.
Agendamiento. Uses n8n-nodes-evolution-api, redis, dataTable, executeWorkflowTrigger. Event-driven trigger; 60 nodes.