5.3 KiB
name, description
| name | description |
|---|---|
| connectwise-n8n-automation | Use when automating ConnectWise PSA tasks via n8n workflows. |
ConnectWise n8n Automation
Use when automating ConnectWise PSA tasks (fetching tickets, updating owners, summarizing notes) using n8n workflows via MCP.
Workflow
- Identify Workflow: Search for existing workflows using
mcp__n8n__search_workflows. - Inspect Schema: Use
mcp__n8n__get_workflow_detailsto understand required input parameters (e.g.,username,ticketId). - Execute: Use
mcp__n8n__execute_workflow. - Retrieve Results:
- Use
mcp__n8n__get_executionwithincludeData: true. - If the result is large and truncated to a file (e.g.,
/tmp/hermes-results/...), useread_fileandexecute_code.
- Use
- Verification: If a workflow is supposed to update data, verify the change by re-fetching the record.
Pitfalls & Lessons
1. Parsing Truncated Tool Outputs
When mcp__n8n__get_execution returns a result too large for the context, Hermes saves it to a file. These files are not raw JSON; they are line-numbered (e.g., 1|{"result": ...}).
- Wrong:
json.loads(file_content) - Right:
json_str = line.split('|', 1)[1].strip()before parsing.
2. User Filtering Ambiguity
ConnectWise nodes in n8n may use different fields for "username".
- If filtering by
SBrown(identifier) returns 0 results but you know tickets exist, tryScott Brown(full name). - The workflow's internal query often uses
owner/name like ..., which may require the human-readable name.
3. API Auth (n8n vs. Direct)
Direct API calls via execute_code (using requests) often fail with 401 Unauthorized even with correct Public/Private keys because they lack the required clientId (UUID).
- Guidance: Always prefer existing n8n workflows for ConnectWise actions. If no workflow exists, create one using
mcp__n8n__create_workflow_from_codeto leverage n8n's managed credentials.
4. Long-Running LLM Workflows
Workflows utilizing AI (e.g., Ollama for summarization) take significantly longer than standard API la calls.
- Action: Poll
mcp__n8n__get_executionmultiple times or implement a wait loop inexecute_codebefore attempting to read the final results.
5. MCP Server Access: Two Servers, Two Tokens, SSE Result Framing
- TWO n8n MCP servers exist: tallerhawk (token in ~/.hermes/.env as N8N_API_KEY) and n8n.vistanetinc.com (token ONLY in config.yaml under mcp_servers). The .env token returns
Unauthorizedagainst vistanetinc — pull the config.yaml one instead. - Raw HTTP MCP works: POST to /mcp-server/http with Accept: 'application/json, text/event-stream'; responses are SSE frames. The RESULT frame is the first
data:frame containing aresultkey (it often has NOidkey — don't wait for id==1). - search_workflow_executions: server retains only ~30 recent executions server-wide;
statusfilter param is not accepted; filter by workflowId param works but also just filter client-side by scanning.nextCursorpagination exists but the retained window is tiny anyway. - Direct API Auth & Headers: same as below
Direct API calls via
execute_code(usingrequests) fail with401 Unauthorizedif theclientIdandcompanyIdare missing from the headers, even if Basic Auth is correct. - Required Headers:
clientId: UUID of the client application.companyId: The company identifier (e.g.,VNI).
- Auth String Format: The username must be constructed as
companyid+publickey. If the public key already starts with a+, do not add an additional+between the company ID and the key (to avoid the "double-plus bug"). - Correct Base64 Pattern:
base64(companyid+publickey:privatekey). - Correction: Ensure both headers are present alongside Basic Auth. If standard
auth=(user, pass)parameters fail, manually construct theAuthorization: Basic <base64>header.
7. Trigger-Specific Data Mapping (MCP vs Webhook)
When triggering a workflow via the execute_workflow MCP tool, input data is injected at the root level, whereas real HTTP requests put data under the body object.
- Pitfall: An n8n workflow starting with a Webhook trigger will see an empty
$json.bodywhen executed via MCP, causing downstream nodes to fail or receiveundefined. - Fix: Add a Set (Edit Fields) node immediately after the trigger to normalize the data using nullish coalescing:
ticketId\rightarrow{{ $json.body?.ticketId ?? $json.ticketId }}memberId\rightarrow{{ $json.body?.memberId ?? $json.memberId }}
- Result: Downstream nodes can now safely use
{{ $json.ticketId }}regardless of how the workflow was triggered.
8. PSA Release Notes Are Not Programmatically Reachable
docs.connectwise.com's PSA release-notes tree is SSO-gated and blocks anonymous datacenter IPs at the CDN edge (every fetch returns a login interstitial; Wayback/archive.today hold zero captures). When asked what a release contains: verify CVE/security-bulletin facts from public bulletins first — those ARE fetchable — then route functional release-note questions to the user (ConnectWise Home release-notes widget on their logged-in console) instead of cycling anonymous recovery ladders. For a full pull, ask the user to save partner-portal credentials to the vault so the docs site can be logged into.