UNPKG

@awesomate/hosting-mcp

Version:

Awesomate MCP server — lets Claude manage your Awesomate WordPress hosting, plan, limits, n8n automations, and build Node/static apps + databases

144 lines (118 loc) • 7.33 kB
# AI Agent / LLM workflows on Awesomate n8n Read before designing or editing any agent, chat, or LLM-chain workflow. **Not sure this is the right kind of agent?** An assistant the user sets up once and talks to in Slack/Telegram, runs on a schedule, or calls from many workflows is an **n8n Agent** (the Agents tab, n8n 2.40+), not a workflow with an AI Agent node: read [n8n-agents.md](n8n-agents.md) and use `awesomate_n8n_agents`. Platform basics (task runners, `$vars`, `$json.body`) are in platform-notes.md. ## Before building — always 1. Call `awesomate_n8n_context` — confirm consent, plan, variant, limits. 2. Check model credentials FIRST: `awesomate_n8n_inspect {what:"credentials"}`. Look for openrouter / openai / anthropic entries. No model credential = stop and ask the user; never invent one. 3. Verify current typeVersions via `awesomate_n8n_node_docs {tool:"get_node"}` — `agent`, `chatTrigger`, `httpRequestTool` bump frequently. Point-in-time snapshot (re-verify): `@n8n/n8n-nodes-langchain.agent` 3.1, `n8n-nodes-base.httpRequestTool` 4.4, `lmChatOpenRouter` 1. On 503 `node_catalog_unavailable`, fall back to the vendor/ references. ## Architecture - Chat agent = `@n8n/n8n-nodes-langchain.chatTrigger` → `@n8n/n8n-nodes-langchain.agent`, with model (`ai_languageModel`), memory (`ai_memory`), and tools (`ai_tool`) attached as sub-node connections. - Agent v3.x: `systemMessage` lives at `parameters.options.systemMessage`. The validator reports it missing — false positive, ignore. Set `options.maxIterations` explicitly. - Chat Hub / streaming requires agent typeVersion >= 3.x. A 1.x agent behind a chatTrigger fails at send time with "Agent node version is too old to support streaming responses". - **Reasoning/execution separation**: the AI decides, deterministic nodes act. Validate model output before any side effect. An LLM cannot tell its input was truncated — detect truncation in the deterministic layer, state it in the payload, and forbid destructive recommendations explicitly. ## Tools - HTTP tool node is `n8n-nodes-base.httpRequestTool` at its CURRENT typeVersion (verify via get_node; 4.4 at last check). NEVER `@n8n/n8n-nodes-langchain.toolHttpRequest` — deprecated, and under agent v3.x it fails every call with `has a "supplyData" method but no "execute" method`. - Every tool needs a descriptive `toolDescription` — it is the only signal the agent has for choosing and parameterizing the tool. - Headers via `headerParameters.parameters` `[{name, value}]`; body via `bodyParameters.parameters`. Full response (status/headers/IDs): `options.response.response.fullResponse: true`. ### $fromAI rules - `$fromAI('alias', 'description', 'string')` goes in individual tool parameter VALUES only: `"value": "={{ $fromAI('alias', 'desc', 'string') }}"`. - NEVER inside `JSON.stringify()` or embedded mid-string in `jsonBody` — the `$fromAI` scanner cannot extract it and the model passes literal placeholder text. (Sole exception: a `jsonBody` that is ONE whole-body `$fromAI('JSON', ``, 'json')` expression, optionally wrapped in an arrow-IIFE to inject mandatory fields — keep the `/*n8n-auto-generated-fromAI-override*/` marker.) - One `$fromAI` key per node = one parameter. Repeating a key in multiple parameters with differing description/type crashes EVERY agent turn with `Duplicate key '<k>' found` before any LLM call. - Type `'json'` does NOT parse a JSON-encoded string argument. For array/object params use `JSON.parse($fromAI(..., 'string'))` — the parse throw surfaces as a tool error the agent recovers from; it is load-bearing. - Default emitted type is `'string'`. Numeric/boolean params need a manual override: `={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('limit', `desc`, 'number') }}` — otherwise real numbers fail schema validation. ### toolWorkflow (sub-workflow tools) - The sub-workflow must be ACTIVE — an inactive one errors at tool-call time, not save time. - `workflowInputs` needs a populated `schema`, not just `value`. With `schema: []`, `$fromAI` mappings silently resolve to empty strings and the agent loops to "Max iterations reached". - Tools run the sub-workflow's PUBLISHED version. Draft edits are dormant until the sub-workflow is republished — the classic "my edit did nothing". ## Model credentials - OpenRouter via `lmChatOpenRouter`: model IDs use DOT notation (`anthropic/claude-sonnet-4.5`), never hyphenated version suffixes — the wrapper mangles them. Dated slugs (`...-20250929`) are rejected. Verify slugs against OpenRouter's live `/api/v1/models`, not memory. - Dedicated model nodes (lmChatOpenRouter etc.) auto-bind credentials by NAME at create time — prefer them over raw HTTP for LLM calls. ## Memory - Separate memory per user/session: key the memory node's session on the chatTrigger's `sessionId`. A static shared key mixes every user's conversation into one history. - Motorhead memory node is deprecated — do not use. ## Structured output - NEVER attach a structured output parser to the FINAL agent of a chat workflow — it breaks streaming/chat responses. Agent v3.x + parser + `enableStreaming: true` loops to max iterations: tools fire (side effects happen) on iteration 1, then the agent restates a valid answer forever. - Prefer deriving routing metadata deterministically (e.g. `{{ $('Trigger').isExecuted }}`) over asking the LLM to echo it. If structured output is genuinely needed, disable streaming or parse in a downstream node. - `retryOnFail` on an agent whose tools have side effects re-runs the whole agent after a post-success failure → duplicate posts/sends. Don't combine. ## chainLlm (Basic LLM Chain) - Emits NO `pairedItem`: any downstream `$('Node').item` throws "Paired item data ... is unavailable" on multi-item inputs. `$('Node').first()` works. Fixes: positional re-join in a Code node right after the chain (with a count-mismatch guard), or route all items through ONE switch output so the chain runs exactly once (fan-in from two outputs breaks pairing). - Its error output (`onError: continueErrorOutput`) DOES carry the input item's json fields plus an `error` key. ## Chat widget embed (agent on a website) n8n's chat widget can embed the agent on any site. chatTrigger config: - `mode: "webhook"` and `responseMode: "lastNode"` for external embedding. - CORS `allowedOrigins`: no trailing slashes, no spaces after commas. - No structured output parser on the final agent (see above). ## Test and publish - E2E = publish + production webhook + poll executions. Publish through the n8n MCP server, fire the production webhook (or the n8n server's execute tool), then `awesomate_n8n_executions {workflowId}` to find the run and `awesomate_n8n_executions {executionId, debug: true}` for node-by-node detail. - A change to a live agent workflow goes onto its own id (SKILL.md §4); a copy mints new webhookIds. - `saveExecutionProgress` stays FALSE (set it yourself; quadratic-write incident). Agent/tool loops around `splitInBatches` need an `executionTimeout`. - Agent + chat workflows also run their published version — republish after edits, and republish referenced sub-workflows too.