mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-04-04 00:23:08 +00:00
feat: add patchNodeField operation for surgical string edits (v2.46.0) (#698)
Add dedicated `patchNodeField` operation to `n8n_update_partial_workflow` for surgical find/replace edits in node string fields. Strict alternative to the existing `__patch_find_replace` in updateNode — errors on not-found, detects ambiguous matches, supports replaceAll and regex flags. Security hardening: - Prototype pollution protection in setNestedProperty/getNestedProperty - ReDoS protection rejecting unsafe regex patterns (nested quantifiers) - Resource limits: max 50 patches, 500-char regex, 512KB field size Fixes #696 Conceived by Romuald Członkowski - https://www.aiadvisors.pl/en Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
parent
ca20586eda
commit
2d4115530c
10
dist/mcp/handlers-workflow-diff.js
vendored
10
dist/mcp/handlers-workflow-diff.js
vendored
@@ -51,7 +51,7 @@ function getValidator(repository) {
|
||||
return cachedValidator;
|
||||
}
|
||||
const NODE_TARGETING_OPERATIONS = new Set([
|
||||
'updateNode', 'removeNode', 'moveNode', 'enableNode', 'disableNode'
|
||||
'updateNode', 'removeNode', 'moveNode', 'enableNode', 'disableNode', 'patchNodeField'
|
||||
]);
|
||||
const workflowDiffSchema = zod_1.z.object({
|
||||
id: zod_1.z.string(),
|
||||
@@ -62,6 +62,8 @@ const workflowDiffSchema = zod_1.z.object({
|
||||
nodeId: zod_1.z.string().optional(),
|
||||
nodeName: zod_1.z.string().optional(),
|
||||
updates: zod_1.z.any().optional(),
|
||||
fieldPath: zod_1.z.string().optional(),
|
||||
patches: zod_1.z.any().optional(),
|
||||
position: zod_1.z.tuple([zod_1.z.number(), zod_1.z.number()]).optional(),
|
||||
source: zod_1.z.string().optional(),
|
||||
target: zod_1.z.string().optional(),
|
||||
@@ -506,6 +508,8 @@ function inferIntentFromOperations(operations) {
|
||||
return `Remove node ${op.nodeName || op.nodeId || ''}`.trim();
|
||||
case 'updateNode':
|
||||
return `Update node ${op.nodeName || op.nodeId || ''}`.trim();
|
||||
case 'patchNodeField':
|
||||
return `Patch field on node ${op.nodeName || op.nodeId || ''}`.trim();
|
||||
case 'addConnection':
|
||||
return `Connect ${op.source || 'node'} to ${op.target || 'node'}`;
|
||||
case 'removeConnection':
|
||||
@@ -538,6 +542,10 @@ function inferIntentFromOperations(operations) {
|
||||
const count = opTypes.filter((t) => t === 'updateNode').length;
|
||||
summary.push(`update ${count} node${count > 1 ? 's' : ''}`);
|
||||
}
|
||||
if (typeSet.has('patchNodeField')) {
|
||||
const count = opTypes.filter((t) => t === 'patchNodeField').length;
|
||||
summary.push(`patch ${count} field${count > 1 ? 's' : ''}`);
|
||||
}
|
||||
if (typeSet.has('addConnection') || typeSet.has('rewireConnection')) {
|
||||
summary.push('modify connections');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user