From 2713db6d106f30554f3f144c548504c2097f2741 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Fri, 2 Jan 2026 08:48:47 -0600 Subject: [PATCH] feat: add MCP tool annotations to all 20 tools (#512) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add MCP tool annotations to all 20 tools Add MCP tool annotations per specification to help AI assistants understand tool behavior and capabilities. Documentation tools (7): - tools_documentation, search_nodes, get_node, validate_node, get_template, search_templates, validate_workflow - All marked readOnlyHint=true (local database queries) Management tools (13): - n8n_create_workflow, n8n_get_workflow, n8n_update_full_workflow, n8n_update_partial_workflow, n8n_delete_workflow, n8n_list_workflows, n8n_validate_workflow, n8n_autofix_workflow, n8n_test_workflow, n8n_executions, n8n_health_check, n8n_workflow_versions, n8n_deploy_template - All marked openWorldHint=true (n8n API access) - Destructive operations (delete_workflow, executions delete, workflow_versions delete/truncate) marked destructiveHint=true Annotations follow MCP spec: https://spec.modelcontextprotocol.io/specification/2025-03-26/server/tools/#annotations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 * feat: add idempotentHint to all read-only tools Adds idempotentHint: true annotation to all read-only tools that produce the same output when called multiple times: - 7 documentation tools (tools.ts) - 4 management tools (tools-n8n-manager.ts): n8n_get_workflow, n8n_list_workflows, n8n_validate_workflow, n8n_health_check Also adds trailing newline to tools-n8n-manager.ts. Conceived by Romuald Członkowski - www.aiadvisors.pl/en 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 * feat: add idempotentHint to update operations, bump to 2.31.5 Adds idempotentHint: true to update operations that produce the same result when called repeatedly with the same arguments: - n8n_update_full_workflow - n8n_update_partial_workflow - n8n_autofix_workflow Also bumps version to 2.31.5 and updates CHANGELOG.md with complete documentation of all MCP tool annotations added in this PR. Conceived by Romuald Członkowski - www.aiadvisors.pl/en 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --------- Co-authored-by: triepod-ai Co-authored-by: Claude Opus 4.5 Co-authored-by: Romuald Członkowski --- CHANGELOG.md | 23 +++++++ package.json | 2 +- src/mcp/tools-n8n-manager.ts | 121 +++++++++++++++++++++++++++++------ src/mcp/tools.ts | 35 ++++++++++ src/types/index.ts | 19 ++++++ 5 files changed, 179 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57267f7..5567c33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [2.31.5] - 2026-01-02 + +### Added + +**MCP Tool Annotations (PR #512)** + +Added MCP tool annotations to all 20 tools following the [MCP specification](https://spec.modelcontextprotocol.io/specification/2025-03-26/server/tools/#annotations). These annotations help AI assistants understand tool behavior and capabilities. + +**Annotations added:** +- `title`: Human-readable name for each tool +- `readOnlyHint`: True for tools that don't modify state (11 tools) +- `destructiveHint`: True for delete operations (3 tools) +- `idempotentHint`: True for operations that produce same result when called repeatedly (14 tools) +- `openWorldHint`: True for tools accessing external n8n API (13 tools) + +**Documentation tools** (7): All marked `readOnlyHint=true`, `idempotentHint=true` +- `tools_documentation`, `search_nodes`, `get_node`, `validate_node`, `get_template`, `search_templates`, `validate_workflow` + +**Management tools** (13): All marked `openWorldHint=true` +- Read-only: `n8n_get_workflow`, `n8n_list_workflows`, `n8n_validate_workflow`, `n8n_health_check` +- Idempotent updates: `n8n_update_full_workflow`, `n8n_update_partial_workflow`, `n8n_autofix_workflow` +- Destructive: `n8n_delete_workflow`, `n8n_executions` (delete action), `n8n_workflow_versions` (delete/truncate) + ## [2.31.4] - 2026-01-02 ### Fixed diff --git a/package.json b/package.json index 5a94b29..dd1bae0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "n8n-mcp", - "version": "2.31.4", + "version": "2.31.5", "description": "Integration between n8n workflow automation and Model Context Protocol (MCP)", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/mcp/tools-n8n-manager.ts b/src/mcp/tools-n8n-manager.ts index 55ac582..0f0ab4a 100644 --- a/src/mcp/tools-n8n-manager.ts +++ b/src/mcp/tools-n8n-manager.ts @@ -66,7 +66,13 @@ export const n8nManagementTools: ToolDefinition[] = [ } }, required: ['name', 'nodes', 'connections'] - } + }, + annotations: { + title: 'Create Workflow', + readOnlyHint: false, + destructiveHint: false, + openWorldHint: true, + }, }, { name: 'n8n_get_workflow', @@ -86,7 +92,13 @@ export const n8nManagementTools: ToolDefinition[] = [ } }, required: ['id'] - } + }, + annotations: { + title: 'Get Workflow', + readOnlyHint: true, + idempotentHint: true, + openWorldHint: true, + }, }, { name: 'n8n_update_full_workflow', @@ -120,7 +132,14 @@ export const n8nManagementTools: ToolDefinition[] = [ } }, required: ['id'] - } + }, + annotations: { + title: 'Update Full Workflow', + readOnlyHint: false, + destructiveHint: false, + idempotentHint: true, + openWorldHint: true, + }, }, { name: 'n8n_update_partial_workflow', @@ -151,7 +170,14 @@ export const n8nManagementTools: ToolDefinition[] = [ } }, required: ['id', 'operations'] - } + }, + annotations: { + title: 'Update Partial Workflow', + readOnlyHint: false, + destructiveHint: false, + idempotentHint: true, + openWorldHint: true, + }, }, { name: 'n8n_delete_workflow', @@ -165,7 +191,13 @@ export const n8nManagementTools: ToolDefinition[] = [ } }, required: ['id'] - } + }, + annotations: { + title: 'Delete Workflow', + readOnlyHint: false, + destructiveHint: true, + openWorldHint: true, + }, }, { name: 'n8n_list_workflows', @@ -194,12 +226,18 @@ export const n8nManagementTools: ToolDefinition[] = [ type: 'string', description: 'Filter by project ID (enterprise feature)' }, - excludePinnedData: { - type: 'boolean', - description: 'Exclude pinned data from response (default: true)' + excludePinnedData: { + type: 'boolean', + description: 'Exclude pinned data from response (default: true)' } } - } + }, + annotations: { + title: 'List Workflows', + readOnlyHint: true, + idempotentHint: true, + openWorldHint: true, + }, }, { name: 'n8n_validate_workflow', @@ -227,16 +265,22 @@ export const n8nManagementTools: ToolDefinition[] = [ type: 'boolean', description: 'Validate n8n expressions (default: true)' }, - profile: { - type: 'string', + profile: { + type: 'string', enum: ['minimal', 'runtime', 'ai-friendly', 'strict'], - description: 'Validation profile to use (default: runtime)' + description: 'Validation profile to use (default: runtime)' } } } }, required: ['id'] - } + }, + annotations: { + title: 'Validate Workflow', + readOnlyHint: true, + idempotentHint: true, + openWorldHint: true, + }, }, { name: 'n8n_autofix_workflow', @@ -271,7 +315,14 @@ export const n8nManagementTools: ToolDefinition[] = [ } }, required: ['id'] - } + }, + annotations: { + title: 'Autofix Workflow', + readOnlyHint: false, + destructiveHint: false, + idempotentHint: true, + openWorldHint: true, + }, }, // Execution Management Tools @@ -328,7 +379,13 @@ export const n8nManagementTools: ToolDefinition[] = [ } }, required: ['workflowId'] - } + }, + annotations: { + title: 'Test Workflow', + readOnlyHint: false, + destructiveHint: false, + openWorldHint: true, + }, }, { name: 'n8n_executions', @@ -410,7 +467,13 @@ export const n8nManagementTools: ToolDefinition[] = [ } }, required: ['action'] - } + }, + annotations: { + title: 'Manage Executions', + readOnlyHint: false, + destructiveHint: true, + openWorldHint: true, + }, }, // System Tools @@ -431,7 +494,13 @@ export const n8nManagementTools: ToolDefinition[] = [ description: 'Include extra details in diagnostic mode (default: false)' } } - } + }, + annotations: { + title: 'Health Check', + readOnlyHint: true, + idempotentHint: true, + openWorldHint: true, + }, }, { name: 'n8n_workflow_versions', @@ -485,7 +554,13 @@ export const n8nManagementTools: ToolDefinition[] = [ } }, required: ['mode'] - } + }, + annotations: { + title: 'Workflow Versions', + readOnlyHint: false, + destructiveHint: true, + openWorldHint: true, + }, }, // Template Deployment Tool @@ -520,6 +595,12 @@ export const n8nManagementTools: ToolDefinition[] = [ } }, required: ['templateId'] - } + }, + annotations: { + title: 'Deploy Template', + readOnlyHint: false, + destructiveHint: false, + openWorldHint: true, + }, } -]; \ No newline at end of file +]; diff --git a/src/mcp/tools.ts b/src/mcp/tools.ts index cc71ce3..6fb4a0b 100644 --- a/src/mcp/tools.ts +++ b/src/mcp/tools.ts @@ -25,6 +25,11 @@ export const n8nDocumentationToolsFinal: ToolDefinition[] = [ }, }, }, + annotations: { + title: 'Tools Documentation', + readOnlyHint: true, + idempotentHint: true, + }, }, { name: 'search_nodes', @@ -55,6 +60,11 @@ export const n8nDocumentationToolsFinal: ToolDefinition[] = [ }, required: ['query'], }, + annotations: { + title: 'Search Nodes', + readOnlyHint: true, + idempotentHint: true, + }, }, { name: 'get_node', @@ -108,6 +118,11 @@ export const n8nDocumentationToolsFinal: ToolDefinition[] = [ }, required: ['nodeType'], }, + annotations: { + title: 'Get Node Info', + readOnlyHint: true, + idempotentHint: true, + }, }, { name: 'validate_node', @@ -188,6 +203,11 @@ export const n8nDocumentationToolsFinal: ToolDefinition[] = [ }, required: ['nodeType', 'displayName', 'valid'] }, + annotations: { + title: 'Validate Node Config', + readOnlyHint: true, + idempotentHint: true, + }, }, { name: 'get_template', @@ -208,6 +228,11 @@ export const n8nDocumentationToolsFinal: ToolDefinition[] = [ }, required: ['templateId'], }, + annotations: { + title: 'Get Template', + readOnlyHint: true, + idempotentHint: true, + }, }, { name: 'search_templates', @@ -303,6 +328,11 @@ export const n8nDocumentationToolsFinal: ToolDefinition[] = [ }, }, }, + annotations: { + title: 'Search Templates', + readOnlyHint: true, + idempotentHint: true, + }, }, { name: 'validate_workflow', @@ -388,6 +418,11 @@ export const n8nDocumentationToolsFinal: ToolDefinition[] = [ }, required: ['valid', 'summary'] }, + annotations: { + title: 'Validate Workflow', + readOnlyHint: true, + idempotentHint: true, + }, }, ]; diff --git a/src/types/index.ts b/src/types/index.ts index ccddfbf..c7c4d22 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -10,6 +10,23 @@ export interface MCPServerConfig { authToken?: string; } +/** + * MCP Tool annotations to help AI assistants understand tool behavior. + * Per MCP spec: https://spec.modelcontextprotocol.io/specification/2025-03-26/server/tools/#annotations + */ +export interface ToolAnnotations { + /** Human-readable title for the tool */ + title?: string; + /** If true, the tool does not modify its environment */ + readOnlyHint?: boolean; + /** If true, the tool may perform destructive updates to its environment */ + destructiveHint?: boolean; + /** If true, calling the tool repeatedly with the same arguments has no additional effect */ + idempotentHint?: boolean; + /** If true, the tool may interact with external entities (APIs, services) */ + openWorldHint?: boolean; +} + export interface ToolDefinition { name: string; description: string; @@ -25,6 +42,8 @@ export interface ToolDefinition { required?: string[]; additionalProperties?: boolean | Record; }; + /** Tool behavior hints for AI assistants */ + annotations?: ToolAnnotations; } export interface ResourceDefinition {