@path58/p58-n8n 0.2.2 → 0.2.4
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/AGENT_INSTALL.md +150 -138
- package/CHANGELOG.md +39 -5
- package/README.md +22 -9
- package/dist/mcp/server.bundle.cjs +403 -40
- package/package.json +3 -2
package/AGENT_INSTALL.md
CHANGED
|
@@ -1,124 +1,127 @@
|
|
|
1
|
-
#
|
|
1
|
+
# p58-n8n — LLM Agent Installation Guide
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> **🤖 ACTION REQUIRED:** You are reading this because a user wants you to install the **p58-n8n** MCP server. Follow the steps below in order. You have everything you need in this file — do NOT search the web for additional instructions. If the user dropped a repo URL or README, this is the authoritative installation guide.
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
> **Your job:** Detect the user's MCP client → find their n8n instance (if any) → write the config → restart → verify. Minimize questions to the user — auto-discover what you can, only ask when you must (API key, n8n URL if not found).
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
## What
|
|
9
|
+
## What is p58-n8n?
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
p58-n8n is an MCP server that gives LLMs the ability to validate, build, deploy, and manage n8n workflows. It provides 35 tools organized in tiers:
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
| `validate_workflow` | Run L1-L6 validation on workflow JSON |
|
|
16
|
-
| `get_operation_schema` | Get exact parameter requirements for any operation |
|
|
17
|
-
| `check_parameter` | Validate a parameter value with typo detection |
|
|
18
|
-
| `suggest_fix` | Get fix suggestions for validation issues |
|
|
19
|
-
| `list_nodes` | Browse and search 1,982 n8n nodes |
|
|
20
|
-
| `list_operations` | List all operations for a node type |
|
|
21
|
-
| `get_node_info` | Get comprehensive node metadata |
|
|
22
|
-
| `find_similar_pattern` | Search 9,000+ validated workflows |
|
|
13
|
+
- **Tier 1 (offline):** `validate_workflow`, `list_nodes`, `get_operation_schema`, `suggest_fix`, `check_parameter` — work immediately, no env vars needed
|
|
14
|
+
- **Tier 2-7 (require n8n):** `build_workflow`, `list_credentials`, `activate_workflow`, `execute_workflow`, `test_workflow`, `plan_workflow`, etc. — require connection to user's n8n instance
|
|
23
15
|
|
|
24
|
-
|
|
16
|
+
---
|
|
25
17
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
18
|
+
## Installation Decision Tree
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
Does the user have n8n running?
|
|
22
|
+
├── YES → Full install (N8N_API_URL + N8N_API_KEY)
|
|
23
|
+
│ All 34 tools work: validate, build, deploy, execute
|
|
24
|
+
│
|
|
25
|
+
└── NO / DON'T KNOW → Minimal install (no env vars)
|
|
26
|
+
Tier 1 tools only: validate, list, check params
|
|
27
|
+
User can add n8n config later
|
|
28
|
+
```
|
|
32
29
|
|
|
33
30
|
---
|
|
34
31
|
|
|
35
|
-
##
|
|
32
|
+
## Step 1: Detect the MCP Client
|
|
36
33
|
|
|
37
|
-
|
|
34
|
+
Determine which AI client the user is using. Check for config files in this order:
|
|
38
35
|
|
|
39
|
-
|
|
36
|
+
| Client | Config File Path | OS |
|
|
37
|
+
|--------|-----------------|-----|
|
|
38
|
+
| **Claude Desktop** | `~/Library/Application Support/Claude/claude_desktop_config.json` | macOS |
|
|
39
|
+
| **Claude Desktop** | `%APPDATA%\Claude\claude_desktop_config.json` | Windows |
|
|
40
|
+
| **Claude Desktop** | `~/.config/Claude/claude_desktop_config.json` | Linux |
|
|
41
|
+
| **Claude Code** | Use `claude mcp add` CLI command | All |
|
|
42
|
+
| **Cursor** | `~/.cursor/mcp.json` | All |
|
|
43
|
+
| **Gemini CLI** | `~/.gemini/settings.json` or `~/.gemini/antigravity/mcp_config.json` | All |
|
|
44
|
+
| **VS Code (Copilot)** | `.vscode/mcp.json` in workspace | All |
|
|
40
45
|
|
|
41
|
-
**
|
|
42
|
-
```
|
|
43
|
-
Can I run shell commands?
|
|
44
|
-
├─ YES (Claude Code, Cowork mode, Gemini CLI) → Go to STEP 2a (Auto-Install)
|
|
45
|
-
└─ NO (Claude Desktop Chat-only) → Go to STEP 2b (Guided Install)
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
**Detect platform:**
|
|
49
|
-
```
|
|
50
|
-
What OS is the user on?
|
|
51
|
-
├─ macOS → Config paths use ~/Library/Application Support/
|
|
52
|
-
├─ Windows → Config paths use %APPDATA%\
|
|
53
|
-
└─ Linux → Config paths use ~/.config/
|
|
54
|
-
```
|
|
46
|
+
**Detection method:** Check if these files exist. If multiple exist, ask the user which client they want to configure.
|
|
55
47
|
|
|
56
48
|
---
|
|
57
49
|
|
|
58
|
-
|
|
50
|
+
## Step 2: Find the User's n8n Instance
|
|
59
51
|
|
|
60
|
-
|
|
52
|
+
Try these methods in order:
|
|
61
53
|
|
|
54
|
+
### Method A: Check environment variables
|
|
62
55
|
```bash
|
|
63
|
-
|
|
64
|
-
|
|
56
|
+
echo $N8N_API_URL
|
|
57
|
+
echo $N8N_API_BASE_URL
|
|
58
|
+
echo $N8N_HOST
|
|
65
59
|
```
|
|
66
60
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
61
|
+
### Method B: Probe common localhost ports
|
|
62
|
+
```bash
|
|
63
|
+
# Standard n8n port
|
|
64
|
+
curl -s -o /dev/null -w "%{http_code}" http://localhost:5678/api/v1/workflows 2>/dev/null
|
|
65
|
+
# Returns 401 = n8n is running (auth required) ✅
|
|
66
|
+
# Returns 000 = n8n is not running at this address ❌
|
|
67
|
+
```
|
|
70
68
|
|
|
71
|
-
|
|
69
|
+
### Method C: Check Docker containers
|
|
70
|
+
```bash
|
|
71
|
+
docker ps --filter "name=n8n" --format "{{.Ports}}" 2>/dev/null
|
|
72
|
+
# Example output: 0.0.0.0:5678->5678/tcp → n8n at localhost:5678
|
|
73
|
+
```
|
|
72
74
|
|
|
75
|
+
### Method D: Check running processes
|
|
73
76
|
```bash
|
|
74
|
-
|
|
77
|
+
ps aux | grep -i n8n | grep -v grep
|
|
75
78
|
```
|
|
76
79
|
|
|
77
|
-
|
|
80
|
+
### Method E: Ask the user
|
|
81
|
+
If none of the above work, ask: "What is the URL of your n8n instance? (e.g., http://localhost:5678 or https://n8n.example.com)"
|
|
78
82
|
|
|
79
|
-
|
|
83
|
+
**IMPORTANT:** The API URL must include the `/api/v1` suffix. Example: `http://localhost:5678/api/v1`
|
|
80
84
|
|
|
81
|
-
|
|
85
|
+
---
|
|
82
86
|
|
|
83
|
-
|
|
84
|
-
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
85
|
-
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
86
|
-
- Linux: `~/.config/Claude/claude_desktop_config.json`
|
|
87
|
+
## Step 3: Get the n8n API Key
|
|
87
88
|
|
|
88
|
-
|
|
89
|
+
The API key cannot be auto-discovered. The user must provide it or create one.
|
|
89
90
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
91
|
+
**Instructions to give the user:**
|
|
92
|
+
1. Open n8n in your browser (the URL from Step 2, without `/api/v1`)
|
|
93
|
+
2. Go to **Settings → API Keys** (or **Settings → n8n API**)
|
|
94
|
+
3. Click **Create an API key**
|
|
95
|
+
4. Copy the key — it starts with `eyJ...` (JWT format)
|
|
96
|
+
5. Share it with me so I can add it to your config
|
|
97
|
+
|
|
98
|
+
**If the user can't find API Keys in Settings:** They may be on n8n Community Edition < 0.225.0 or n8n Cloud with API disabled. API key management requires admin access.
|
|
99
|
+
|
|
100
|
+
---
|
|
96
101
|
|
|
97
|
-
|
|
102
|
+
## Step 4: Write the Configuration
|
|
98
103
|
|
|
104
|
+
### For Claude Desktop / Cursor / Gemini CLI / VS Code (JSON config)
|
|
105
|
+
|
|
106
|
+
Read the existing config file, then add p58-n8n inside the `mcpServers` object. Do NOT overwrite existing MCP servers.
|
|
107
|
+
|
|
108
|
+
**Full config (with n8n):**
|
|
99
109
|
```json
|
|
100
110
|
{
|
|
101
111
|
"mcpServers": {
|
|
102
112
|
"p58-n8n": {
|
|
103
113
|
"command": "npx",
|
|
104
|
-
"args": ["-y", "@path58/p58-n8n"]
|
|
114
|
+
"args": ["-y", "@path58/p58-n8n"],
|
|
115
|
+
"env": {
|
|
116
|
+
"N8N_API_URL": "http://localhost:5678/api/v1",
|
|
117
|
+
"N8N_API_KEY": "<paste-api-key-here>"
|
|
118
|
+
}
|
|
105
119
|
}
|
|
106
120
|
}
|
|
107
121
|
}
|
|
108
122
|
```
|
|
109
123
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
#### Gemini CLI
|
|
113
|
-
|
|
114
|
-
There is NO `gemini mcp add` command. Edit the config file directly.
|
|
115
|
-
|
|
116
|
-
**Config path:** `~/.gemini/settings.json` (user-level) or `.gemini/settings.json` (project-level)
|
|
117
|
-
|
|
118
|
-
**If file exists:** Read it, parse JSON, add the `p58-n8n` entry inside `mcpServers`.
|
|
119
|
-
|
|
120
|
-
**If file doesn't exist:** Create it with:
|
|
121
|
-
|
|
124
|
+
**Minimal config (validation only, no n8n needed):**
|
|
122
125
|
```json
|
|
123
126
|
{
|
|
124
127
|
"mcpServers": {
|
|
@@ -130,94 +133,103 @@ There is NO `gemini mcp add` command. Edit the config file directly.
|
|
|
130
133
|
}
|
|
131
134
|
```
|
|
132
135
|
|
|
133
|
-
|
|
136
|
+
### For Claude Code (CLI)
|
|
134
137
|
|
|
135
|
-
|
|
138
|
+
**Full config:**
|
|
139
|
+
```bash
|
|
140
|
+
claude mcp add p58-n8n \
|
|
141
|
+
-e N8N_API_URL=http://localhost:5678/api/v1 \
|
|
142
|
+
-e N8N_API_KEY=<paste-api-key-here> \
|
|
143
|
+
-- npx -y @path58/p58-n8n
|
|
144
|
+
```
|
|
136
145
|
|
|
137
|
-
|
|
146
|
+
**Minimal config:**
|
|
147
|
+
```bash
|
|
148
|
+
claude mcp add p58-n8n -- npx -y @path58/p58-n8n
|
|
149
|
+
```
|
|
138
150
|
|
|
139
|
-
|
|
151
|
+
---
|
|
140
152
|
|
|
141
|
-
|
|
153
|
+
## Step 5: Restart the Client
|
|
142
154
|
|
|
143
|
-
|
|
155
|
+
The MCP server config is only read at startup. After writing the config:
|
|
144
156
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
157
|
+
| Client | Restart Method |
|
|
158
|
+
|--------|---------------|
|
|
159
|
+
| **Claude Desktop** | Quit completely (Cmd+Q on macOS), then reopen |
|
|
160
|
+
| **Claude Code** | Exit and restart the CLI session |
|
|
161
|
+
| **Cursor** | Restart Cursor (Cmd+Shift+P → Reload Window) |
|
|
162
|
+
| **Gemini CLI** | Exit and restart the CLI session, or use the MCP refresh command |
|
|
149
163
|
|
|
150
|
-
|
|
164
|
+
**CRITICAL:** On macOS, closing the window is NOT enough for Claude Desktop. The user must Cmd+Q to fully quit.
|
|
151
165
|
|
|
152
|
-
|
|
153
|
-
{
|
|
154
|
-
"mcpServers": {
|
|
155
|
-
"p58-n8n": {
|
|
156
|
-
"command": "npx",
|
|
157
|
-
"args": ["-y", "@path58/p58-n8n"]
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
```
|
|
166
|
+
---
|
|
162
167
|
|
|
163
|
-
|
|
168
|
+
## Step 6: Verify Installation
|
|
164
169
|
|
|
165
|
-
|
|
170
|
+
After restart, run these verification steps:
|
|
166
171
|
|
|
167
|
-
|
|
172
|
+
### Check 1: Tool availability
|
|
173
|
+
Ask: "List n8n nodes for sending email"
|
|
174
|
+
- **Expected:** The LLM calls `list_nodes` and returns results
|
|
175
|
+
- **If tools not visible:** Config file has syntax error or wrong path
|
|
168
176
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
177
|
+
### Check 2: n8n connectivity (if configured)
|
|
178
|
+
Ask: "Check n8n server health"
|
|
179
|
+
- **Expected:** `connected: true` with server version
|
|
180
|
+
- **If `connected: false`:** Check N8N_API_URL — is n8n actually running at that address?
|
|
181
|
+
- **If `Authentication failed`:** Check N8N_API_KEY — is it valid?
|
|
172
182
|
|
|
173
|
-
|
|
183
|
+
### Check 3: Full pipeline (if n8n connected)
|
|
184
|
+
Ask: "List my n8n credentials"
|
|
185
|
+
- **Expected:** Returns list of configured credentials
|
|
186
|
+
- **If error:** API key may be expired or n8n needs restart
|
|
174
187
|
|
|
175
|
-
|
|
188
|
+
---
|
|
176
189
|
|
|
177
|
-
|
|
178
|
-
2. Add:
|
|
190
|
+
## Environment Variables Reference
|
|
179
191
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
"command": "npx",
|
|
185
|
-
"args": ["-y", "@path58/p58-n8n"]
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
```
|
|
192
|
+
| Variable | Required? | Description | How to find |
|
|
193
|
+
|----------|-----------|-------------|-------------|
|
|
194
|
+
| `N8N_API_URL` | For Tier 2-7 tools | n8n instance API URL | See Step 2 above |
|
|
195
|
+
| `N8N_API_KEY` | For Tier 2-7 tools | n8n API authentication key | n8n → Settings → API Keys |
|
|
190
196
|
|
|
191
|
-
|
|
197
|
+
> **Note:** `N8N_API_BASE_URL` is accepted as a fallback for `N8N_API_URL`. If neither is set, defaults to `http://localhost:5678/api/v1`.
|
|
192
198
|
|
|
193
|
-
|
|
199
|
+
### Variables NOT needed for standard installation
|
|
200
|
+
|
|
201
|
+
| Variable | Purpose | Who needs it |
|
|
202
|
+
|----------|---------|-------------|
|
|
203
|
+
| `P58_DATABASE_URL` | Extended catalog enrichment | Path58 internal / advanced users only |
|
|
204
|
+
| `NODE_ENV` | Logger behavior | Not needed (server handles this) |
|
|
205
|
+
| `NO_COLOR` | Disable ANSI colors | Not needed (server strips automatically since v0.2.2) |
|
|
194
206
|
|
|
195
207
|
---
|
|
196
208
|
|
|
197
|
-
|
|
209
|
+
## Troubleshooting
|
|
198
210
|
|
|
199
|
-
|
|
211
|
+
| Symptom | Cause | Fix |
|
|
212
|
+
|---------|-------|-----|
|
|
213
|
+
| Tools not appearing | Config syntax error | Validate JSON (check trailing commas, unclosed braces) |
|
|
214
|
+
| Tools not appearing | Wrong config file path | Verify OS-specific path from Step 1 |
|
|
215
|
+
| "npx: command not found" | Node.js not installed | Install from https://nodejs.org/ |
|
|
216
|
+
| "Authentication failed" on deploy tools | N8N_API_KEY missing or invalid | Add API key to config, restart client |
|
|
217
|
+
| "Connection refused" on server_health | n8n not running at configured URL | Start n8n or fix N8N_API_URL |
|
|
218
|
+
| All tools timeout | Firewall blocking localhost | Check firewall / VPN settings |
|
|
219
|
+
| Server shows "failed" status | ANSI color issue (pre-v0.2.2) | Update to latest version: `npx -y @path58/p58-n8n@latest` |
|
|
200
220
|
|
|
201
|
-
|
|
221
|
+
---
|
|
202
222
|
|
|
203
|
-
|
|
223
|
+
## Post-Install: What the User Can Do
|
|
204
224
|
|
|
205
|
-
|
|
225
|
+
Once installed, the user can ask their AI assistant to:
|
|
206
226
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
├─ npx not found → Install Node.js 18+ from https://nodejs.org/
|
|
213
|
-
└─ Permission error → Try: sudo npm install -g @path58/p58-n8n
|
|
214
|
-
|
|
215
|
-
Server starts but tools don't work?
|
|
216
|
-
├─ Database not accessible → Server needs network access to Supabase
|
|
217
|
-
├─ Timeout errors → Check internet connection
|
|
218
|
-
└─ "Module not found" → Run: npm install -g @path58/p58-n8n (reinstall)
|
|
219
|
-
```
|
|
227
|
+
- **"Validate this n8n workflow JSON"** — Tier 1, works immediately
|
|
228
|
+
- **"What parameters does the Slack node need?"** — Tier 1, works immediately
|
|
229
|
+
- **"Build me a workflow that sends Slack when Gmail receives an email"** — Tier 2+, needs n8n
|
|
230
|
+
- **"List my n8n credentials"** — Tier 2+, needs n8n
|
|
231
|
+
- **"Deploy and test this workflow"** — Tier 2+, needs n8n
|
|
220
232
|
|
|
221
233
|
---
|
|
222
234
|
|
|
223
|
-
**Package:** `@path58/p58-n8n` | **
|
|
235
|
+
**Package:** `@path58/p58-n8n` | **npm:** https://www.npmjs.com/package/@path58/p58-n8n | **Version:** 0.2.4+
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,38 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.2.4] - 2026-03-10
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Lazy initialization** — MCP server defers tool registration and fixer registry loading until after stdio handshake completes; eliminates cold-start timeouts on strict-timeout clients (Gemini CLI / Antigravity)
|
|
13
|
+
- **`setup_check` tool** — new Tier 7 diagnostic tool that validates server health, n8n connectivity, and database access in a single call; total tools now **35** across 7 tiers
|
|
14
|
+
- **Gemini CLI support** — installation guide and documentation updated with Gemini CLI / Antigravity configuration examples
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Documentation overhauled for v0.2.4: replaced Windsurf references with Gemini CLI throughout AGENT_INSTALL.md, README.md, and FRIEND_ONBOARDING.md
|
|
19
|
+
- Fixed broken `docs/INSTALLATION.md` links in README (file never existed) — now point to AGENT_INSTALL.md
|
|
20
|
+
- Standardized `N8N_API_URL` environment variable naming across all documentation
|
|
21
|
+
- Updated catalog counts in documentation: 1,545 nodes, 679 credentials, 35 tools
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- Server initialization no longer blocks the MCP handshake — clients with < 5s timeouts can now connect reliably
|
|
26
|
+
- Startup version banner now correctly reports v0.2.4
|
|
27
|
+
- **Friend & family UX hardening** — 5 catalog tool handlers now return `CATALOG_UNREACHABLE` or `DB_NOT_CONFIGURED` with setup guide URLs instead of opaque "internal error" when database issues occur
|
|
28
|
+
- DB pool auto-sizes for catalog-only users (max 3 connections, no keepAlive) — prevents resource exhaustion for friends without n8n
|
|
29
|
+
- Startup health check confirms database connectivity before accepting tool calls
|
|
30
|
+
- Shutdown race condition eliminated — in-flight request tracker waits up to 5s for active queries before pool disposal
|
|
31
|
+
- `makeDbNotConfiguredResponse` now includes `isError: true` flag so LLMs recognize the error
|
|
32
|
+
- `plan_workflow` description updated to note that `build_workflow` requires n8n API access
|
|
33
|
+
|
|
34
|
+
## [0.2.3] - 2026-03-09
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- Internal release — build and bundle pipeline fixes
|
|
39
|
+
|
|
8
40
|
## [0.2.2] - 2026-03-09
|
|
9
41
|
|
|
10
42
|
### Fixed
|
|
@@ -98,8 +130,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
98
130
|
- npm package published as `@path58/p58-n8n`
|
|
99
131
|
- ESM module support with shebang for direct `npx` execution
|
|
100
132
|
|
|
101
|
-
[0.2.
|
|
102
|
-
[0.2.
|
|
103
|
-
[0.2.
|
|
104
|
-
[0.
|
|
105
|
-
[0.
|
|
133
|
+
[0.2.4]: https://github.com/tsvika58/p58-n8n/releases/tag/v0.2.4
|
|
134
|
+
[0.2.3]: https://github.com/tsvika58/p58-n8n/releases/tag/v0.2.3
|
|
135
|
+
[0.2.2]: https://github.com/tsvika58/p58-n8n/releases/tag/v0.2.2
|
|
136
|
+
[0.2.1]: https://github.com/tsvika58/p58-n8n/releases/tag/v0.2.1
|
|
137
|
+
[0.2.0]: https://github.com/tsvika58/p58-n8n/releases/tag/v0.2.0
|
|
138
|
+
[0.1.1]: https://github.com/tsvika58/p58-n8n/releases/tag/v0.1.1
|
|
139
|
+
[0.1.0]: https://github.com/tsvika58/p58-n8n/releases/tag/v0.1.0
|
package/README.md
CHANGED
|
@@ -4,10 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@path58/p58-n8n)
|
|
6
6
|
[](LICENSE)
|
|
7
|
-
[](https://github.com/tsvika58/p58-n8n/actions/workflows/ci.yml)
|
|
8
8
|
|
|
9
9
|
p58-n8n is an MCP server that gives your AI assistant deep knowledge of n8n — **1,545 nodes**, **12,619 operations**, **38,005 parameter rules** — so it can plan, build, validate, fix, and deploy workflows correctly. No manual iteration. No broken JSON.
|
|
10
10
|
|
|
11
|
+
> **🤖 AI Agent?** If you are an LLM assistant and a user asked you to install this MCP server, **stop here and read [`AGENT_INSTALL.md`](https://github.com/tsvika58/p58-n8n/blob/main/AGENT_INSTALL.md)** — it has the complete autonomous installation guide with client detection, n8n auto-discovery, config templates for all clients, and verification steps. Everything you need to install p58-n8n without asking the user unnecessary questions.
|
|
12
|
+
|
|
11
13
|
---
|
|
12
14
|
|
|
13
15
|
## Quick Start (< 2 minutes)
|
|
@@ -28,7 +30,10 @@ npm install -g @path58/p58-n8n
|
|
|
28
30
|
|
|
29
31
|
**Claude Code** (one command):
|
|
30
32
|
```bash
|
|
31
|
-
claude mcp add p58-n8n
|
|
33
|
+
claude mcp add p58-n8n \
|
|
34
|
+
-e N8N_API_URL=http://localhost:5678/api/v1 \
|
|
35
|
+
-e N8N_API_KEY=your-n8n-api-key \
|
|
36
|
+
-- npx -y @path58/p58-n8n
|
|
32
37
|
```
|
|
33
38
|
|
|
34
39
|
**Claude Desktop** — add to `claude_desktop_config.json`:
|
|
@@ -39,16 +44,23 @@ claude mcp add p58-n8n -- npx -y @path58/p58-n8n
|
|
|
39
44
|
"command": "npx",
|
|
40
45
|
"args": ["-y", "@path58/p58-n8n"],
|
|
41
46
|
"env": {
|
|
42
|
-
"
|
|
47
|
+
"N8N_API_URL": "http://localhost:5678/api/v1",
|
|
48
|
+
"N8N_API_KEY": "your-n8n-api-key"
|
|
43
49
|
}
|
|
44
50
|
}
|
|
45
51
|
}
|
|
46
52
|
}
|
|
47
53
|
```
|
|
48
54
|
|
|
55
|
+
Get your API key from **n8n → Settings → API Keys**.
|
|
56
|
+
|
|
49
57
|
Config file location: `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows). Restart Claude Desktop after saving.
|
|
50
58
|
|
|
51
|
-
**
|
|
59
|
+
> **Note:** Validation tools (`validate_workflow`, `list_nodes`, etc.) work immediately without any env vars. The `N8N_API_URL` and `N8N_API_KEY` are only needed for deploy, execute, and credential tools.
|
|
60
|
+
|
|
61
|
+
**Cursor / Gemini CLI** — same JSON format, add to your client's MCP config file. See [AGENT_INSTALL.md](https://github.com/tsvika58/p58-n8n/blob/main/AGENT_INSTALL.md) for all supported clients.
|
|
62
|
+
|
|
63
|
+
**LLM-assisted setup** — if you're an AI agent helping a user install p58-n8n, read [AGENT_INSTALL.md](https://github.com/tsvika58/p58-n8n/blob/main/AGENT_INSTALL.md) for the autonomous installation guide.
|
|
52
64
|
|
|
53
65
|
### 3. Try it
|
|
54
66
|
|
|
@@ -114,7 +126,7 @@ p58-n8n uses 80% less token context than n8n-mcp by serving structured catalog d
|
|
|
114
126
|
|
|
115
127
|
---
|
|
116
128
|
|
|
117
|
-
##
|
|
129
|
+
## 35 Tools in 7 Tiers
|
|
118
130
|
|
|
119
131
|
### Tier 1 — Validation & Analysis
|
|
120
132
|
|
|
@@ -184,6 +196,7 @@ p58-n8n uses 80% less token context than n8n-mcp by serving structured catalog d
|
|
|
184
196
|
| Tool | What it does |
|
|
185
197
|
|------|-------------|
|
|
186
198
|
| `collect_config` | Detect missing node configuration from your live n8n instance (covers 2,494 known gaps) |
|
|
199
|
+
| `setup_check` | Diagnostic report — server version, n8n connectivity, credential count, tool availability |
|
|
187
200
|
|
|
188
201
|
Full reference with input/output schemas: [docs/TOOLS.md](docs/TOOLS.md)
|
|
189
202
|
|
|
@@ -223,11 +236,11 @@ p58-n8n will: call `get_credential_schema` for Slack → `create_credential` wit
|
|
|
223
236
|
|
|
224
237
|
## Installation
|
|
225
238
|
|
|
226
|
-
See [
|
|
239
|
+
See [AGENT_INSTALL.md](https://github.com/tsvika58/p58-n8n/blob/main/AGENT_INSTALL.md) for full setup instructions:
|
|
227
240
|
|
|
228
241
|
- Claude Desktop (macOS, Windows, Linux)
|
|
229
242
|
- Claude Code (one-command setup)
|
|
230
|
-
- Cursor and
|
|
243
|
+
- Cursor and Gemini CLI
|
|
231
244
|
- Global install vs npx
|
|
232
245
|
- Troubleshooting
|
|
233
246
|
|
|
@@ -262,7 +275,7 @@ MIT — see [LICENSE](LICENSE) for details.
|
|
|
262
275
|
|
|
263
276
|
p58-n8n is in **soft launch** (friends & family). Issues and feedback welcome:
|
|
264
277
|
|
|
265
|
-
- **Bugs:** [GitHub Issues](https://github.com/tsvika58/n8n
|
|
278
|
+
- **Bugs:** [GitHub Issues](https://github.com/tsvika58/p58-n8n/issues)
|
|
266
279
|
- **Email:** tvagman@gmail.com
|
|
267
280
|
|
|
268
281
|
---
|
|
@@ -272,7 +285,7 @@ p58-n8n is in **soft launch** (friends & family). Issues and feedback welcome:
|
|
|
272
285
|
p58-n8n runs as a local stdio MCP server. No cloud services required for basic use.
|
|
273
286
|
|
|
274
287
|
```
|
|
275
|
-
AI Client (Claude / Cursor /
|
|
288
|
+
AI Client (Claude / Cursor / Gemini CLI)
|
|
276
289
|
↕ MCP Protocol (stdio)
|
|
277
290
|
p58-n8n Server
|
|
278
291
|
├── Validation Engine (L1-L6, ~1.4s)
|
|
@@ -52,6 +52,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
52
52
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
53
53
|
mod
|
|
54
54
|
));
|
|
55
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
55
56
|
|
|
56
57
|
// node_modules/consola/dist/core.cjs
|
|
57
58
|
var require_core = __commonJS({
|
|
@@ -3013,22 +3014,28 @@ function buildPoolOptions() {
|
|
|
3013
3014
|
}
|
|
3014
3015
|
function createPool(cfg) {
|
|
3015
3016
|
const timeoutMs = getEnvNumber("DB_STATEMENT_TIMEOUT_MS", 3e4);
|
|
3017
|
+
const isCatalogOnly = !!(process.env.P58_DATABASE_URL || process.env.MCP_DATABASE_URL) && !process.env.N8N_API_KEY;
|
|
3016
3018
|
const pool = new import_pg.Pool({
|
|
3017
3019
|
host: cfg.host,
|
|
3018
3020
|
port: resolvePoolPort(cfg),
|
|
3019
3021
|
user: cfg.user,
|
|
3020
3022
|
password: cfg.password,
|
|
3021
3023
|
database: cfg.database,
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
+
// Friends: 3 max (1 active + 2 burst). Full mode: 10.
|
|
3025
|
+
max: getEnvNumber("VALIDATOR_DB_POOL_MAX", isCatalogOnly ? 3 : 10),
|
|
3026
|
+
// Friends: 0 min — don't hold connections when idle. Full mode: 1.
|
|
3027
|
+
min: getEnvNumber("VALIDATOR_DB_POOL_MIN", isCatalogOnly ? 0 : 1),
|
|
3024
3028
|
// allowExitOnIdle: true — prevents zombie processes when MCP session ends (RAG-4.35.5)
|
|
3025
|
-
|
|
3026
|
-
|
|
3029
|
+
// Friends: 30s idle (release fast). Full mode: 60s.
|
|
3030
|
+
idleTimeoutMillis: isCatalogOnly ? 3e4 : 6e4,
|
|
3031
|
+
// Friends: 10s connect timeout (fail fast). Full mode: 15s.
|
|
3032
|
+
connectionTimeoutMillis: isCatalogOnly ? 1e4 : 15e3,
|
|
3027
3033
|
statement_timeout: timeoutMs,
|
|
3028
3034
|
options: buildPoolOptions(),
|
|
3029
3035
|
allowExitOnIdle: true,
|
|
3030
|
-
keepAlive:
|
|
3031
|
-
|
|
3036
|
+
// Friends: no keepAlive (let connections close naturally). Full mode: keepAlive.
|
|
3037
|
+
keepAlive: !isCatalogOnly,
|
|
3038
|
+
...isCatalogOnly ? {} : { keepAliveInitialDelayMillis: 1e4 }
|
|
3032
3039
|
});
|
|
3033
3040
|
pool.on("error", (err) => {
|
|
3034
3041
|
console.warn(`[pg-pool] Idle connection error (non-fatal): ${err.message}`);
|
|
@@ -3040,6 +3047,24 @@ function getValidatorPool() {
|
|
|
3040
3047
|
validatorPool = createPool(getValidatorDbConfig());
|
|
3041
3048
|
return validatorPool;
|
|
3042
3049
|
}
|
|
3050
|
+
async function warmSingleConnection(pool) {
|
|
3051
|
+
const client = await pool.connect();
|
|
3052
|
+
await client.query("SELECT 1");
|
|
3053
|
+
client.release();
|
|
3054
|
+
}
|
|
3055
|
+
async function warmValidatorPool() {
|
|
3056
|
+
if (poolWarmed)
|
|
3057
|
+
return;
|
|
3058
|
+
const pool = getValidatorPool();
|
|
3059
|
+
const minConns = getEnvNumber("VALIDATOR_DB_POOL_MIN", 1);
|
|
3060
|
+
try {
|
|
3061
|
+
for (let i = 0; i < minConns; i++)
|
|
3062
|
+
await warmSingleConnection(pool);
|
|
3063
|
+
poolWarmed = true;
|
|
3064
|
+
} catch (error) {
|
|
3065
|
+
console.warn("Validator pool warm-up failed, continuing with lazy connection creation:", error);
|
|
3066
|
+
}
|
|
3067
|
+
}
|
|
3043
3068
|
async function validatorQuery(sql, params = []) {
|
|
3044
3069
|
const client = await getValidatorPool().connect();
|
|
3045
3070
|
const onClientError = (err) => {
|
|
@@ -3061,7 +3086,7 @@ async function shutdownValidatorPool() {
|
|
|
3061
3086
|
validatorPool = null;
|
|
3062
3087
|
}
|
|
3063
3088
|
}
|
|
3064
|
-
var import_pg, dotenv, path, import_url, import_connection, __filename, __dirname, PROJECT_ROOT, validatorPool;
|
|
3089
|
+
var import_pg, dotenv, path, import_url, import_connection, __filename, __dirname, PROJECT_ROOT, validatorPool, poolWarmed;
|
|
3065
3090
|
var init_validatorPostgresClient = __esm({
|
|
3066
3091
|
"dist/db/validatorPostgresClient.js"() {
|
|
3067
3092
|
"use strict";
|
|
@@ -3076,6 +3101,7 @@ var init_validatorPostgresClient = __esm({
|
|
|
3076
3101
|
dotenv.config({ path: path.resolve(PROJECT_ROOT, ".env.supabase") });
|
|
3077
3102
|
dotenv.config({ path: path.resolve(PROJECT_ROOT, ".env") });
|
|
3078
3103
|
validatorPool = null;
|
|
3104
|
+
poolWarmed = false;
|
|
3079
3105
|
}
|
|
3080
3106
|
});
|
|
3081
3107
|
|
|
@@ -18433,6 +18459,12 @@ var init_cached_catalog_adapter = __esm({
|
|
|
18433
18459
|
});
|
|
18434
18460
|
|
|
18435
18461
|
// dist/mcp/server.js
|
|
18462
|
+
var server_exports = {};
|
|
18463
|
+
__export(server_exports, {
|
|
18464
|
+
isServerInitialized: () => isServerInitialized,
|
|
18465
|
+
logStartupSummary: () => logStartupSummary
|
|
18466
|
+
});
|
|
18467
|
+
module.exports = __toCommonJS(server_exports);
|
|
18436
18468
|
var import_server = require("@modelcontextprotocol/sdk/server/index.js");
|
|
18437
18469
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
18438
18470
|
var import_types22 = require("@modelcontextprotocol/sdk/types.js");
|
|
@@ -18441,7 +18473,7 @@ var import_types22 = require("@modelcontextprotocol/sdk/types.js");
|
|
|
18441
18473
|
var config = {
|
|
18442
18474
|
// Server identity
|
|
18443
18475
|
SERVER_NAME: "p58-n8n",
|
|
18444
|
-
SERVER_VERSION: "0.2.
|
|
18476
|
+
SERVER_VERSION: "0.2.4",
|
|
18445
18477
|
// Database configuration (from environment)
|
|
18446
18478
|
SUPABASE_URL: process.env.SUPABASE_URL,
|
|
18447
18479
|
SUPABASE_KEY: process.env.SUPABASE_KEY,
|
|
@@ -18727,6 +18759,7 @@ var collectConfigSchema = import_zod.z.object({
|
|
|
18727
18759
|
config_requirements: import_zod.z.array(configRequirementItemSchema).optional().describe("Config requirements from plan_workflow response (preferred over workflow_json). Pass the configRequirements array directly from plan_workflow output."),
|
|
18728
18760
|
user_responses: import_zod.z.record(import_zod.z.unknown()).optional().describe('User-provided values keyed by "nodeType:parameterName" (from question.id). Example: { "n8n-nodes-base.googleSheets:spreadsheetId": "1BxiMVs0..." }. Omit to get questions without providing values (first turn of multi-turn collection).')
|
|
18729
18761
|
});
|
|
18762
|
+
var setupCheckSchema = import_zod.z.object({});
|
|
18730
18763
|
var toolSchemas = {
|
|
18731
18764
|
test_workflow: testWorkflowSchema,
|
|
18732
18765
|
validate_workflow: validateWorkflowSchema,
|
|
@@ -18761,7 +18794,8 @@ var toolSchemas = {
|
|
|
18761
18794
|
test_credential: testCredentialSchema,
|
|
18762
18795
|
update_credential: updateCredentialSchema,
|
|
18763
18796
|
delete_credential: deleteCredentialSchema,
|
|
18764
|
-
collect_config: collectConfigSchema
|
|
18797
|
+
collect_config: collectConfigSchema,
|
|
18798
|
+
setup_check: setupCheckSchema
|
|
18765
18799
|
};
|
|
18766
18800
|
|
|
18767
18801
|
// dist/mcp/tools/validate.js
|
|
@@ -19171,6 +19205,30 @@ async function injectResponseMetadata(sessionId, toolName, response, executionSt
|
|
|
19171
19205
|
return instrumented;
|
|
19172
19206
|
}
|
|
19173
19207
|
|
|
19208
|
+
// dist/mcp/in-flight-tracker.js
|
|
19209
|
+
var inflightCount = 0;
|
|
19210
|
+
function incrementInflight() {
|
|
19211
|
+
inflightCount++;
|
|
19212
|
+
}
|
|
19213
|
+
function decrementInflight() {
|
|
19214
|
+
if (inflightCount > 0)
|
|
19215
|
+
inflightCount--;
|
|
19216
|
+
}
|
|
19217
|
+
function waitForInflightRequests(timeoutMs) {
|
|
19218
|
+
if (inflightCount === 0)
|
|
19219
|
+
return Promise.resolve();
|
|
19220
|
+
return new Promise((resolve2) => {
|
|
19221
|
+
const deadline = setTimeout(resolve2, timeoutMs);
|
|
19222
|
+
const poll = setInterval(() => {
|
|
19223
|
+
if (inflightCount <= 0) {
|
|
19224
|
+
clearInterval(poll);
|
|
19225
|
+
clearTimeout(deadline);
|
|
19226
|
+
resolve2();
|
|
19227
|
+
}
|
|
19228
|
+
}, 50);
|
|
19229
|
+
});
|
|
19230
|
+
}
|
|
19231
|
+
|
|
19174
19232
|
// dist/validation/l1-structure.js
|
|
19175
19233
|
async function validateL1Structure(workflowJson) {
|
|
19176
19234
|
const startTime = performance.now();
|
|
@@ -30380,7 +30438,13 @@ var AutoFixerRegistry = class _AutoFixerRegistry {
|
|
|
30380
30438
|
}
|
|
30381
30439
|
}
|
|
30382
30440
|
};
|
|
30383
|
-
var
|
|
30441
|
+
var _fixerRegistry = null;
|
|
30442
|
+
function getFixerRegistry() {
|
|
30443
|
+
if (!_fixerRegistry) {
|
|
30444
|
+
_fixerRegistry = new AutoFixerRegistry();
|
|
30445
|
+
}
|
|
30446
|
+
return _fixerRegistry;
|
|
30447
|
+
}
|
|
30384
30448
|
|
|
30385
30449
|
// node_modules/axios/lib/helpers/bind.js
|
|
30386
30450
|
function bind(fn, thisArg) {
|
|
@@ -34878,7 +34942,7 @@ async function runAutofixOnWorkflow(workflowJson, issues) {
|
|
|
34878
34942
|
const { applied: credApplied, changelog: credChangelog } = preAssignCredentials(workflow, issues);
|
|
34879
34943
|
const errorIssues = issues.filter((i) => i.severity === "error");
|
|
34880
34944
|
const problems = errorIssues.map(issueToValidationProblem);
|
|
34881
|
-
const fixResult = await
|
|
34945
|
+
const fixResult = await getFixerRegistry().applyFixes(workflow, problems);
|
|
34882
34946
|
const fixChangelog = buildChangelog(fixResult.results);
|
|
34883
34947
|
return {
|
|
34884
34948
|
fixedWorkflow: fixResult.workflow,
|
|
@@ -35273,10 +35337,10 @@ How it works:
|
|
|
35273
35337
|
|
|
35274
35338
|
Validation levels:
|
|
35275
35339
|
- L1: JSON structure, required fields, duplicate node names
|
|
35276
|
-
- L2: Node types exist in catalog (1,
|
|
35277
|
-
- L3: Credential types valid (
|
|
35278
|
-
- L4: Connection patterns exist (
|
|
35279
|
-
- L5: Required parameters configured (
|
|
35340
|
+
- L2: Node types exist in catalog (1,545 nodes)
|
|
35341
|
+
- L3: Credential types valid (679 credentials) \u2014 includes available_credentials lookup
|
|
35342
|
+
- L4: Connection patterns exist (7,642 rules)
|
|
35343
|
+
- L5: Required parameters configured (38,005 params)
|
|
35280
35344
|
- L6: Pattern validation (flow integrity, security, expressions)
|
|
35281
35345
|
|
|
35282
35346
|
Returns detailed issues with severity, location, and suggested fixes.
|
|
@@ -35479,7 +35543,7 @@ var getOperationSchemaToolDefinition = {
|
|
|
35479
35543
|
name: "get_operation_schema",
|
|
35480
35544
|
description: `Get parameter requirements for a specific n8n node operation.
|
|
35481
35545
|
|
|
35482
|
-
Returns the exact required and optional parameters from our
|
|
35546
|
+
Returns the exact required and optional parameters from our 38,005 parameter catalog.
|
|
35483
35547
|
Use this to prevent parameter hallucination when generating n8n workflows.
|
|
35484
35548
|
|
|
35485
35549
|
Examples:
|
|
@@ -36565,6 +36629,77 @@ Examples:
|
|
|
36565
36629
|
}
|
|
36566
36630
|
};
|
|
36567
36631
|
|
|
36632
|
+
// dist/mcp/tools/handlers/shared/n8n-guard.js
|
|
36633
|
+
var SETUP_GUIDE_URL = "https://github.com/tsvika58/p58-n8n/blob/main/docs/AGENT_INSTALL.md";
|
|
36634
|
+
var OFFLINE_TOOLS = /* @__PURE__ */ new Set([
|
|
36635
|
+
"validate_workflow",
|
|
36636
|
+
"get_operation_schema",
|
|
36637
|
+
"check_parameter",
|
|
36638
|
+
"suggest_fix",
|
|
36639
|
+
"list_operations",
|
|
36640
|
+
"list_nodes",
|
|
36641
|
+
"get_node_info",
|
|
36642
|
+
"find_similar_pattern",
|
|
36643
|
+
"get_session_metrics",
|
|
36644
|
+
"get_credential_schema",
|
|
36645
|
+
"setup_check"
|
|
36646
|
+
]);
|
|
36647
|
+
function requiresN8nApiKey(toolName) {
|
|
36648
|
+
return !OFFLINE_TOOLS.has(toolName);
|
|
36649
|
+
}
|
|
36650
|
+
function makeN8nNotConfiguredError() {
|
|
36651
|
+
return {
|
|
36652
|
+
content: [
|
|
36653
|
+
{
|
|
36654
|
+
type: "text",
|
|
36655
|
+
text: JSON.stringify({
|
|
36656
|
+
error: `This tool requires n8n connection. Set N8N_API_URL and N8N_API_KEY in your MCP config. See: ${SETUP_GUIDE_URL}`
|
|
36657
|
+
})
|
|
36658
|
+
}
|
|
36659
|
+
],
|
|
36660
|
+
isError: true
|
|
36661
|
+
};
|
|
36662
|
+
}
|
|
36663
|
+
function isDbConfigError(error) {
|
|
36664
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
36665
|
+
return msg.includes("Missing required validator DB environment variable");
|
|
36666
|
+
}
|
|
36667
|
+
function isDbConnectionError(error) {
|
|
36668
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
36669
|
+
return msg.includes("ECONNREFUSED") || msg.includes("ETIMEDOUT") || msg.includes("connect ETIMEDOUT") || msg.includes("after calling end on the pool") || msg.includes("Connection terminated") || msg.includes("getaddrinfo ENOTFOUND") || msg.includes("too many connections") || msg.includes("remaining connection slots");
|
|
36670
|
+
}
|
|
36671
|
+
function makeDbNotConfiguredResponse() {
|
|
36672
|
+
return {
|
|
36673
|
+
content: [
|
|
36674
|
+
{
|
|
36675
|
+
type: "text",
|
|
36676
|
+
text: JSON.stringify({
|
|
36677
|
+
error: "DB_NOT_CONFIGURED",
|
|
36678
|
+
message: "Catalog features require P58_DATABASE_URL. Set P58_DATABASE_URL in your MCP config to enable this tool.",
|
|
36679
|
+
setup_guide: SETUP_GUIDE_URL
|
|
36680
|
+
})
|
|
36681
|
+
}
|
|
36682
|
+
],
|
|
36683
|
+
isError: true
|
|
36684
|
+
};
|
|
36685
|
+
}
|
|
36686
|
+
function makeDbConnectionErrorResponse() {
|
|
36687
|
+
return {
|
|
36688
|
+
content: [
|
|
36689
|
+
{
|
|
36690
|
+
type: "text",
|
|
36691
|
+
text: JSON.stringify({
|
|
36692
|
+
error: "CATALOG_UNREACHABLE",
|
|
36693
|
+
message: "Catalog database is unreachable. Verify your P58_DATABASE_URL is correct and the database server is accessible. If the problem persists, contact Tsvika.",
|
|
36694
|
+
hint: "Check: (1) connection string starts with postgresql://mcp_friend... (2) port is 6543 (transaction pooler) (3) network allows outbound to AWS eu-north-1",
|
|
36695
|
+
setup_guide: SETUP_GUIDE_URL
|
|
36696
|
+
})
|
|
36697
|
+
}
|
|
36698
|
+
],
|
|
36699
|
+
isError: true
|
|
36700
|
+
};
|
|
36701
|
+
}
|
|
36702
|
+
|
|
36568
36703
|
// dist/mcp/middleware/response-compression.js
|
|
36569
36704
|
function selectFields(item, fields) {
|
|
36570
36705
|
const result = {};
|
|
@@ -36684,8 +36819,11 @@ async function handleListOperations(args) {
|
|
|
36684
36819
|
return toMCPResponse(response);
|
|
36685
36820
|
} catch (error) {
|
|
36686
36821
|
const originalError = error instanceof Error ? error : new Error(String(error));
|
|
36687
|
-
|
|
36688
|
-
|
|
36822
|
+
if (isDbConfigError(originalError))
|
|
36823
|
+
return makeDbNotConfiguredResponse();
|
|
36824
|
+
if (isDbConnectionError(originalError))
|
|
36825
|
+
return makeDbConnectionErrorResponse();
|
|
36826
|
+
return toMCPResponse(createInternalError(correlationId, originalError));
|
|
36689
36827
|
}
|
|
36690
36828
|
}
|
|
36691
36829
|
var listOperationsToolDefinition = {
|
|
@@ -36782,13 +36920,16 @@ async function handleListNodes(args) {
|
|
|
36782
36920
|
return toMCPResponse(response);
|
|
36783
36921
|
} catch (error) {
|
|
36784
36922
|
const originalError = error instanceof Error ? error : new Error(String(error));
|
|
36785
|
-
|
|
36786
|
-
|
|
36923
|
+
if (isDbConfigError(originalError))
|
|
36924
|
+
return makeDbNotConfiguredResponse();
|
|
36925
|
+
if (isDbConnectionError(originalError))
|
|
36926
|
+
return makeDbConnectionErrorResponse();
|
|
36927
|
+
return toMCPResponse(createInternalError(correlationId, originalError));
|
|
36787
36928
|
}
|
|
36788
36929
|
}
|
|
36789
36930
|
var listNodesToolDefinition = {
|
|
36790
36931
|
name: "list_nodes",
|
|
36791
|
-
description: `List all available n8n nodes (1,
|
|
36932
|
+
description: `List all available n8n nodes (1,545 total) with filtering and pagination.
|
|
36792
36933
|
|
|
36793
36934
|
Use this to discover available nodes before generating workflows. The tool supports:
|
|
36794
36935
|
- Pagination: Use limit (1-100) and offset for large result sets
|
|
@@ -36945,8 +37086,11 @@ async function handleGetNodeInfo(args) {
|
|
|
36945
37086
|
return toMCPResponse(response);
|
|
36946
37087
|
} catch (error) {
|
|
36947
37088
|
const originalError = error instanceof Error ? error : new Error(String(error));
|
|
36948
|
-
|
|
36949
|
-
|
|
37089
|
+
if (isDbConfigError(originalError))
|
|
37090
|
+
return makeDbNotConfiguredResponse();
|
|
37091
|
+
if (isDbConnectionError(originalError))
|
|
37092
|
+
return makeDbConnectionErrorResponse();
|
|
37093
|
+
return toMCPResponse(createInternalError(correlationId, originalError));
|
|
36950
37094
|
}
|
|
36951
37095
|
}
|
|
36952
37096
|
var getNodeInfoToolDefinition = {
|
|
@@ -37034,8 +37178,11 @@ async function handleFindSimilarPattern(args) {
|
|
|
37034
37178
|
return toMCPResponse(response);
|
|
37035
37179
|
} catch (error) {
|
|
37036
37180
|
const originalError = error instanceof Error ? error : new Error(String(error));
|
|
37037
|
-
|
|
37038
|
-
|
|
37181
|
+
if (isDbConfigError(originalError))
|
|
37182
|
+
return makeDbNotConfiguredResponse();
|
|
37183
|
+
if (isDbConnectionError(originalError))
|
|
37184
|
+
return makeDbConnectionErrorResponse();
|
|
37185
|
+
return toMCPResponse(createInternalError(correlationId, originalError));
|
|
37039
37186
|
}
|
|
37040
37187
|
}
|
|
37041
37188
|
var findSimilarPatternToolDefinition = {
|
|
@@ -37232,8 +37379,8 @@ schemas, build_workflow handles validation, autofix, and deployment automaticall
|
|
|
37232
37379
|
|
|
37233
37380
|
Runs L1-L4 validation before creating:
|
|
37234
37381
|
- L1: JSON structure, required fields
|
|
37235
|
-
- L2: Node types exist in catalog (1,
|
|
37236
|
-
- L3: Credential types are valid (
|
|
37382
|
+
- L2: Node types exist in catalog (1,545 nodes)
|
|
37383
|
+
- L3: Credential types are valid (679 credentials)
|
|
37237
37384
|
- L4: Connection patterns exist
|
|
37238
37385
|
|
|
37239
37386
|
Refuses creation if any L1-L4 errors are found.
|
|
@@ -38604,7 +38751,7 @@ async function validateWorkflowObject(workflow, timeoutMs, label) {
|
|
|
38604
38751
|
}
|
|
38605
38752
|
async function runAutoFix(workflow, validationResult, timeoutMs, toolName) {
|
|
38606
38753
|
const problems = validationResult.issues.filter((i) => i.severity === "error").map(issueToValidationProblem2);
|
|
38607
|
-
const fixResult = await withTimeout(
|
|
38754
|
+
const fixResult = await withTimeout(getFixerRegistry().applyFixes(workflow, problems), timeoutMs, `${toolName} autofix`);
|
|
38608
38755
|
return { fixedWorkflow: fixResult.workflow, fixResult };
|
|
38609
38756
|
}
|
|
38610
38757
|
async function applyAutoFixIfNeeded(workflow, validationResult, hasErrors, shouldFix, timeoutMs, correlationId, toolName) {
|
|
@@ -38825,6 +38972,16 @@ async function warmCredentialCache() {
|
|
|
38825
38972
|
import_logging42.logger.warn("credential-cache: warm-up failed (non-fatal)", { error: String(error) });
|
|
38826
38973
|
}
|
|
38827
38974
|
}
|
|
38975
|
+
function getCredentialCacheStatus() {
|
|
38976
|
+
if (!cacheState) {
|
|
38977
|
+
return { loaded: false, count: 0, expires_at: null };
|
|
38978
|
+
}
|
|
38979
|
+
return {
|
|
38980
|
+
loaded: true,
|
|
38981
|
+
count: cacheState.credentials.length,
|
|
38982
|
+
expires_at: new Date(cacheState.expires_at).toISOString()
|
|
38983
|
+
};
|
|
38984
|
+
}
|
|
38828
38985
|
function clearCredentialCache() {
|
|
38829
38986
|
cacheState = null;
|
|
38830
38987
|
}
|
|
@@ -39241,7 +39398,7 @@ function issueToValidationProblem3(issue) {
|
|
|
39241
39398
|
}
|
|
39242
39399
|
async function runFixStep(workflow, validation, timeoutMs) {
|
|
39243
39400
|
const problems = validation.issues.filter((i) => i.severity === "error").map(issueToValidationProblem3);
|
|
39244
|
-
const fixResult = await withTimeout(
|
|
39401
|
+
const fixResult = await withTimeout(getFixerRegistry().applyFixes(workflow, problems), timeoutMs, "server_autofix:fix");
|
|
39245
39402
|
return {
|
|
39246
39403
|
fixedWorkflow: fixResult.workflow,
|
|
39247
39404
|
fixes: extractAppliedFixes(fixResult)
|
|
@@ -41271,6 +41428,10 @@ and what service it connects to \u2014 don't attempt to build with a broken cred
|
|
|
41271
41428
|
Part of the generation lifecycle: plan_workflow \u2192 test_credential(s) \u2192 build_workflow.
|
|
41272
41429
|
NOT needed for editing or updating existing workflows (use update_workflow or partial_update_workflow).
|
|
41273
41430
|
|
|
41431
|
+
Note: plan_workflow works without n8n (catalog-only mode). To actually deploy
|
|
41432
|
+
workflows with build_workflow, N8N_API_KEY and N8N_API_URL must be configured.
|
|
41433
|
+
Without n8n, use plan_workflow for research and architecture planning only.
|
|
41434
|
+
|
|
41274
41435
|
Response modes:
|
|
41275
41436
|
- "full": All research data within token_budget (default 8,000)
|
|
41276
41437
|
- "summary" (default): Key fields within token_budget (default 4,000)
|
|
@@ -43077,7 +43238,12 @@ async function handleGetCredentialSchema(args) {
|
|
|
43077
43238
|
return buildSchemaResponse(credential_type, rows, nodes, correlationId, startTime);
|
|
43078
43239
|
} catch (error) {
|
|
43079
43240
|
import_logging57.logger.error("get_credential_schema: unexpected error", { correlationId, error });
|
|
43080
|
-
|
|
43241
|
+
const originalError = error instanceof Error ? error : new Error(String(error));
|
|
43242
|
+
if (isDbConfigError(originalError))
|
|
43243
|
+
return makeDbNotConfiguredResponse();
|
|
43244
|
+
if (isDbConnectionError(originalError))
|
|
43245
|
+
return makeDbConnectionErrorResponse();
|
|
43246
|
+
return toMCPResponse(createInternalError(correlationId, originalError));
|
|
43081
43247
|
}
|
|
43082
43248
|
}
|
|
43083
43249
|
async function handleUnknownType(credentialType, correlationId) {
|
|
@@ -44091,6 +44257,129 @@ When values are collected, marks matching factory.gaps entries as resolved for a
|
|
|
44091
44257
|
}
|
|
44092
44258
|
};
|
|
44093
44259
|
|
|
44260
|
+
// dist/mcp/tools/handlers/setup-check.js
|
|
44261
|
+
var SETUP_GUIDE_URL2 = "https://github.com/tsvika58/p58-n8n/blob/main/docs/AGENT_INSTALL.md";
|
|
44262
|
+
var N8N_PROBE_TIMEOUT_MS = 2e3;
|
|
44263
|
+
var N8N_PROBE_PORTS = [5678, 5679];
|
|
44264
|
+
async function probeN8nUrl(url2) {
|
|
44265
|
+
const controller = new AbortController();
|
|
44266
|
+
const timer = setTimeout(() => controller.abort(), N8N_PROBE_TIMEOUT_MS);
|
|
44267
|
+
try {
|
|
44268
|
+
const response = await fetch(url2, { signal: controller.signal });
|
|
44269
|
+
const needs_api_key = response.status === 401 || response.status === 403;
|
|
44270
|
+
return { url: url2, status: response.status, needs_api_key, reachable: true };
|
|
44271
|
+
} catch (error) {
|
|
44272
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
44273
|
+
return {
|
|
44274
|
+
url: url2,
|
|
44275
|
+
status: null,
|
|
44276
|
+
needs_api_key: false,
|
|
44277
|
+
reachable: false,
|
|
44278
|
+
error: message.includes("abort") ? "timeout" : message
|
|
44279
|
+
};
|
|
44280
|
+
} finally {
|
|
44281
|
+
clearTimeout(timer);
|
|
44282
|
+
}
|
|
44283
|
+
}
|
|
44284
|
+
async function discoverN8nInstances() {
|
|
44285
|
+
const probeUrls = N8N_PROBE_PORTS.map((port) => `http://localhost:${port}/api/v1/workflows`);
|
|
44286
|
+
return Promise.all(probeUrls.map(probeN8nUrl));
|
|
44287
|
+
}
|
|
44288
|
+
function buildToolCounts() {
|
|
44289
|
+
const total = getRegisteredTools().length;
|
|
44290
|
+
const tier1 = OFFLINE_TOOLS.size;
|
|
44291
|
+
return { tier1, tier2_7: total - tier1 };
|
|
44292
|
+
}
|
|
44293
|
+
function collectIssues(apiKeySet, n8nConnected, probes) {
|
|
44294
|
+
const issues = [];
|
|
44295
|
+
if (!apiKeySet) {
|
|
44296
|
+
issues.push("N8N_API_KEY not set \u2014 Tier 2-7 deploy tools unavailable");
|
|
44297
|
+
}
|
|
44298
|
+
const apiUrlSet = Boolean(process.env.N8N_API_URL ?? process.env.N8N_API_BASE_URL);
|
|
44299
|
+
if (!apiUrlSet && probes) {
|
|
44300
|
+
const reachable = probes.filter((p) => p.reachable);
|
|
44301
|
+
if (reachable.length > 0) {
|
|
44302
|
+
const probeUrl = reachable[0].url.replace("/api/v1/workflows", "");
|
|
44303
|
+
issues.push(`N8N_API_URL not set \u2014 n8n detected at ${probeUrl}. Set N8N_API_URL=${probeUrl}/api/v1 in your MCP config.`);
|
|
44304
|
+
} else {
|
|
44305
|
+
issues.push("N8N_API_URL not set \u2014 no n8n instance detected on localhost:5678 or localhost:5679");
|
|
44306
|
+
}
|
|
44307
|
+
}
|
|
44308
|
+
if (apiKeySet && !n8nConnected) {
|
|
44309
|
+
issues.push("N8N_API_KEY is set but n8n is unreachable \u2014 check N8N_API_URL and ensure n8n is running");
|
|
44310
|
+
}
|
|
44311
|
+
return issues;
|
|
44312
|
+
}
|
|
44313
|
+
async function buildReport() {
|
|
44314
|
+
const apiKeySet = Boolean(process.env.N8N_API_KEY);
|
|
44315
|
+
const n8nUrl = process.env.N8N_API_URL ?? process.env.N8N_API_BASE_URL ?? null;
|
|
44316
|
+
const cacheStatus = getCredentialCacheStatus();
|
|
44317
|
+
const n8nConnected = cacheStatus.loaded;
|
|
44318
|
+
const credentialCount = cacheStatus.loaded ? cacheStatus.count : null;
|
|
44319
|
+
let probes;
|
|
44320
|
+
if (!n8nUrl) {
|
|
44321
|
+
probes = await discoverN8nInstances();
|
|
44322
|
+
}
|
|
44323
|
+
const issues = collectIssues(apiKeySet, n8nConnected, probes);
|
|
44324
|
+
const toolCounts = buildToolCounts();
|
|
44325
|
+
const report = {
|
|
44326
|
+
server_version: config.SERVER_VERSION,
|
|
44327
|
+
n8n_configured: apiKeySet,
|
|
44328
|
+
n8n_url: n8nUrl,
|
|
44329
|
+
n8n_connected: n8nConnected,
|
|
44330
|
+
n8n_api_key_set: apiKeySet,
|
|
44331
|
+
credential_count: credentialCount,
|
|
44332
|
+
catalog_ready: true,
|
|
44333
|
+
tools_available: toolCounts,
|
|
44334
|
+
issues,
|
|
44335
|
+
setup_guide: SETUP_GUIDE_URL2
|
|
44336
|
+
};
|
|
44337
|
+
if (probes) {
|
|
44338
|
+
report.n8n_probes = probes.map((p) => ({
|
|
44339
|
+
...p,
|
|
44340
|
+
url: p.url.replace("/api/v1/workflows", "/api/v1")
|
|
44341
|
+
}));
|
|
44342
|
+
}
|
|
44343
|
+
return report;
|
|
44344
|
+
}
|
|
44345
|
+
async function handleSetupCheck(_args) {
|
|
44346
|
+
try {
|
|
44347
|
+
const report = await buildReport();
|
|
44348
|
+
return {
|
|
44349
|
+
content: [{ type: "text", text: JSON.stringify(report, null, 2) }]
|
|
44350
|
+
};
|
|
44351
|
+
} catch (error) {
|
|
44352
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
44353
|
+
return {
|
|
44354
|
+
content: [{ type: "text", text: JSON.stringify({ error: `setup_check failed: ${message}` }) }],
|
|
44355
|
+
isError: true
|
|
44356
|
+
};
|
|
44357
|
+
}
|
|
44358
|
+
}
|
|
44359
|
+
var setupCheckToolDefinition = {
|
|
44360
|
+
name: "setup_check",
|
|
44361
|
+
description: `Run this first to check what's configured and what's missing.
|
|
44362
|
+
|
|
44363
|
+
Returns a diagnostic report including:
|
|
44364
|
+
- Server version
|
|
44365
|
+
- n8n connection status (configured/connected/unreachable)
|
|
44366
|
+
- n8n URL (from env var or auto-detected)
|
|
44367
|
+
- Credential count (if n8n is connected)
|
|
44368
|
+
- Tool availability by tier
|
|
44369
|
+
- List of issues with actionable guidance
|
|
44370
|
+
- Link to the setup guide
|
|
44371
|
+
|
|
44372
|
+
When N8N_API_URL is not set, automatically probes localhost:5678 and localhost:5679
|
|
44373
|
+
to detect a local n8n installation.
|
|
44374
|
+
|
|
44375
|
+
Use this after installation to verify everything is working, or to diagnose
|
|
44376
|
+
connection problems.`,
|
|
44377
|
+
inputSchema: {
|
|
44378
|
+
type: "object",
|
|
44379
|
+
properties: {}
|
|
44380
|
+
}
|
|
44381
|
+
};
|
|
44382
|
+
|
|
44094
44383
|
// dist/mcp/tools/index.js
|
|
44095
44384
|
var toolRegistry = /* @__PURE__ */ new Map();
|
|
44096
44385
|
var TOOL_ENTRIES = [
|
|
@@ -44127,7 +44416,8 @@ var TOOL_ENTRIES = [
|
|
|
44127
44416
|
{ name: "test_credential", definition: testCredentialToolDefinition, handler: handleTestCredential },
|
|
44128
44417
|
{ name: "update_credential", definition: updateCredentialToolDefinition, handler: handleUpdateCredential },
|
|
44129
44418
|
{ name: "delete_credential", definition: deleteCredentialToolDefinition, handler: handleDeleteCredential },
|
|
44130
|
-
{ name: "collect_config", definition: collectConfigToolDefinition, handler: handleCollectConfig }
|
|
44419
|
+
{ name: "collect_config", definition: collectConfigToolDefinition, handler: handleCollectConfig },
|
|
44420
|
+
{ name: "setup_check", definition: setupCheckToolDefinition, handler: handleSetupCheck }
|
|
44131
44421
|
];
|
|
44132
44422
|
function registerTool(tool) {
|
|
44133
44423
|
if (!hasSchema(tool.name)) {
|
|
@@ -44155,13 +44445,21 @@ async function dispatchToolCall(name, args) {
|
|
|
44155
44445
|
const tool = toolRegistry.get(name);
|
|
44156
44446
|
if (!tool)
|
|
44157
44447
|
return buildUnknownToolResponse(name);
|
|
44158
|
-
if (
|
|
44159
|
-
|
|
44160
|
-
|
|
44161
|
-
|
|
44162
|
-
|
|
44448
|
+
if (requiresN8nApiKey(name) && !process.env.N8N_API_KEY) {
|
|
44449
|
+
return makeN8nNotConfiguredError();
|
|
44450
|
+
}
|
|
44451
|
+
incrementInflight();
|
|
44452
|
+
try {
|
|
44453
|
+
if (tool.inputSchema && hasSchema(name)) {
|
|
44454
|
+
const validation = validateToolInput(name, args);
|
|
44455
|
+
if (!validation.success)
|
|
44456
|
+
return createValidationErrorResponse(validation.error);
|
|
44457
|
+
return await tool.handler(validation.data);
|
|
44458
|
+
}
|
|
44459
|
+
return await tool.handler(args);
|
|
44460
|
+
} finally {
|
|
44461
|
+
decrementInflight();
|
|
44163
44462
|
}
|
|
44164
|
-
return tool.handler(args);
|
|
44165
44463
|
}
|
|
44166
44464
|
async function handleToolCall(name, args, sessionId = "default") {
|
|
44167
44465
|
const startTime = Date.now();
|
|
@@ -44179,7 +44477,9 @@ function registerAllTools() {
|
|
|
44179
44477
|
registerTool({ ...entry, inputSchema: toolSchemas[entry.name] });
|
|
44180
44478
|
}
|
|
44181
44479
|
}
|
|
44182
|
-
|
|
44480
|
+
|
|
44481
|
+
// dist/mcp/server.js
|
|
44482
|
+
init_validatorPostgresClient();
|
|
44183
44483
|
|
|
44184
44484
|
// dist/mcp/middleware/credential-redaction.js
|
|
44185
44485
|
var MAX_DEPTH = 20;
|
|
@@ -44352,6 +44652,7 @@ var defaultDeps = {
|
|
|
44352
44652
|
};
|
|
44353
44653
|
async function runCleanup(serverName, deps) {
|
|
44354
44654
|
try {
|
|
44655
|
+
await waitForInflightRequests(5e3);
|
|
44355
44656
|
await deps.shutdownPool();
|
|
44356
44657
|
deps.clearCache();
|
|
44357
44658
|
deps.clearConfigCache?.();
|
|
@@ -44383,6 +44684,46 @@ function registerShutdownHandlers(serverName, deps) {
|
|
|
44383
44684
|
}
|
|
44384
44685
|
|
|
44385
44686
|
// dist/mcp/server.js
|
|
44687
|
+
var SETUP_GUIDE_URL3 = "https://github.com/tsvika58/p58-n8n/blob/main/docs/AGENT_INSTALL.md";
|
|
44688
|
+
var _serverInitialized = false;
|
|
44689
|
+
function isServerInitialized() {
|
|
44690
|
+
return _serverInitialized;
|
|
44691
|
+
}
|
|
44692
|
+
function buildInitializingResponse() {
|
|
44693
|
+
return {
|
|
44694
|
+
content: [{
|
|
44695
|
+
type: "text",
|
|
44696
|
+
text: JSON.stringify({
|
|
44697
|
+
error: "SERVER_INITIALIZING",
|
|
44698
|
+
message: "Server is still loading. Please retry in a moment.",
|
|
44699
|
+
retryAfterMs: 2e3
|
|
44700
|
+
})
|
|
44701
|
+
}],
|
|
44702
|
+
isError: true
|
|
44703
|
+
};
|
|
44704
|
+
}
|
|
44705
|
+
function logStartupSummary(n8nConnected) {
|
|
44706
|
+
const apiKey = process.env.N8N_API_KEY;
|
|
44707
|
+
const n8nUrl = process.env.N8N_API_URL ?? process.env.N8N_API_BASE_URL ?? "http://localhost:5678/api/v1";
|
|
44708
|
+
const totalTools = getRegisteredTools().length;
|
|
44709
|
+
const tier1Count = OFFLINE_TOOLS.size;
|
|
44710
|
+
const tier27Count = totalTools - tier1Count;
|
|
44711
|
+
let n8nStatus;
|
|
44712
|
+
if (!apiKey) {
|
|
44713
|
+
n8nStatus = "not configured (set N8N_API_URL and N8N_API_KEY for deploy tools)";
|
|
44714
|
+
} else if (n8nConnected) {
|
|
44715
|
+
n8nStatus = `connected (${n8nUrl})`;
|
|
44716
|
+
} else {
|
|
44717
|
+
n8nStatus = `configured but unreachable (${n8nUrl})`;
|
|
44718
|
+
}
|
|
44719
|
+
const tier27Status = apiKey && n8nConnected ? `${tier27Count} tools ready` : `${tier27Count} tools unavailable (no N8N_API_KEY)`;
|
|
44720
|
+
console.error(`n8n: ${n8nStatus}`);
|
|
44721
|
+
console.error(`catalog: ready`);
|
|
44722
|
+
console.error(`Tier 1: ${tier1Count} tools ready | Tier 2-7: ${tier27Status}`);
|
|
44723
|
+
if (!apiKey) {
|
|
44724
|
+
console.error(`Setup guide: ${SETUP_GUIDE_URL3}`);
|
|
44725
|
+
}
|
|
44726
|
+
}
|
|
44386
44727
|
var server = new import_server.Server({
|
|
44387
44728
|
name: config.SERVER_NAME,
|
|
44388
44729
|
version: config.SERVER_VERSION
|
|
@@ -44405,6 +44746,9 @@ function toCallToolResult(response) {
|
|
|
44405
44746
|
server.setRequestHandler(import_types22.CallToolRequestSchema, async (request) => {
|
|
44406
44747
|
const { name, arguments: args } = request.params;
|
|
44407
44748
|
try {
|
|
44749
|
+
if (!_serverInitialized) {
|
|
44750
|
+
return toCallToolResult(buildInitializingResponse());
|
|
44751
|
+
}
|
|
44408
44752
|
const response = await handleToolCall(name, args ?? {});
|
|
44409
44753
|
return toCallToolResult(redactMCPResponse(response));
|
|
44410
44754
|
} catch (error) {
|
|
@@ -44414,16 +44758,35 @@ server.setRequestHandler(import_types22.CallToolRequestSchema, async (request) =
|
|
|
44414
44758
|
});
|
|
44415
44759
|
async function main() {
|
|
44416
44760
|
const transport = new import_stdio.StdioServerTransport();
|
|
44761
|
+
const startMs = Date.now();
|
|
44417
44762
|
await server.connect(transport);
|
|
44763
|
+
console.error(`[INIT] MCP handshake complete in ${Date.now() - startMs}ms`);
|
|
44764
|
+
registerAllTools();
|
|
44765
|
+
_serverInitialized = true;
|
|
44418
44766
|
const toolCount = getRegisteredTools().length;
|
|
44419
|
-
console.error(
|
|
44767
|
+
console.error(`[INIT] ${toolCount} tools registered in ${Date.now() - startMs}ms`);
|
|
44768
|
+
logStartupSummary(Boolean(process.env.N8N_API_KEY));
|
|
44420
44769
|
registerShutdownHandlers(config.SERVER_NAME);
|
|
44421
|
-
warmCredentialCache().catch((
|
|
44770
|
+
void warmCredentialCache().catch(() => {
|
|
44771
|
+
});
|
|
44772
|
+
if (process.env.P58_DATABASE_URL || process.env.MCP_DATABASE_URL) {
|
|
44773
|
+
void warmValidatorPool().then(() => {
|
|
44774
|
+
console.error("catalog: connected \u2713");
|
|
44775
|
+
}).catch((err) => {
|
|
44776
|
+
console.error(`catalog: WARNING \u2014 connection failed: ${err.message}`);
|
|
44777
|
+
console.error("catalog: tools will retry on first use, but check P58_DATABASE_URL if errors persist");
|
|
44778
|
+
});
|
|
44779
|
+
}
|
|
44422
44780
|
}
|
|
44423
44781
|
main().catch((error) => {
|
|
44424
44782
|
console.error("Server failed to start:", error);
|
|
44425
44783
|
process.exit(1);
|
|
44426
44784
|
});
|
|
44785
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
44786
|
+
0 && (module.exports = {
|
|
44787
|
+
isServerInitialized,
|
|
44788
|
+
logStartupSummary
|
|
44789
|
+
});
|
|
44427
44790
|
/*! Bundled license information:
|
|
44428
44791
|
|
|
44429
44792
|
mime-db/index.js:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@path58/p58-n8n",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "The smartest and fastest n8n MCP server — validate, fix, and discover workflows inside your LLM",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
],
|
|
14
14
|
"author": "Path58",
|
|
15
15
|
"license": "MIT",
|
|
16
|
+
"homepage": "https://github.com/tsvika58/p58-n8n#readme",
|
|
16
17
|
"repository": {
|
|
17
18
|
"type": "git",
|
|
18
|
-
"url": "git+https://github.com/tsvika58/n8n
|
|
19
|
+
"url": "git+https://github.com/tsvika58/p58-n8n.git"
|
|
19
20
|
},
|
|
20
21
|
"bin": {
|
|
21
22
|
"p58-n8n": "dist/mcp/server.bundle.cjs"
|