Files

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

  1. Identify Workflow: Search for existing workflows using mcp__n8n__search_workflows.
  2. Inspect Schema: Use mcp__n8n__get_workflow_details to understand required input parameters (e.g., username, ticketId).
  3. Execute: Use mcp__n8n__execute_workflow.
  4. Retrieve Results:
    • Use mcp__n8n__get_execution with includeData: true.
    • If the result is large and truncated to a file (e.g., /tmp/hermes-results/...), use read_file and execute_code.
  5. 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, try Scott 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_code to 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_execution multiple times or implement a wait loop in execute_code before 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 Unauthorized against 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 a result key (it often has NO id key — don't wait for id==1).
  • search_workflow_executions: server retains only ~30 recent executions server-wide; status filter param is not accepted; filter by workflowId param works but also just filter client-side by scanning. nextCursor pagination exists but the retained window is tiny anyway.
  • Direct API Auth & Headers: same as below Direct API calls via execute_code (using requests) fail with 401 Unauthorized if the clientId and companyId are 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 the Authorization: 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.body when executed via MCP, causing downstream nodes to fail or receive undefined.
  • 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.