n8n-nodes-clientify 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Clientify
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,378 @@
1
+ # n8n-nodes-clientify
2
+
3
+ [![npm version](https://badge.fury.io/js/n8n-nodes-clientify.svg)](https://www.npmjs.com/package/n8n-nodes-clientify)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ N8N community node for integrating with Clientify CRM via Model Context Protocol (MCP). This node provides seamless access to all Clientify CRM operations including contacts, companies, deals, tasks, and more.
7
+
8
+ ## Table of Contents
9
+
10
+ - [Installation](#installation)
11
+ - [Prerequisites](#prerequisites)
12
+ - [Configuration](#configuration)
13
+ - [Available Operations](#available-operations)
14
+ - [Usage Examples](#usage-examples)
15
+ - [Troubleshooting](#troubleshooting)
16
+ - [Support](#support)
17
+ - [License](#license)
18
+
19
+ ## Installation
20
+
21
+ ### In n8n (GUI)
22
+
23
+ 1. Go to **Settings** → **Community Nodes**
24
+ 2. Click **Install**
25
+ 3. Enter: `n8n-nodes-clientify`
26
+ 4. Click **I understand the risks** and then **Install**
27
+ 5. **Restart n8n** (important - the node won't appear until you restart)
28
+
29
+ ### Via npm (Command Line)
30
+
31
+ ```bash
32
+ cd ~/.n8n/nodes
33
+ npm install n8n-nodes-clientify
34
+ # Restart n8n
35
+ ```
36
+
37
+ ### Docker
38
+
39
+ If running n8n in Docker, ensure you persist the nodes directory:
40
+
41
+ ```yaml
42
+ volumes:
43
+ - n8n_data:/home/node/.n8n
44
+ ```
45
+
46
+ Or enable auto-reinstall on restart:
47
+
48
+ ```yaml
49
+ environment:
50
+ - N8N_REINSTALL_MISSING_PACKAGES=true
51
+ ```
52
+
53
+ ## Prerequisites
54
+
55
+ - **n8n version:** 0.180.0 or higher
56
+ - **Node.js version:** 20.15 or higher
57
+ - **Clientify Account:** Active Clientify CRM account with API access
58
+ - **Authentication Token:** JWT token from Clientify MCP server
59
+
60
+ ## Configuration
61
+
62
+ ### Step 1: Obtain Your Clientify MCP Token
63
+
64
+ 1. Log into your Clientify account
65
+ 2. Navigate to API settings or contact your Clientify administrator
66
+ 3. Generate or copy your MCP authentication token (JWT format)
67
+
68
+ ### Step 2: Add Credentials in n8n
69
+
70
+ 1. In n8n, go to **Credentials** → **New**
71
+ 2. Search for **"Clientify MCP API"**
72
+ 3. Enter your **Authentication Token** (JWT)
73
+ 4. Click **Save**
74
+
75
+ ### Step 3: Use the Node
76
+
77
+ 1. In your workflow, click **+** to add a node
78
+ 2. Search for **"Clientify"**
79
+ 3. Select the **Clientify** node
80
+ 4. Choose your saved credentials
81
+ 5. Select an operation from the dropdown
82
+ 6. Configure the parameters for your operation
83
+
84
+ ## Available Operations
85
+
86
+ This node dynamically supports **26 operations** from the Clientify MCP API:
87
+
88
+ ### 📊 Companies
89
+ - **List Companies** - Retrieve all companies with pagination
90
+ - **Get Company** - Get detailed information for a specific company by ID
91
+ - **Create Company** - Create a new company in the CRM
92
+ - **Update Company** - Update an existing company
93
+ - **Delete Company** - Remove a company from the CRM
94
+ - **Search Companies** - Search for companies by criteria
95
+
96
+ ### 👥 Contacts
97
+ - **List Contacts** - Retrieve all contacts or search for specific contacts
98
+ - **Get Contact** - Get detailed information for a specific contact by ID
99
+ - **Create Contact** - Create a new contact in the CRM
100
+ - **Update Contact** - Update an existing contact
101
+ - **Delete Contact** - Remove a contact from the CRM
102
+
103
+ ### 💼 Deals
104
+ - **List Deals** - Retrieve all deals with filtering and pagination
105
+ - **List Deals By Stage** - Filter deals by pipeline stage
106
+ - **Get Deal** - Get detailed information for a specific deal by ID
107
+ - **Create Deal** - Create a new deal/opportunity
108
+ - **Update Deal** - Update an existing deal
109
+ - **Delete Deal** - Remove a deal from the CRM
110
+ - **Mark Deal Won** - Mark a deal as won/closed successfully
111
+ - **Mark Deal Lost** - Mark a deal as lost/closed unsuccessfully
112
+
113
+ ### ✅ Tasks
114
+ - **List Tasks** - Retrieve all tasks with pagination
115
+ - **Get Task** - Get detailed information for a specific task by ID
116
+ - **Create Task** - Create a new task/activity
117
+ - **List Activity Types** - Get available activity types for tasks
118
+
119
+ ### ⚙️ Configuration & Utilities
120
+ - **List Pipelines** - Retrieve all available sales pipelines
121
+ - **Get Current User** - Get information about the authenticated user
122
+ - **Get Current Time** - Get current date/time with timezone awareness
123
+
124
+ ## Usage Examples
125
+
126
+ ### Example 1: List All Contacts
127
+
128
+ Retrieve a paginated list of all contacts in your CRM.
129
+
130
+ **Configuration:**
131
+ - **Operation:** `List Contacts`
132
+ - **Parameters:** Leave empty for all contacts, or add filters
133
+
134
+ **Output:** Array of contact objects with names, emails, phone numbers, and IDs.
135
+
136
+ ```json
137
+ [
138
+ {
139
+ "id": 123,
140
+ "first_name": "John",
141
+ "last_name": "Doe",
142
+ "email": "john.doe@example.com",
143
+ "phone": "+1234567890",
144
+ "company_id": 456
145
+ }
146
+ ]
147
+ ```
148
+
149
+ ---
150
+
151
+ ### Example 2: Create a New Company
152
+
153
+ Add a new company to your Clientify CRM.
154
+
155
+ **Configuration:**
156
+ - **Operation:** `Create Company`
157
+ - **Parameters:**
158
+ - **name** (required): `Acme Corporation`
159
+ - **domain**: `acme.com`
160
+ - **industry**: `Technology`
161
+ - **description**: `Leading software provider`
162
+
163
+ **Output:** Created company object with assigned ID.
164
+
165
+ ```json
166
+ {
167
+ "id": 789,
168
+ "name": "Acme Corporation",
169
+ "domain": "acme.com",
170
+ "industry": "Technology",
171
+ "created_at": "2025-10-01T12:00:00Z"
172
+ }
173
+ ```
174
+
175
+ ---
176
+
177
+ ### Example 3: Update a Deal and Mark as Won
178
+
179
+ Update deal details and mark it as successfully closed.
180
+
181
+ **Workflow:**
182
+ 1. **First Node:** Get the deal you want to update
183
+ - **Operation:** `Get Deal`
184
+ - **deal_id:** `{{$json.deal_id}}`
185
+
186
+ 2. **Second Node:** Update the deal
187
+ - **Operation:** `Update Deal`
188
+ - **deal_id:** `{{$json.id}}`
189
+ - **value:** `50000`
190
+ - **notes:** `Final negotiations completed`
191
+
192
+ 3. **Third Node:** Mark as won
193
+ - **Operation:** `Mark Deal Won`
194
+ - **deal_id:** `{{$json.id}}`
195
+
196
+ ---
197
+
198
+ ### Example 4: Search Companies and Create Contacts
199
+
200
+ Find a company by name and create a new contact associated with it.
201
+
202
+ **Workflow:**
203
+ 1. **Search Companies:**
204
+ - **Operation:** `Search Companies`
205
+ - **query:** `Acme`
206
+
207
+ 2. **Create Contact:**
208
+ - **Operation:** `Create Contact`
209
+ - **first_name:** `Jane`
210
+ - **last_name:** `Smith`
211
+ - **email:** `jane.smith@acme.com`
212
+ - **company_id:** `{{$json.id}}` (from previous node)
213
+
214
+ ---
215
+
216
+ ### Example 5: List All Deals in a Specific Pipeline Stage
217
+
218
+ Retrieve deals that are in the "Negotiation" stage.
219
+
220
+ **Configuration:**
221
+ - **Operation:** `List Deals By Stage`
222
+ - **Parameters:**
223
+ - **stage:** `Negotiation`
224
+
225
+ **Use Case:** Create automated alerts when deals reach certain stages, or generate reports on pipeline health.
226
+
227
+ ---
228
+
229
+ ## Troubleshooting
230
+
231
+ ### Node Doesn't Appear After Installation
232
+
233
+ **Problem:** The Clientify node doesn't show up in the node panel after installing.
234
+
235
+ **Solution:**
236
+ 1. **Restart n8n completely** (required for community nodes)
237
+ 2. Clear your browser cache (Ctrl+Shift+Delete or Cmd+Shift+Delete)
238
+ 3. Search for "Clientify" (not the package name) in the node search
239
+ 4. Verify installation in **Settings → Community Nodes**
240
+
241
+ ### Authentication Errors
242
+
243
+ **Problem:** "Authentication failed" or 401/403 errors.
244
+
245
+ **Solution:**
246
+ 1. Verify your JWT token is valid and not expired
247
+ 2. Check that the token has the correct permissions in Clientify
248
+ 3. Ensure you're using the Clientify MCP token (not a regular API key)
249
+ 4. Try creating a new credential with a fresh token
250
+
251
+ ### "Missing required parameter" Errors
252
+
253
+ **Problem:** Operation fails with missing parameter errors.
254
+
255
+ **Solution:**
256
+ 1. Check which fields are marked as **required** (indicated by red asterisk)
257
+ 2. Some operations require specific IDs (contact_id, company_id, etc.)
258
+ 3. Use `Get` operations first to retrieve IDs, then pass them to `Update` or `Delete` operations
259
+ 4. Review the parameter descriptions for expected format
260
+
261
+ ### Operations Return Empty Results
262
+
263
+ **Problem:** List operations return no results even though data exists.
264
+
265
+ **Solution:**
266
+ 1. Check pagination parameters (page, page_size)
267
+ 2. Verify your token has permission to access the requested resources
268
+ 3. Try without filters first to confirm data access
269
+ 4. Check the Clientify web UI to confirm data exists
270
+
271
+ ### Node Execution Fails in Docker
272
+
273
+ **Problem:** Node fails with "package not found" errors in Docker environments.
274
+
275
+ **Solution:**
276
+ 1. Ensure community nodes directory is persisted in volumes:
277
+ ```yaml
278
+ volumes:
279
+ - n8n_data:/home/node/.n8n
280
+ ```
281
+ 2. Or enable auto-reinstall:
282
+ ```yaml
283
+ environment:
284
+ - N8N_REINSTALL_MISSING_PACKAGES=true
285
+ ```
286
+ 3. Restart the container after installing the node
287
+
288
+ ### Rate Limiting Errors
289
+
290
+ **Problem:** "Too many requests" or 429 errors.
291
+
292
+ **Solution:**
293
+ 1. Add delay between operations using n8n's **Wait** node
294
+ 2. Reduce the frequency of scheduled workflows
295
+ 3. Batch operations where possible
296
+ 4. Contact Clientify support to increase rate limits if needed
297
+
298
+ ## Parameter Reference
299
+
300
+ ### Common Parameters
301
+
302
+ Most operations support these common parameters:
303
+
304
+ - **page** (number): Page number for pagination (default: 1)
305
+ - **page_size** (number): Number of results per page (default: 20, max: 100)
306
+ - **sort_by** (string): Field to sort by (e.g., "created_at", "name")
307
+ - **sort_order** (string): Sort direction ("asc" or "desc")
308
+
309
+ ### ID Parameters
310
+
311
+ Operations that work with specific records require an ID parameter:
312
+
313
+ - **company_id** (number): Unique identifier for a company
314
+ - **contact_id** (number): Unique identifier for a contact
315
+ - **deal_id** (number): Unique identifier for a deal
316
+ - **task_id** (number): Unique identifier for a task
317
+
318
+ ## Advanced Usage
319
+
320
+ ### Combining Multiple Operations
321
+
322
+ Create powerful workflows by chaining operations:
323
+
324
+ ```
325
+ Trigger → Search Companies → Create Contact → Create Deal → Create Task
326
+ ```
327
+
328
+ ### Error Handling
329
+
330
+ Use n8n's built-in error handling:
331
+
332
+ 1. Enable **"Continue On Fail"** in node settings
333
+ 2. Add an **IF** node to check for errors
334
+ 3. Route errors to notification nodes (Email, Slack, etc.)
335
+
336
+ ### Data Transformation
337
+
338
+ Use n8n's **Code** or **Function** nodes to transform data between operations:
339
+
340
+ ```
341
+ List Contacts → Code Node (transform) → External API
342
+ ```
343
+
344
+ ## Development & Contribution
345
+
346
+ This is a community-maintained node. Contributions are welcome!
347
+
348
+ **Repository:** https://github.com/contacteitor/clientify_ai
349
+
350
+ **Report Issues:** https://github.com/contacteitor/clientify_ai/issues
351
+
352
+ **Documentation:** See the `/n8n` directory in the repository
353
+
354
+ ## Support
355
+
356
+ - **Issues & Bugs:** https://github.com/contacteitor/clientify_ai/issues
357
+ - **Email:** sebastianonearth@gmail.com
358
+ - **Clientify Documentation:** https://mcp.clientify.com/docs
359
+
360
+ ## Version History
361
+
362
+ - **v0.1.0** (2025-10-01): Initial release
363
+ - 26 MCP operations supported
364
+ - Dynamic field generation from MCP API
365
+ - Full CRUD operations for contacts, companies, deals, tasks
366
+ - Pipeline and user management
367
+
368
+ ## License
369
+
370
+ MIT License - see [LICENSE](LICENSE) file for details.
371
+
372
+ Copyright (c) 2025 Clientify
373
+
374
+ ---
375
+
376
+ **Made with ❤️ for the n8n community**
377
+
378
+ *This is an unofficial community node. Clientify and n8n are trademarks of their respective owners.*
@@ -0,0 +1,7 @@
1
+ import { ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class ClientifyMcpApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ properties: INodeProperties[];
7
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ClientifyMcpApi = void 0;
4
+ class ClientifyMcpApi {
5
+ constructor() {
6
+ this.name = 'clientifyMcpApi';
7
+ this.displayName = 'Clientify MCP API';
8
+ this.documentationUrl = 'https://mcp.clientify.com/docs';
9
+ this.properties = [
10
+ {
11
+ displayName: 'Authentication Token',
12
+ name: 'authToken',
13
+ type: 'string',
14
+ typeOptions: {
15
+ password: true,
16
+ },
17
+ default: '',
18
+ required: true,
19
+ placeholder: 'Enter your JWT token',
20
+ description: 'The x-end-user-token for authentication with Clientify MCP server',
21
+ },
22
+ ];
23
+ }
24
+ }
25
+ exports.ClientifyMcpApi = ClientifyMcpApi;
@@ -0,0 +1,5 @@
1
+ import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
+ export declare class ClientifyMcpDynamic implements INodeType {
3
+ description: INodeTypeDescription;
4
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
5
+ }
@@ -0,0 +1,211 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ClientifyMcpDynamic = void 0;
4
+ const n8n_workflow_1 = require("n8n-workflow");
5
+ const ClientifyMcpFields_1 = require("./ClientifyMcpFields");
6
+ class ClientifyMcpDynamic {
7
+ constructor() {
8
+ this.description = {
9
+ displayName: 'Clientify',
10
+ name: 'clientifyMcpDynamic',
11
+ icon: 'file:clientify.svg',
12
+ group: ['transform'],
13
+ version: 1,
14
+ subtitle: '={{$parameter["tool"]}}',
15
+ description: 'Connect to Clientify CRM via MCP',
16
+ defaults: {
17
+ name: 'Clientify',
18
+ },
19
+ inputs: ["main" /* NodeConnectionType.Main */],
20
+ outputs: ["main" /* NodeConnectionType.Main */],
21
+ credentials: [
22
+ {
23
+ name: 'clientifyMcpApi',
24
+ required: true,
25
+ },
26
+ ],
27
+ properties: (() => {
28
+ const props = [
29
+ {
30
+ displayName: 'Tool',
31
+ name: 'tool',
32
+ type: 'options',
33
+ options: ClientifyMcpFields_1.toolOptions,
34
+ default: 'listContacts',
35
+ required: true,
36
+ description: 'Select the MCP tool to execute',
37
+ },
38
+ ...ClientifyMcpFields_1.toolFields,
39
+ ];
40
+ // Add additional fields for each tool
41
+ for (const toolOption of ClientifyMcpFields_1.toolOptions) {
42
+ const additionalField = (0, ClientifyMcpFields_1.getAdditionalFieldsForTool)(toolOption.value);
43
+ if (additionalField) {
44
+ props.push(additionalField);
45
+ }
46
+ }
47
+ return props;
48
+ })(),
49
+ };
50
+ }
51
+ async execute() {
52
+ var _a, _b, _c, _d, _e, _f;
53
+ const items = this.getInputData();
54
+ const returnData = [];
55
+ // Get credentials
56
+ const credentials = await this.getCredentials('clientifyMcpApi');
57
+ const authToken = credentials.authToken;
58
+ // MCP Server URL is fixed
59
+ const mcpUrl = 'https://mcp.clientify.com/mcp';
60
+ for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
61
+ try {
62
+ const toolName = this.getNodeParameter('tool', itemIndex);
63
+ // Build tool arguments from individual fields
64
+ const toolArguments = {};
65
+ // Process regular fields
66
+ for (const field of ClientifyMcpFields_1.toolFields) {
67
+ const fieldName = field.name;
68
+ // Check if this field should be shown for the current tool
69
+ if ((_c = (_b = (_a = field.displayOptions) === null || _a === void 0 ? void 0 : _a.show) === null || _b === void 0 ? void 0 : _b.tool) === null || _c === void 0 ? void 0 : _c.includes(toolName)) {
70
+ try {
71
+ const value = this.getNodeParameter(fieldName, itemIndex);
72
+ if (value !== undefined && value !== '' && value !== null) {
73
+ toolArguments[fieldName] = value;
74
+ }
75
+ }
76
+ catch (e) {
77
+ // Field might not exist for this tool
78
+ }
79
+ }
80
+ }
81
+ // Process additional fields
82
+ const additionalFieldsParam = `additionalFields`;
83
+ try {
84
+ const additionalFields = this.getNodeParameter(additionalFieldsParam, itemIndex);
85
+ if (additionalFields && typeof additionalFields === 'object') {
86
+ Object.assign(toolArguments, additionalFields);
87
+ }
88
+ }
89
+ catch (e) {
90
+ // Additional fields might not exist for this tool
91
+ }
92
+ // Step 1: Initialize session
93
+ const initRequest = {
94
+ jsonrpc: '2.0',
95
+ id: 1,
96
+ method: 'initialize',
97
+ params: {
98
+ protocolVersion: '2024-11-05',
99
+ capabilities: {}
100
+ }
101
+ };
102
+ const initOptions = {
103
+ method: 'POST',
104
+ url: mcpUrl,
105
+ headers: {
106
+ 'Content-Type': 'application/json',
107
+ 'x-end-user-token': authToken,
108
+ },
109
+ body: initRequest,
110
+ json: true,
111
+ returnFullResponse: true,
112
+ };
113
+ const initResponse = await this.helpers.httpRequest(initOptions);
114
+ // Extract session ID from headers
115
+ const sessionId = initResponse.headers['mcp-session-id'] || initResponse.headers['Mcp-Session-Id'];
116
+ if (!sessionId) {
117
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Failed to get session ID from MCP server');
118
+ }
119
+ // Step 2: Execute the selected tool
120
+ const requestBody = {
121
+ jsonrpc: '2.0',
122
+ id: 2,
123
+ method: 'tools/call',
124
+ params: {
125
+ name: toolName,
126
+ arguments: toolArguments,
127
+ }
128
+ };
129
+ // Make request with session ID
130
+ const options = {
131
+ method: 'POST',
132
+ url: mcpUrl,
133
+ headers: {
134
+ 'Content-Type': 'application/json',
135
+ 'x-end-user-token': authToken,
136
+ 'Mcp-Session-Id': sessionId,
137
+ },
138
+ body: requestBody,
139
+ json: true,
140
+ };
141
+ const response = await this.helpers.httpRequest(options);
142
+ // Process response
143
+ if (response.error) {
144
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `MCP Error: ${response.error.message || JSON.stringify(response.error)}`);
145
+ }
146
+ // Parse MCP response to make it user-friendly
147
+ let parsedResult = {};
148
+ try {
149
+ // Check if response has the MCP structure with JSON string
150
+ if ((_f = (_e = (_d = response.result) === null || _d === void 0 ? void 0 : _d.content) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.text) {
151
+ // Parse the JSON string from MCP response
152
+ const mcpData = JSON.parse(response.result.content[0].text);
153
+ // Return the parsed data directly - clean and accessible
154
+ parsedResult = mcpData;
155
+ // Add helpful boolean flags for common checks (generic, works for any response)
156
+ if (typeof mcpData === 'object' && mcpData !== null) {
157
+ // If there's a count field, add a boolean for it
158
+ if ('count' in mcpData) {
159
+ parsedResult._hasResults = mcpData.count > 0;
160
+ }
161
+ // If there's a results array, add a boolean for it
162
+ if (Array.isArray(mcpData.results)) {
163
+ parsedResult._hasResults = mcpData.results.length > 0;
164
+ parsedResult._resultCount = mcpData.results.length;
165
+ }
166
+ // If there's a success field, expose it clearly
167
+ if ('success' in mcpData) {
168
+ parsedResult._success = mcpData.success;
169
+ }
170
+ // If there's an error field, expose it clearly
171
+ if ('error' in mcpData) {
172
+ parsedResult._hasError = true;
173
+ parsedResult._error = mcpData.error;
174
+ }
175
+ }
176
+ }
177
+ else {
178
+ // Not an MCP text response - return as is
179
+ parsedResult = response.result || response;
180
+ }
181
+ }
182
+ catch (parseError) {
183
+ // If parsing fails, return original result
184
+ parsedResult = response.result || response;
185
+ }
186
+ // Return formatted result with both parsed and raw data
187
+ returnData.push({
188
+ json: Object.assign(Object.assign({ success: true, tool: toolName, sessionId: sessionId }, parsedResult), {
189
+ // Keep raw response for advanced users
190
+ _raw: response.result || response }),
191
+ pairedItem: itemIndex,
192
+ });
193
+ }
194
+ catch (error) {
195
+ if (this.continueOnFail()) {
196
+ returnData.push({
197
+ json: {
198
+ success: false,
199
+ error: error instanceof Error ? error.message : String(error),
200
+ },
201
+ pairedItem: itemIndex,
202
+ });
203
+ continue;
204
+ }
205
+ throw error;
206
+ }
207
+ }
208
+ return [returnData];
209
+ }
210
+ }
211
+ exports.ClientifyMcpDynamic = ClientifyMcpDynamic;
@@ -0,0 +1,15 @@
1
+ import { INodeProperties } from 'n8n-workflow';
2
+ export declare const toolOptions: ({
3
+ name: string;
4
+ value: string;
5
+ description: string;
6
+ } | {
7
+ name: string;
8
+ value: string;
9
+ description?: undefined;
10
+ })[];
11
+ export declare const toolFields: INodeProperties[];
12
+ export declare const additionalFieldsDefinitions: {
13
+ [key: string]: INodeProperties[];
14
+ };
15
+ export declare function getAdditionalFieldsForTool(toolName: string): INodeProperties | null;