mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-01-30 06:22:04 +00:00
This commit adds automatic detection of n8n server version and filters workflow settings properties based on what the target version supports. Changes: - Add n8n-version.ts service for version detection via /rest/settings - Fix nested response structure handling (data.data.versionCli) - Add N8nVersionInfo and N8nSettingsData types - Update N8nApiClient with getVersion() and version-aware filtering - Clean workflow settings before API update based on detected version Version compatibility: - n8n < 1.37.0: 7 core properties only - n8n 1.37.0+: adds executionOrder - n8n 1.119.0+: adds callerPolicy, callerIds, timeSavedPerExecution, availableInMCP Fixes #466
401 lines
8.8 KiB
TypeScript
401 lines
8.8 KiB
TypeScript
// n8n API Types - Ported from n8n-manager-for-ai-agents
|
|
// These types define the structure of n8n API requests and responses
|
|
|
|
// Resource Locator Types
|
|
export interface ResourceLocatorValue {
|
|
__rl: true;
|
|
value: string;
|
|
mode: 'id' | 'url' | 'expression' | string;
|
|
}
|
|
|
|
// Expression Format Types
|
|
export type ExpressionValue = string | ResourceLocatorValue;
|
|
|
|
// Workflow Node Types
|
|
export interface WorkflowNode {
|
|
id: string;
|
|
name: string;
|
|
type: string;
|
|
typeVersion: number;
|
|
position: [number, number];
|
|
parameters: Record<string, unknown>;
|
|
credentials?: Record<string, unknown>;
|
|
disabled?: boolean;
|
|
notes?: string;
|
|
notesInFlow?: boolean;
|
|
continueOnFail?: boolean;
|
|
onError?: 'continueRegularOutput' | 'continueErrorOutput' | 'stopWorkflow';
|
|
retryOnFail?: boolean;
|
|
maxTries?: number;
|
|
waitBetweenTries?: number;
|
|
alwaysOutputData?: boolean;
|
|
executeOnce?: boolean;
|
|
webhookId?: string; // n8n assigns this for webhook/form/chat trigger nodes
|
|
}
|
|
|
|
export interface WorkflowConnection {
|
|
[sourceNodeId: string]: {
|
|
[outputType: string]: Array<Array<{
|
|
node: string;
|
|
type: string;
|
|
index: number;
|
|
}>>;
|
|
};
|
|
}
|
|
|
|
export interface WorkflowSettings {
|
|
executionOrder?: 'v0' | 'v1';
|
|
timezone?: string;
|
|
saveDataErrorExecution?: 'all' | 'none';
|
|
saveDataSuccessExecution?: 'all' | 'none';
|
|
saveManualExecutions?: boolean;
|
|
saveExecutionProgress?: boolean;
|
|
executionTimeout?: number;
|
|
errorWorkflow?: string;
|
|
}
|
|
|
|
export interface Workflow {
|
|
id?: string;
|
|
name: string;
|
|
description?: string; // Returned by GET but must be excluded from PUT/PATCH (n8n API limitation, Issue #431)
|
|
nodes: WorkflowNode[];
|
|
connections: WorkflowConnection;
|
|
active?: boolean; // Optional for creation as it's read-only
|
|
isArchived?: boolean; // Optional, available in newer n8n versions
|
|
settings?: WorkflowSettings;
|
|
staticData?: Record<string, unknown>;
|
|
tags?: string[];
|
|
updatedAt?: string;
|
|
createdAt?: string;
|
|
versionId?: string;
|
|
versionCounter?: number; // Added: n8n 1.118.1+ returns this in GET responses
|
|
meta?: {
|
|
instanceId?: string;
|
|
};
|
|
}
|
|
|
|
// Execution Types
|
|
export enum ExecutionStatus {
|
|
SUCCESS = 'success',
|
|
ERROR = 'error',
|
|
WAITING = 'waiting',
|
|
// Note: 'running' status is not returned by the API
|
|
}
|
|
|
|
export interface ExecutionSummary {
|
|
id: string;
|
|
finished: boolean;
|
|
mode: string;
|
|
retryOf?: string;
|
|
retrySuccessId?: string;
|
|
status: ExecutionStatus;
|
|
startedAt: string;
|
|
stoppedAt?: string;
|
|
workflowId: string;
|
|
workflowName?: string;
|
|
waitTill?: string;
|
|
}
|
|
|
|
export interface ExecutionData {
|
|
startData?: Record<string, unknown>;
|
|
resultData: {
|
|
runData: Record<string, unknown>;
|
|
lastNodeExecuted?: string;
|
|
error?: Record<string, unknown>;
|
|
};
|
|
executionData?: Record<string, unknown>;
|
|
}
|
|
|
|
export interface Execution extends ExecutionSummary {
|
|
data?: ExecutionData;
|
|
}
|
|
|
|
// Credential Types
|
|
export interface Credential {
|
|
id?: string;
|
|
name: string;
|
|
type: string;
|
|
data?: Record<string, unknown>;
|
|
nodesAccess?: Array<{
|
|
nodeType: string;
|
|
date?: string;
|
|
}>;
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
}
|
|
|
|
// Tag Types
|
|
export interface Tag {
|
|
id?: string;
|
|
name: string;
|
|
workflowIds?: string[];
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
}
|
|
|
|
// Variable Types
|
|
export interface Variable {
|
|
id?: string;
|
|
key: string;
|
|
value: string;
|
|
type?: 'string';
|
|
}
|
|
|
|
// Import/Export Types
|
|
export interface WorkflowExport {
|
|
id: string;
|
|
name: string;
|
|
active: boolean;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
nodes: WorkflowNode[];
|
|
connections: WorkflowConnection;
|
|
settings?: WorkflowSettings;
|
|
staticData?: Record<string, unknown>;
|
|
tags?: string[];
|
|
pinData?: Record<string, unknown>;
|
|
versionId?: string;
|
|
versionCounter?: number; // Added: n8n 1.118.1+
|
|
meta?: Record<string, unknown>;
|
|
}
|
|
|
|
export interface WorkflowImport {
|
|
name: string;
|
|
nodes: WorkflowNode[];
|
|
connections: WorkflowConnection;
|
|
settings?: WorkflowSettings;
|
|
staticData?: Record<string, unknown>;
|
|
tags?: string[];
|
|
pinData?: Record<string, unknown>;
|
|
}
|
|
|
|
// Source Control Types
|
|
export interface SourceControlStatus {
|
|
ahead: number;
|
|
behind: number;
|
|
conflicted: string[];
|
|
created: string[];
|
|
current: string;
|
|
deleted: string[];
|
|
detached: boolean;
|
|
files: Array<{
|
|
path: string;
|
|
status: string;
|
|
}>;
|
|
modified: string[];
|
|
notAdded: string[];
|
|
renamed: Array<{
|
|
from: string;
|
|
to: string;
|
|
}>;
|
|
staged: string[];
|
|
tracking: string;
|
|
}
|
|
|
|
export interface SourceControlPullResult {
|
|
conflicts: string[];
|
|
files: Array<{
|
|
path: string;
|
|
status: string;
|
|
}>;
|
|
mergeConflicts: boolean;
|
|
pullResult: 'success' | 'conflict' | 'error';
|
|
}
|
|
|
|
export interface SourceControlPushResult {
|
|
ahead: number;
|
|
conflicts: string[];
|
|
files: Array<{
|
|
path: string;
|
|
status: string;
|
|
}>;
|
|
pushResult: 'success' | 'conflict' | 'error';
|
|
}
|
|
|
|
// Health Check Types
|
|
export interface HealthCheckResponse {
|
|
status: 'ok' | 'error';
|
|
instanceId?: string;
|
|
n8nVersion?: string;
|
|
features?: {
|
|
sourceControl?: boolean;
|
|
externalHooks?: boolean;
|
|
workers?: boolean;
|
|
[key: string]: boolean | undefined;
|
|
};
|
|
}
|
|
|
|
// n8n Version Information
|
|
export interface N8nVersionInfo {
|
|
version: string; // Full version string, e.g., "1.119.0"
|
|
major: number; // Major version number
|
|
minor: number; // Minor version number
|
|
patch: number; // Patch version number
|
|
}
|
|
|
|
// Settings data within the response
|
|
export interface N8nSettingsData {
|
|
n8nVersion?: string;
|
|
versionCli?: string;
|
|
instanceId?: string;
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
// Response from /rest/settings endpoint (unauthenticated)
|
|
// The actual response wraps settings in a "data" property
|
|
export interface N8nSettingsResponse {
|
|
data?: N8nSettingsData;
|
|
}
|
|
|
|
// Request Parameter Types
|
|
export interface WorkflowListParams {
|
|
limit?: number;
|
|
cursor?: string;
|
|
active?: boolean;
|
|
tags?: string | null; // Comma-separated string per n8n API spec
|
|
projectId?: string;
|
|
excludePinnedData?: boolean;
|
|
instance?: string;
|
|
}
|
|
|
|
export interface WorkflowListResponse {
|
|
data: Workflow[];
|
|
nextCursor?: string | null;
|
|
}
|
|
|
|
export interface ExecutionListParams {
|
|
limit?: number;
|
|
cursor?: string;
|
|
workflowId?: string;
|
|
projectId?: string;
|
|
status?: ExecutionStatus;
|
|
includeData?: boolean;
|
|
}
|
|
|
|
export interface ExecutionListResponse {
|
|
data: Execution[];
|
|
nextCursor?: string | null;
|
|
}
|
|
|
|
export interface CredentialListParams {
|
|
limit?: number;
|
|
cursor?: string;
|
|
filter?: Record<string, unknown>;
|
|
}
|
|
|
|
export interface CredentialListResponse {
|
|
data: Credential[];
|
|
nextCursor?: string | null;
|
|
}
|
|
|
|
export interface TagListParams {
|
|
limit?: number;
|
|
cursor?: string;
|
|
withUsageCount?: boolean;
|
|
}
|
|
|
|
export interface TagListResponse {
|
|
data: Tag[];
|
|
nextCursor?: string | null;
|
|
}
|
|
|
|
// Webhook Request Type
|
|
export interface WebhookRequest {
|
|
webhookUrl: string;
|
|
httpMethod: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
data?: Record<string, unknown>;
|
|
headers?: Record<string, string>;
|
|
waitForResponse?: boolean;
|
|
}
|
|
|
|
// MCP Tool Response Type
|
|
export interface McpToolResponse {
|
|
success: boolean;
|
|
data?: unknown;
|
|
error?: string;
|
|
message?: string;
|
|
code?: string;
|
|
details?: Record<string, unknown>;
|
|
executionId?: string;
|
|
workflowId?: string;
|
|
}
|
|
|
|
// Execution Filtering Types
|
|
export type ExecutionMode = 'preview' | 'summary' | 'filtered' | 'full';
|
|
|
|
export interface ExecutionPreview {
|
|
totalNodes: number;
|
|
executedNodes: number;
|
|
estimatedSizeKB: number;
|
|
nodes: Record<string, NodePreview>;
|
|
}
|
|
|
|
export interface NodePreview {
|
|
status: 'success' | 'error';
|
|
itemCounts: {
|
|
input: number;
|
|
output: number;
|
|
};
|
|
dataStructure: Record<string, any>;
|
|
estimatedSizeKB: number;
|
|
error?: string;
|
|
}
|
|
|
|
export interface ExecutionRecommendation {
|
|
canFetchFull: boolean;
|
|
suggestedMode: ExecutionMode;
|
|
suggestedItemsLimit?: number;
|
|
reason: string;
|
|
}
|
|
|
|
export interface ExecutionFilterOptions {
|
|
mode?: ExecutionMode;
|
|
nodeNames?: string[];
|
|
itemsLimit?: number;
|
|
includeInputData?: boolean;
|
|
fieldsToInclude?: string[];
|
|
}
|
|
|
|
export interface FilteredExecutionResponse {
|
|
id: string;
|
|
workflowId: string;
|
|
status: ExecutionStatus;
|
|
mode: ExecutionMode;
|
|
startedAt: string;
|
|
stoppedAt?: string;
|
|
duration?: number;
|
|
finished: boolean;
|
|
|
|
// Preview-specific data
|
|
preview?: ExecutionPreview;
|
|
recommendation?: ExecutionRecommendation;
|
|
|
|
// Summary/Filtered data
|
|
summary?: {
|
|
totalNodes: number;
|
|
executedNodes: number;
|
|
totalItems: number;
|
|
hasMoreData: boolean;
|
|
};
|
|
nodes?: Record<string, FilteredNodeData>;
|
|
|
|
// Error information
|
|
error?: Record<string, unknown>;
|
|
}
|
|
|
|
export interface FilteredNodeData {
|
|
executionTime?: number;
|
|
itemsInput: number;
|
|
itemsOutput: number;
|
|
status: 'success' | 'error';
|
|
error?: string;
|
|
data?: {
|
|
input?: any[][];
|
|
output?: any[][];
|
|
metadata: {
|
|
totalItems: number;
|
|
itemsShown: number;
|
|
truncated: boolean;
|
|
};
|
|
};
|
|
} |