@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 +21 -0
- package/README.md +54 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +311 -0
- package/dist/lib/api.d.ts +72 -0
- package/dist/lib/api.js +112 -0
- package/package.json +49 -0
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
|
package/dist/index.d.ts
ADDED
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;
|
package/dist/lib/api.js
ADDED
|
@@ -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
|
+
}
|