@11x.agency/n8n-cli 1.0.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 Robin Sadeghpour
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,54 @@
1
+ # n8n-agent-cli
2
+
3
+ Lightweight CLI wrapper around the n8n REST API — built for AI agents.
4
+
5
+ Fast, direct REST API calls for workflow management without MCP protocol overhead.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install -g n8n-agent-cli
11
+ ```
12
+
13
+ ## Setup
14
+
15
+ Get your API key from n8n: **Settings > API > Create API Key**
16
+
17
+ ```bash
18
+ export N8N_BASE_URL="https://your-n8n-instance.com"
19
+ export N8N_API_KEY="your-api-key"
20
+ ```
21
+
22
+ Or pass via flags:
23
+ ```bash
24
+ n8n-cli --url "https://..." --api-key "..." workflow list
25
+ ```
26
+
27
+ ## Commands
28
+
29
+ ```bash
30
+ n8n-cli workflow list|get|create|update|delete|activate|deactivate|run
31
+ n8n-cli execution list|get|retry|stop|delete
32
+ n8n-cli variable list|get|set|delete
33
+ n8n-cli tag list|create
34
+ n8n-cli doctor # Check API connectivity
35
+ ```
36
+
37
+ Use `--json` or `--quiet` for machine-readable output.
38
+
39
+ ## Claude Code Plugin
40
+
41
+ Use this CLI with Claude Code via the [11x marketplace plugin](https://github.com/11x-agency/claude-marketplace/tree/main/plugins/n8n-agent-cli):
42
+
43
+ ```
44
+ /plugin marketplace add 11x-agency/claude-marketplace
45
+ /plugin install n8n-agent-cli@11x-marketplace
46
+ ```
47
+
48
+ ## Documentation
49
+
50
+ Full documentation, examples, and contribution guidelines: [github.com/robinsadeghpour/n8n-cli](https://github.com/robinsadeghpour/n8n-cli)
51
+
52
+ ## License
53
+
54
+ MIT
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,311 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { N8nApi, getConfig } from './lib/api.js';
4
+ const program = new Command();
5
+ program
6
+ .name('n8n-cli')
7
+ .description('Lightweight CLI for n8n API - designed for AI agents')
8
+ .option('--url <url>', 'n8n base URL', process.env.N8N_BASE_URL)
9
+ .option('--api-key <key>', 'n8n API key', process.env.N8N_API_KEY)
10
+ .option('--json', 'Output as JSON')
11
+ .option('-q, --quiet', 'Quiet mode - only output data');
12
+ function output(data, options) {
13
+ if (options.json) {
14
+ console.log(JSON.stringify(data, null, 2));
15
+ }
16
+ else if (options.quiet) {
17
+ if (typeof data === 'object' && data !== null) {
18
+ console.log(JSON.stringify(data));
19
+ }
20
+ else {
21
+ console.log(data);
22
+ }
23
+ }
24
+ else {
25
+ console.log(JSON.stringify(data, null, 2));
26
+ }
27
+ }
28
+ function errorExit(msg, code = 1) {
29
+ console.error(msg);
30
+ process.exit(code);
31
+ }
32
+ // Doctor command
33
+ program
34
+ .command('doctor')
35
+ .description('Check API connectivity')
36
+ .action(async () => {
37
+ try {
38
+ const opts = program.opts();
39
+ const baseUrl = opts.url || process.env.N8N_BASE_URL;
40
+ const apiKey = opts.apiKey || process.env.N8N_API_KEY;
41
+ if (!baseUrl || !apiKey) {
42
+ errorExit('Error: N8N_BASE_URL and N8N_API_KEY required');
43
+ }
44
+ const api = new N8nApi({ baseUrl, apiKey });
45
+ const info = await api.ping();
46
+ output({ status: 'ok', version: info.version }, program.opts());
47
+ }
48
+ catch (err) {
49
+ errorExit(`Error: ${err.message}`);
50
+ }
51
+ });
52
+ // Workflow commands
53
+ const workflow = program.command('workflow').description('Workflow management');
54
+ workflow
55
+ .command('list')
56
+ .description('List all workflows')
57
+ .action(async () => {
58
+ try {
59
+ const api = new N8nApi(getConfig());
60
+ const { workflows } = await api.listWorkflows();
61
+ output(workflows, program.opts());
62
+ }
63
+ catch (err) {
64
+ errorExit(`Error: ${err.message}`);
65
+ }
66
+ });
67
+ workflow
68
+ .command('get <id>')
69
+ .description('Get workflow by ID')
70
+ .action(async (id) => {
71
+ try {
72
+ const api = new N8nApi(getConfig());
73
+ const wf = await api.getWorkflow(id);
74
+ output(wf, program.opts());
75
+ }
76
+ catch (err) {
77
+ errorExit(`Error: ${err.message}`);
78
+ }
79
+ });
80
+ workflow
81
+ .command('create <json>')
82
+ .description('Create workflow from JSON')
83
+ .action(async (json) => {
84
+ try {
85
+ const data = JSON.parse(json);
86
+ const api = new N8nApi(getConfig());
87
+ const wf = await api.createWorkflow(data);
88
+ output(wf, program.opts());
89
+ }
90
+ catch (err) {
91
+ errorExit(`Error: ${err.message}`);
92
+ }
93
+ });
94
+ workflow
95
+ .command('update <id> <json>')
96
+ .description('Update workflow')
97
+ .action(async (id, json) => {
98
+ try {
99
+ const data = JSON.parse(json);
100
+ const api = new N8nApi(getConfig());
101
+ const wf = await api.updateWorkflow(id, data);
102
+ output(wf, program.opts());
103
+ }
104
+ catch (err) {
105
+ errorExit(`Error: ${err.message}`);
106
+ }
107
+ });
108
+ workflow
109
+ .command('delete <id>')
110
+ .description('Delete workflow')
111
+ .action(async (id) => {
112
+ try {
113
+ const api = new N8nApi(getConfig());
114
+ await api.deleteWorkflow(id);
115
+ output({ success: true, id }, program.opts());
116
+ }
117
+ catch (err) {
118
+ errorExit(`Error: ${err.message}`);
119
+ }
120
+ });
121
+ workflow
122
+ .command('activate <id>')
123
+ .description('Activate workflow')
124
+ .action(async (id) => {
125
+ try {
126
+ const api = new N8nApi(getConfig());
127
+ await api.activateWorkflow(id);
128
+ output({ success: true, id, active: true }, program.opts());
129
+ }
130
+ catch (err) {
131
+ errorExit(`Error: ${err.message}`);
132
+ }
133
+ });
134
+ workflow
135
+ .command('deactivate <id>')
136
+ .description('Deactivate workflow')
137
+ .action(async (id) => {
138
+ try {
139
+ const api = new N8nApi(getConfig());
140
+ await api.deactivateWorkflow(id);
141
+ output({ success: true, id, active: false }, program.opts());
142
+ }
143
+ catch (err) {
144
+ errorExit(`Error: ${err.message}`);
145
+ }
146
+ });
147
+ workflow
148
+ .command('run <id>')
149
+ .description('Trigger workflow manually')
150
+ .action(async (id) => {
151
+ try {
152
+ const api = new N8nApi(getConfig());
153
+ const result = await api.runWorkflow(id);
154
+ output({ success: true, executionId: result.executionId }, program.opts());
155
+ }
156
+ catch (err) {
157
+ errorExit(`Error: ${err.message}`);
158
+ }
159
+ });
160
+ // Execution commands
161
+ const execution = program.command('execution').description('Execution management');
162
+ execution
163
+ .command('list')
164
+ .description('List executions')
165
+ .option('-l, --limit <number>', 'Limit results', '50')
166
+ .option('-s, --status <status>', 'Filter by status (running, success, error, waiting)')
167
+ .action(async (opts) => {
168
+ try {
169
+ const api = new N8nApi(getConfig());
170
+ const { data } = await api.listExecutions(parseInt(opts.limit), opts.status);
171
+ output(data, program.opts());
172
+ }
173
+ catch (err) {
174
+ errorExit(`Error: ${err.message}`);
175
+ }
176
+ });
177
+ execution
178
+ .command('get <id>')
179
+ .description('Get execution by ID')
180
+ .action(async (id) => {
181
+ try {
182
+ const api = new N8nApi(getConfig());
183
+ const exec = await api.getExecution(id);
184
+ output(exec, program.opts());
185
+ }
186
+ catch (err) {
187
+ errorExit(`Error: ${err.message}`);
188
+ }
189
+ });
190
+ execution
191
+ .command('retry <id>')
192
+ .description('Retry execution')
193
+ .action(async (id) => {
194
+ try {
195
+ const api = new N8nApi(getConfig());
196
+ await api.retryExecution(id);
197
+ output({ success: true, id }, program.opts());
198
+ }
199
+ catch (err) {
200
+ errorExit(`Error: ${err.message}`);
201
+ }
202
+ });
203
+ execution
204
+ .command('stop <id>')
205
+ .description('Stop running execution')
206
+ .action(async (id) => {
207
+ try {
208
+ const api = new N8nApi(getConfig());
209
+ await api.stopExecution(id);
210
+ output({ success: true, id, stopped: true }, program.opts());
211
+ }
212
+ catch (err) {
213
+ errorExit(`Error: ${err.message}`);
214
+ }
215
+ });
216
+ execution
217
+ .command('delete <id>')
218
+ .description('Delete execution')
219
+ .action(async (id) => {
220
+ try {
221
+ const api = new N8nApi(getConfig());
222
+ await api.deleteExecution(id);
223
+ output({ success: true, id }, program.opts());
224
+ }
225
+ catch (err) {
226
+ errorExit(`Error: ${err.message}`);
227
+ }
228
+ });
229
+ // Variable commands
230
+ const variable = program.command('variable').description('Variable management');
231
+ variable
232
+ .command('list')
233
+ .description('List all variables')
234
+ .action(async () => {
235
+ try {
236
+ const api = new N8nApi(getConfig());
237
+ const { variables } = await api.listVariables();
238
+ output(variables, program.opts());
239
+ }
240
+ catch (err) {
241
+ errorExit(`Error: ${err.message}`);
242
+ }
243
+ });
244
+ variable
245
+ .command('get <key>')
246
+ .description('Get variable')
247
+ .action(async (key) => {
248
+ try {
249
+ const api = new N8nApi(getConfig());
250
+ const v = await api.getVariable(key);
251
+ output(v, program.opts());
252
+ }
253
+ catch (err) {
254
+ errorExit(`Error: ${err.message}`);
255
+ }
256
+ });
257
+ variable
258
+ .command('set <key> <value>')
259
+ .description('Set variable')
260
+ .action(async (key, value) => {
261
+ try {
262
+ const api = new N8nApi(getConfig());
263
+ const v = await api.setVariable(key, value);
264
+ output(v, program.opts());
265
+ }
266
+ catch (err) {
267
+ errorExit(`Error: ${err.message}`);
268
+ }
269
+ });
270
+ variable
271
+ .command('delete <key>')
272
+ .description('Delete variable')
273
+ .action(async (key) => {
274
+ try {
275
+ const api = new N8nApi(getConfig());
276
+ await api.deleteVariable(key);
277
+ output({ success: true, key }, program.opts());
278
+ }
279
+ catch (err) {
280
+ errorExit(`Error: ${err.message}`);
281
+ }
282
+ });
283
+ // Tag commands
284
+ const tag = program.command('tag').description('Tag management');
285
+ tag
286
+ .command('list')
287
+ .description('List all tags')
288
+ .action(async () => {
289
+ try {
290
+ const api = new N8nApi(getConfig());
291
+ const { tags } = await api.listTags();
292
+ output(tags, program.opts());
293
+ }
294
+ catch (err) {
295
+ errorExit(`Error: ${err.message}`);
296
+ }
297
+ });
298
+ tag
299
+ .command('create <name>')
300
+ .description('Create tag')
301
+ .action(async (name) => {
302
+ try {
303
+ const api = new N8nApi(getConfig());
304
+ const t = await api.createTag(name);
305
+ output(t, program.opts());
306
+ }
307
+ catch (err) {
308
+ errorExit(`Error: ${err.message}`);
309
+ }
310
+ });
311
+ program.parse();
@@ -0,0 +1,72 @@
1
+ export interface N8nConfig {
2
+ baseUrl: string;
3
+ apiKey: string;
4
+ }
5
+ export interface Workflow {
6
+ id: string;
7
+ name: string;
8
+ active: boolean;
9
+ nodes: any[];
10
+ connections: any;
11
+ settings?: any;
12
+ createdAt: string;
13
+ updatedAt: string;
14
+ }
15
+ export interface Execution {
16
+ id: string;
17
+ workflowId: string;
18
+ mode: string;
19
+ status: string;
20
+ startedAt: string;
21
+ finishedAt?: string;
22
+ data?: any;
23
+ error?: string;
24
+ }
25
+ export interface Variable {
26
+ key: string;
27
+ value: string;
28
+ }
29
+ export interface Tag {
30
+ id: string;
31
+ name: string;
32
+ createdAt: string;
33
+ }
34
+ export declare class N8nApi {
35
+ private baseUrl;
36
+ private apiKey;
37
+ constructor(config: N8nConfig);
38
+ private request;
39
+ listWorkflows(): Promise<{
40
+ workflows: Workflow[];
41
+ }>;
42
+ getWorkflow(id: string): Promise<Workflow>;
43
+ createWorkflow(workflow: Partial<Workflow>): Promise<Workflow>;
44
+ updateWorkflow(id: string, workflow: Partial<Workflow>): Promise<Workflow>;
45
+ deleteWorkflow(id: string): Promise<void>;
46
+ activateWorkflow(id: string): Promise<void>;
47
+ deactivateWorkflow(id: string): Promise<void>;
48
+ runWorkflow(id: string): Promise<{
49
+ executionId: string;
50
+ }>;
51
+ listExecutions(limit?: number, status?: string): Promise<{
52
+ data: Execution[];
53
+ }>;
54
+ getExecution(id: string): Promise<Execution>;
55
+ retryExecution(id: string): Promise<void>;
56
+ stopExecution(id: string): Promise<void>;
57
+ deleteExecution(id: string): Promise<void>;
58
+ listVariables(): Promise<{
59
+ variables: Variable[];
60
+ }>;
61
+ getVariable(key: string): Promise<Variable>;
62
+ setVariable(key: string, value: string): Promise<Variable>;
63
+ deleteVariable(key: string): Promise<void>;
64
+ listTags(): Promise<{
65
+ tags: Tag[];
66
+ }>;
67
+ createTag(name: string): Promise<Tag>;
68
+ ping(): Promise<{
69
+ version: string;
70
+ }>;
71
+ }
72
+ export declare function getConfig(): N8nConfig;
@@ -0,0 +1,112 @@
1
+ export class N8nApi {
2
+ baseUrl;
3
+ apiKey;
4
+ constructor(config) {
5
+ this.baseUrl = config.baseUrl.replace(/\/$/, '');
6
+ this.apiKey = config.apiKey;
7
+ }
8
+ async request(endpoint, options = {}) {
9
+ const url = `${this.baseUrl}${endpoint}`;
10
+ const response = await fetch(url, {
11
+ ...options,
12
+ headers: {
13
+ 'X-N8N-API-KEY': this.apiKey,
14
+ 'Content-Type': 'application/json',
15
+ ...options.headers,
16
+ },
17
+ });
18
+ if (!response.ok) {
19
+ const error = await response.text().catch(() => 'Unknown error');
20
+ throw new Error(`API Error ${response.status}: ${error}`);
21
+ }
22
+ return response.json();
23
+ }
24
+ // Workflows
25
+ async listWorkflows() {
26
+ return this.request('/workflows');
27
+ }
28
+ async getWorkflow(id) {
29
+ return this.request(`/workflows/${id}`);
30
+ }
31
+ async createWorkflow(workflow) {
32
+ return this.request('/workflows', {
33
+ method: 'POST',
34
+ body: JSON.stringify(workflow),
35
+ });
36
+ }
37
+ async updateWorkflow(id, workflow) {
38
+ return this.request(`/workflows/${id}`, {
39
+ method: 'PUT',
40
+ body: JSON.stringify(workflow),
41
+ });
42
+ }
43
+ async deleteWorkflow(id) {
44
+ await this.request(`/workflows/${id}`, { method: 'DELETE' });
45
+ }
46
+ async activateWorkflow(id) {
47
+ await this.request(`/workflows/${id}/activate`, { method: 'POST' });
48
+ }
49
+ async deactivateWorkflow(id) {
50
+ await this.request(`/workflows/${id}/deactivate`, { method: 'POST' });
51
+ }
52
+ async runWorkflow(id) {
53
+ return this.request(`/workflows/${id}/run`, { method: 'POST' });
54
+ }
55
+ // Executions
56
+ async listExecutions(limit = 50, status) {
57
+ let endpoint = `/executions?limit=${limit}`;
58
+ if (status)
59
+ endpoint += `&status=${status}`;
60
+ return this.request(endpoint);
61
+ }
62
+ async getExecution(id) {
63
+ return this.request(`/executions/${id}`);
64
+ }
65
+ async retryExecution(id) {
66
+ await this.request(`/executions/${id}/retry`, { method: 'POST' });
67
+ }
68
+ async stopExecution(id) {
69
+ await this.request(`/executions/${id}/stop`, { method: 'POST' });
70
+ }
71
+ async deleteExecution(id) {
72
+ await this.request(`/executions/${id}`, { method: 'DELETE' });
73
+ }
74
+ // Variables
75
+ async listVariables() {
76
+ return this.request('/variables');
77
+ }
78
+ async getVariable(key) {
79
+ return this.request(`/variables/${key}`);
80
+ }
81
+ async setVariable(key, value) {
82
+ return this.request('/variables', {
83
+ method: 'POST',
84
+ body: JSON.stringify({ key, value }),
85
+ });
86
+ }
87
+ async deleteVariable(key) {
88
+ await this.request(`/variables/${key}`, { method: 'DELETE' });
89
+ }
90
+ // Tags
91
+ async listTags() {
92
+ return this.request('/tags');
93
+ }
94
+ async createTag(name) {
95
+ return this.request('/tags', {
96
+ method: 'POST',
97
+ body: JSON.stringify({ name }),
98
+ });
99
+ }
100
+ // Health
101
+ async ping() {
102
+ return this.request('/');
103
+ }
104
+ }
105
+ export function getConfig() {
106
+ const baseUrl = process.env.N8N_BASE_URL || process.env.N8N_URL;
107
+ const apiKey = process.env.N8N_API_KEY;
108
+ if (!baseUrl || !apiKey) {
109
+ throw new Error('Missing N8N_BASE_URL or N8N_API_KEY');
110
+ }
111
+ return { baseUrl, apiKey };
112
+ }
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@11x.agency/n8n-cli",
3
+ "version": "1.0.0",
4
+ "description": "Lightweight CLI for n8n API - designed for AI agents",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "n8n-cli": "dist/index.js",
9
+ "n8n-agent-cli": "dist/index.js"
10
+ },
11
+ "files": [
12
+ "dist/**/*"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "start": "node dist/index.js",
17
+ "dev": "tsx src/index.ts",
18
+ "prepublishOnly": "npm run build"
19
+ },
20
+ "keywords": [
21
+ "n8n",
22
+ "cli",
23
+ "automation",
24
+ "ai",
25
+ "workflow",
26
+ "n8n-api"
27
+ ],
28
+ "license": "MIT",
29
+ "author": "Robin Sadeghpour",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/robinsadeghpour/n8n-cli.git"
33
+ },
34
+ "homepage": "https://github.com/robinsadeghpour/n8n-cli#readme",
35
+ "bugs": {
36
+ "url": "https://github.com/robinsadeghpour/n8n-cli/issues"
37
+ },
38
+ "engines": {
39
+ "node": ">=18.0.0"
40
+ },
41
+ "dependencies": {
42
+ "commander": "^12.1.0"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^20.11.0",
46
+ "tsx": "^4.7.0",
47
+ "typescript": "^5.3.3"
48
+ }
49
+ }