{"workflow":{"id":14301,"name":"Modify Liveblocks storage with JSON Patch and Anthropic Claude","views":1,"recentViews":1,"totalViews":1,"createdAt":"2026-03-24T16:51:26.740Z","description":"## Modify Liveblocks Storage with JSON Patch\n\nThis example uses [Liveblocks Storage](https://liveblocks.io/docs/ready-made-features/multiplayer/sync-engine/liveblocks-storage), a sync engine created by [Liveblocks](https://liveblocks.io) that allows you to create collaborative applications like Figma, Pitch, and Spline. When we fetch the Storage value for a [room](https://liveblocks.io/docs/concepts#Rooms), we're fetching the state of the multiplayer document which users are collaborating on.   \n\nIn this workflow example, our document holds a list of shapes, like a drawing tool. Here's a rectangle, for example:\n\n```\n{\n  \"id\": \"rect-1\",\n  \"type\": \"rectangle\",\n  \"x\": 100,\n  \"y\": 150,\n  \"width\": 200,\n  \"height\": 100,\n  \"color\": \"#ff0000\"\n}\n```\n\nPicture this hooked up to a design tool like Figma, with the user asking AI to edit their document.\n\nIn these nodes, to generates a [JSON Patch](https://liveblocks.io/docs/guides/modifying-storage-via-rest-api-with-json-patch) operation from the user's request (\"Add a blue circle, and make the square orange\") and applies it to the collaborative document. \n\nAs soon as the JSON Patch operation has run, each user's design tool in their web browser will update with the changes in real time.\n\nAdditionally, we're setting presence in the room, which means that the AI will appear in the document's live avatar stacks while it works, before disappearing shortly after.","workflow":{"id":"siRmitBmFbvNMw_elDq6R","meta":{"instanceId":"fdd58b028250e4811c462e28c5cbca067bcbfe46a2f4e6fd38647ade19e87602","templateCredsSetupCompleted":true},"name":"Modify Liveblocks Storage with JSON Patch","tags":[],"nodes":[{"id":"6e1dccd1-9468-4674-8d5b-ca7a6d97eada","name":"When clicking ‘Execute workflow’","type":"n8n-nodes-base.manualTrigger","position":[-240,-32],"parameters":{},"typeVersion":1},{"id":"24255aba-7d7d-417a-9890-4da3962fec00","name":"Create a room","type":"CUSTOM.liveblocks","position":[-48,-32],"parameters":{"operation":"createRoom","createRoom_id":"={{ $execution.id }}","createRoom_defaultAccesses":"={{ [] }}"},"credentials":{"liveblocksApi":{"id":"FhEma6I53jlObzT2","name":"Liveblocks account 2"}},"typeVersion":1},{"id":"4a11137e-f359-4c83-9718-502c01ecf18d","name":"Patch room storage","type":"CUSTOM.liveblocks","position":[144,-32],"parameters":{"body":"[\n  {\n    \"op\": \"add\",\n    \"path\": \"/shapes\",\n    \"value\": [\n      {\n        \"id\": \"rect-1\",\n        \"type\": \"rectangle\",\n        \"x\": 100,\n        \"y\": 150,\n        \"width\": 200,\n        \"height\": 100,\n        \"color\": \"#ff0000\"\n      },\n      {\n        \"id\": \"circle-1\",\n        \"type\": \"circle\",\n        \"x\": 300,\n        \"y\": 200,\n        \"radius\": 50,\n        \"color\": \"#00ff00\"\n      }\n    ]\n  }\n]","roomId":"={{ $json.id }}","resource":"storage","operation":"patchStorageDocument"},"credentials":{"liveblocksApi":{"id":"FhEma6I53jlObzT2","name":"Liveblocks account 2"}},"typeVersion":1},{"id":"43afa742-6fe4-4071-a86b-1d6e4307d396","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[592,-32],"parameters":{"text":"=You are a JSON patch generatgor. All you return is JSPN patch operations. Here is the current document:\n\n```\n{{ JSON.stringify($json.shapes, null, 2) }}\n```\n\nHere is how you must modify the document:\n\n\"\"\"\nAdd a blue circle, and make the square orange. \n\"\"\"\n\nApply this change to `/shapes`.","options":{},"promptType":"define","hasOutputParser":true},"typeVersion":3.1},{"id":"5bfc5dd6-0439-4365-9faf-60ecca8405a2","name":"Get room storage","type":"CUSTOM.liveblocks","position":[400,-32],"parameters":{"roomId":"={{ $execution.id }}","resource":"storage","operation":"getStorageDocument","q_getStorageDocument_format":"json"},"credentials":{"liveblocksApi":{"id":"FhEma6I53jlObzT2","name":"Liveblocks account 2"}},"typeVersion":1},{"id":"443bd8f9-2d50-451a-ada7-4d797906009c","name":"Anthropic Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatAnthropic","position":[592,176],"parameters":{"model":{"__rl":true,"mode":"list","value":"claude-sonnet-4-6","cachedResultName":"Claude Sonnet 4.6"},"options":{}},"credentials":{"anthropicApi":{"id":"TLoCIyCNiIGbje8U","name":"Anthropic account"}},"typeVersion":1.3},{"id":"f4daa4dd-4106-46f2-82e8-8c91e75bada5","name":"Patch room storage1","type":"CUSTOM.liveblocks","position":[912,-32],"parameters":{"body":"={{ $json.output }}","roomId":"={{ $execution.id }}","resource":"storage","operation":"patchStorageDocument"},"credentials":{"liveblocksApi":{"id":"FhEma6I53jlObzT2","name":"Liveblocks account 2"}},"typeVersion":1},{"id":"91207bbf-a8c3-4424-90f4-f2f65700b5a7","name":"Structured Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[736,176],"parameters":{"schemaType":"manual","inputSchema":"={\n  \"type\": \"array\",\n  \"items\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"op\": {\n        \"type\": \"string\",\n        \"enum\": [\"add\", \"remove\", \"replace\"]\n      },\n      \"path\": {\n        \"type\": \"string\"\n      },\n      \"value\": {}\n    },\n    \"required\": [\"op\", \"path\"]\n  }\n}"},"typeVersion":1.3},{"id":"2b0083c0-9367-45b3-9a1e-4adc057dde49","name":"Get room storage1","type":"CUSTOM.liveblocks","position":[1216,-32],"parameters":{"roomId":"={{ $execution.id }}","resource":"storage","operation":"getStorageDocument","q_getStorageDocument_format":"json"},"credentials":{"liveblocksApi":{"id":"FhEma6I53jlObzT2","name":"Liveblocks account 2"}},"typeVersion":1},{"id":"890b299e-fc1d-450b-9d11-4f508085f668","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-656,-160],"parameters":{"width":336,"height":1008,"content":"## Modify Liveblocks Storage with JSON Patch\n\n### How it works\nThis example uses [Liveblocks Storage](https://liveblocks.io/docs/ready-made-features/multiplayer/sync-engine/liveblocks-storage), a sync engine created by [Liveblocks](https://liveblocks.io) that allows you to create collaborative applications like Figma, Pitch, and Spline. When we fetch the Storage value for a [room](https://liveblocks.io/docs/concepts#Rooms), we're fetching the state of the multiplayer document which users are collaborating on.   \n\nIn this workflow example, our document holds a list of shapes, like a drawing tool. Here's a rectangle, for example:\n\n```\n{\n  \"id\": \"rect-1\",\n  \"type\": \"rectangle\",\n  \"x\": 100,\n  \"y\": 150,\n  \"width\": 200,\n  \"height\": 100,\n  \"color\": \"#ff0000\"\n}\n```\n\nPicture this hooked up to a design tool like Figma, with the user asking AI to edit their document.\n\nIn these nodes, to generates a [JSON Patch](https://liveblocks.io/docs/guides/modifying-storage-via-rest-api-with-json-patch) operation from the user's request (\"Add a blue circle, and make the square orange\") and applies it to the collaborative document. \n\nAs soon as the JSON Patch operation has run, each user's design tool in their web browser will update with the changes in real time.\n\nAdditionally, we're setting presence in the room, which means that the AI will appear in the document's live avatar stacks while it works, before disappearing shortly after.\n\n### Setup\nNo setup required. Replace the trigger with any you like to use this workflow."},"typeVersion":1},{"id":"755f766e-03ef-4a68-9c38-ffd3df1e2f98","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-96,-144],"parameters":{"color":7,"width":384,"height":288,"content":"## Create a room\nCreate a multiplayer room and initialize it with a Storage value. In a real app, this'll already be created."},"typeVersion":1},{"id":"cb17c385-0125-421a-81d4-643267f0bf67","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[320,-144],"parameters":{"color":7,"width":768,"height":480,"content":"## Patching Storage with AI\nGetting the full Storage value, passing it to AI, and asking it to run a user query on the data. The AI is told to return JSON Patch operations, and is then applied to Storage. On the front end, the room updates in real time."},"typeVersion":1},{"id":"8c76fbef-ee98-4f95-a3e9-735e395aeb11","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1120,-144],"parameters":{"color":7,"width":294,"height":288,"content":"## Check value\nChecking the final value after applying the operation."},"typeVersion":1},{"id":"b4e7c6eb-7cd7-4330-b9ce-c629e87ab06c","name":"Set presence in a room","type":"CUSTOM.liveblocks","position":[432,464],"parameters":{"roomId":"={{ $execution.id }}","operation":"setPresence","setPresence_ttl":null,"setPresence_userId":"__AI_AGENT","setPresence_userInfo":"{\n  \"name\": \"AI Assistant\",\n  \"avatar\": \"https://liveblocks.io/api/avatar?u=__AI_AGENT&agent=true\"\n}"},"credentials":{"liveblocksApi":{"id":"FhEma6I53jlObzT2","name":"Liveblocks account 2"}},"typeVersion":1},{"id":"5444c0cb-e9a4-4282-bdc2-1906e0fb0f29","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[320,384],"parameters":{"color":7,"width":326,"height":240,"content":"## Show presence\nShow AI presence in the app's avatar stack."},"typeVersion":1},{"id":"2721aedc-d0cf-484c-8243-671837003c22","name":"Set presence in a room1","type":"CUSTOM.liveblocks","position":[880,464],"parameters":{"roomId":"={{ $execution.id }}","operation":"setPresence","setPresence_ttl":2,"setPresence_userId":"__AI_AGENT","setPresence_userInfo":"{\n  \"name\": \"AI Assistant\",\n  \"avatar\": \"https://liveblocks.io/api/avatar?u=__AI_AGENT&agent=true\"\n}"},"credentials":{"liveblocksApi":{"id":"FhEma6I53jlObzT2","name":"Liveblocks account 2"}},"typeVersion":1},{"id":"a883b6ad-ac74-47c5-b0f3-8893e4794f78","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[768,384],"parameters":{"color":7,"width":326,"height":240,"content":"## Hide presence\nTell the AI presence to expire in 2 seconds."},"typeVersion":1}],"active":false,"pinData":{},"settings":{"availableInMCP":false,"executionOrder":"v1"},"versionId":"abc3c565-0fb3-47e8-b22f-b2edb33d2b98","connections":{"AI Agent":{"main":[[{"node":"Patch room storage1","type":"main","index":0}]]},"Create a room":{"main":[[{"node":"Patch room storage","type":"main","index":0}]]},"Get room storage":{"main":[[{"node":"AI Agent","type":"main","index":0},{"node":"Set presence in a room","type":"main","index":0}]]},"Patch room storage":{"main":[[{"node":"Get room storage","type":"main","index":0}]]},"Patch room storage1":{"main":[[{"node":"Get room storage1","type":"main","index":0},{"node":"Set presence in a room1","type":"main","index":0}]]},"Anthropic Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Structured Output Parser":{"ai_outputParser":[[{"node":"AI Agent","type":"ai_outputParser","index":0}]]},"When clicking ‘Execute workflow’":{"main":[[{"node":"Create a room","type":"main","index":0}]]}}},"lastUpdatedBy":1,"workflowInfo":{"nodeCount":17,"nodeTypes":{"CUSTOM.liveblocks":{"count":7},"n8n-nodes-base.stickyNote":{"count":6},"n8n-nodes-base.manualTrigger":{"count":1},"@n8n/n8n-nodes-langchain.agent":{"count":1},"@n8n/n8n-nodes-langchain.lmChatAnthropic":{"count":1},"@n8n/n8n-nodes-langchain.outputParserStructured":{"count":1}}},"status":"published","readyToDemo":null,"user":{"name":"Liveblocks","username":"liveblocks","bio":"Liveblocks provides the infrastructure to handle concurrent edits on shared data, so people and AI agents can collaborate without breaking your app.","verified":true,"links":["https://liveblocks.io"],"avatar":"https://gravatar.com/avatar/2a107b003f338bc7a30a56e2be40b53c2f3ea3a8718db975beaa202f9e3cc3db?r=pg&d=retro&size=200"},"nodes":[{"id":565,"icon":"fa:sticky-note","name":"n8n-nodes-base.stickyNote","codex":{"data":{"alias":["Comments","Notes","Sticky"],"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"input\"]","defaults":{"name":"Sticky Note","color":"#FFD233"},"iconData":{"icon":"sticky-note","type":"icon"},"displayName":"Sticky Note","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":838,"icon":"fa:mouse-pointer","name":"n8n-nodes-base.manualTrigger","codex":{"data":{"resources":{"generic":[],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.manualworkflowtrigger/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0"}},"group":"[\"trigger\"]","defaults":{"name":"When clicking ‘Execute workflow’","color":"#909298"},"iconData":{"icon":"mouse-pointer","type":"icon"},"displayName":"Manual Trigger","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":1119,"icon":"fa:robot","name":"@n8n/n8n-nodes-langchain.agent","codex":{"data":{"alias":["LangChain","Chat","Conversational","Plan and Execute","ReAct","Tools"],"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.agent/"}]},"categories":["AI","Langchain"],"subcategories":{"AI":["Agents","Root Nodes"]}}},"group":"[\"transform\"]","defaults":{"name":"AI Agent","color":"#404040"},"iconData":{"icon":"robot","type":"icon"},"displayName":"AI Agent","typeVersion":3,"nodeCategories":[{"id":25,"name":"AI"},{"id":26,"name":"Langchain"}]},{"id":1145,"icon":"file:anthropic.svg","name":"@n8n/n8n-nodes-langchain.lmChatAnthropic","codex":{"data":{"alias":["claude","sonnet","opus"],"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.lmchatanthropic/"}]},"categories":["AI","Langchain"],"subcategories":{"AI":["Language Models","Root Nodes"],"Language Models":["Chat Models (Recommended)"]}}},"group":"[\"transform\"]","defaults":{"name":"Anthropic Chat Model"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NiIgaGVpZ2h0PSIzMiIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzdEN0Q4NyIgZD0iTTMyLjczIDBoLTYuOTQ1TDM4LjQ1IDMyaDYuOTQ1ek0xMi42NjUgMCAwIDMyaDcuMDgybDIuNTktNi43MmgxMy4yNWwyLjU5IDYuNzJoNy4wODJMMTkuOTI5IDB6bS0uNzAyIDE5LjMzNyA0LjMzNC0xMS4yNDYgNC4zMzQgMTEuMjQ2eiIvPjwvc3ZnPg=="},"displayName":"Anthropic Chat Model","typeVersion":1,"nodeCategories":[{"id":25,"name":"AI"},{"id":26,"name":"Langchain"}]},{"id":1179,"icon":"fa:code","name":"@n8n/n8n-nodes-langchain.outputParserStructured","codex":{"data":{"alias":["json","zod"],"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.outputparserstructured/"}]},"categories":["AI","Langchain"],"subcategories":{"AI":["Output Parsers"]}}},"group":"[\"transform\"]","defaults":{"name":"Structured Output Parser"},"iconData":{"icon":"code","type":"icon"},"displayName":"Structured Output Parser","typeVersion":1,"nodeCategories":[{"id":25,"name":"AI"},{"id":26,"name":"Langchain"}]}],"categories":[{"id":5,"name":"Engineering"},{"id":48,"name":"AI RAG"}],"image":[]}}