Releases: freddy-schuetz/n8n-claw
Release list
v1.9.2 — Config backup: 413 fix + claw_agents in backups
Two bugs in the config-backup skill's full backup, fixed.
Fixed
- 413 Payload Too Large — once the DB grew to ~19 MB, the base64 backup body (~25 MB) blew past the file-bridge's hardcoded 25 MB Express limit, so automatic backups had been failing since ~2026-06-01. The file-bridge now gzips backups at rest (transparent
compress: trueflag — downloads and Seafile forwards decompress on the fly, no breaking change), and the body limit derives fromMAX_FILE_SIZE_MB(20 → 200) instead of a hardcoded value. - Persona/config silently missing from backups —
TABLE_DEFS/SCOPES/UPSERT_TABLESstill named the tableagents, so since the Issue #35 rename every full backup wroteclaw_agents: 0 rows. Now corrected; restore adds a legacyagents→claw_agentsalias so pre-#35 backups still restore.
Validated
Live on the VPS: 19.0 MB / 11372-row full backup with claw_agents: 19 rows, uploaded without 413 and forwarded to Seafile (19.2 MB). End-to-end: DB → file-bridge (gzipped at rest) → Seafile (plain JSON).
Upgrade
git pull && ./setup.sh --force, then reinstall the config-backup skill (now n8n-claw-templates@6089521, v1.2.0). No breaking changes to stored files.
Full notes in CHANGELOG.md.
🤖 Generated with Claude Code
v1.9.1 — Bugfix: agents table collision with n8n 2.21+
Bugfix release
Fixes a startup crash that takes the whole instance down after upgrading n8n (Issue #35).
The problem
n8n 2.21.4 introduced a built-in Agents feature. Its boot migration CreateAgentTables1783000000000 creates a public.agents table and indexes its projectId column. n8n-claw already owned a public.agents table (persona and tool config, the source of the system prompt) in the same Postgres database. So n8n's createTable('agents') no-op'd, the follow-up createIndex('agents', ['projectId']) failed with column "projectId" does not exist, and n8n crash-looped on every boot without ever reaching "ready".
The whole 2.21.x and 2.22.x lines are affected (last clean n8n: 2.20.12). Because docker-compose.yml tracks n8nio/n8n:latest, any docker compose pull after 2.21.4 shipped took the instance down. No data is lost (the failed migration rolls back in its transaction), but every restart re-fails.
The fix
The n8n-claw config/persona table is renamed from agents to claw_agents, freeing the agents name for n8n's own core table. New migration supabase/migrations/009_agents_rename.sql is idempotent and data-preserving: it only ever touches a public.agents that has a key column (n8n-claw's table, never n8n's core one), and it handles both the rename-in-place and the upgrade case where 001 has already created an empty claw_agents. docker-compose.yml stays on :latest, since the two table names no longer overlap.
All shipped workflows, the schema, the seeds, and setup.sh are updated to claw_agents. Persona keys (persona:{id}) are unchanged.
Upgrade
git pull && ./setup.sh --forceMigration 009 preserves all personas and config; n8n then creates its own clean agents table. No manual steps, no data loss.
Breaking only for custom code: any user-added workflow or external script that queries the agents table or /rest/v1/agents directly must switch to claw_agents.
Verified live
After setup.sh --force on the live instance: public.agents is now n8n's core table (projectId, 0 rows), public.claw_agents holds the app rows (config + personas, nothing lost), n8n boots without the CreateAgentTables failure, and the agent loads its system prompt from claw_agents and replies normally (executions finished with status success).
Full details: see CHANGELOG.md.
v1.9.0 — Browser use, interactive 2FA
What's new
n8n-claw stops being read-only on the web. Until now the agent could read pages (Crawl4AI as Web Reader, SearXNG as Web Search) but couldn't do anything — it couldn't sign you up for a newsletter, fill a contact form, click a button, log into a site to fetch private data, or run any multi-step UI flow. v1.9.0 ships Browser Use as a built-in capability: a real headless Chromium driven by an agentic LLM loop, exposed to the main agent as a single browser_action tool with three modes (task, list_sessions, close_session).
End-to-end validated on 2026-05-11 against the live VPS — newsletter signup on jens.marketing in 70s (5 LLM steps), seven-field pizza-order form on httpbin in 65s, top-5 HN stories with article-content summaries in 206s (12 steps), and a full interactive-2FA login round-trip to GitHub that actually starred a real repo as the authenticated user.
This is not a skill — it's a built-in agent capability like Memory or Web Reader. No install step. Pull v1.9.0, run setup.sh --force, and browser_action is wired into every chat.
The cherry on top emerged unplanned during real-world testing: interactive 2FA works end-to-end without any TOTP generator built into the bridge. The agent hits the 2FA wall, returns a focused message asking for the code, the keep-alive session pool keeps the 2FA page loaded in the live Chromium, the user reads the code from their authenticator app and sends it as the next Telegram message, the agent makes a follow-up browser_action call with the matching domain — the code lands on the still-open form, GitHub redirects to the dashboard, every subsequent task on that domain inherits the authenticated session. This was not a designed feature; it falls out of keep_alive=True plus the agent behaving sensibly when it doesn't have a tool for something — and it covers TOTP, SMS, and email-magic-link 2FA. The only 2FA flavour it can't cover is hardware-key / WebAuthn / passkey, because that needs a physical USB device the bridge doesn't have.
How it works under the hood
Browser Use 0.12.6 ships only an stdio MCP server, which n8n's HTTP-based MCP Client cannot speak to. So this release does not register a skill in mcp_registry — instead it ships a thin FastAPI sidecar (browser-bridge/, ~200 lines of Python) that adapts Browser Use's SDK to a normal HTTP API and runs alongside the existing bridges (email-bridge, file-bridge, discord-bridge). The agent's tool call → workflows/browser-use.json sub-workflow → http://browser-bridge:3400/tasks → live Chromium.
This shape gives us two things Browser Use doesn't have natively:
- Keep-alive session pool keyed by
(user_id, domain)— works around the brokensave_storage_statein Browser Use 0.12.6 (Issue #1002, reproduced during the spike) by simply keeping the Chromium process alive between tool calls. Max 5 concurrent live browsers (BROWSER_BRIDGE_MAX_SESSIONS), 30-min idle eviction (BROWSER_BRIDGE_IDLE_TIMEOUT_S), LRU-evicted when full. All sessions die on container restart by design — this is the v1 trade-off until upstream fixes the persistence bug. - Per-request LLM provider routing — bridge reads
tools_config.llm_provideron everyPOST /tasksand instantiates the matchingbrowser_use.llm.Chat*class with the corresponding env-supplied API key. Switching providers does not require a bridge restart, and the bridge always follows whichever provider the main agent is currently configured for.
Critical Chromium args (--no-sandbox --disable-dev-shm-usage --disable-gpu + chromium_sandbox=False) are hardcoded in session_pool.py — without these the browser launch times out at 30 s on a headless Linux VPS. Spike-validated, future-proofed.
Engine decision — why Browser Use, not Skyvern
Data-driven, not vibes. A hands-on spike against Skyvern 1.0.36+ (the obvious AGPL alternative) on three identical tasks showed Browser Use winning decisively on the use case that matters: form fills.
| Task | Skyvern | Browser Use |
|---|---|---|
| Newsletter signup (jens.marketing) | ✅ 58 s / 3 steps | ✅ 52 s / 5 steps |
| Cookie persistence (httpbin) | ✅ with workaround | ❌ save_storage_state raises ValueError |
| 7-field pizza-order form (httpbin) | ✅ 585 s / 16 steps | ✅ 65 s / 4 steps |
That 9× gap on form fill is not a tuning issue, it's an architecture gap — Skyvern is vision-based and bills one action per step (~36 s/step end-to-end including LLM call + screenshot + reasoning), Browser Use is DOM-based and bundles up to 5 actions per step. Skyvern Issue #4439 ("4–5 min for 5–6 fields") has been open since December and matches what was measured.
License pointed the same way: Browser Use is MIT, Skyvern is AGPL-3.0 with a network-clause that would have closed the door on the dmo-claw commercial fork. The cookie-persistence bug we worked around in browser-bridge's session pool is upstream-fixable; the Skyvern speed gap is architectural and would not have improved.
Validated
- Newsletter signup (executions
104677/104678) — jens.marketing, 70 s, 5 steps, agent dismissed cookie banner + navigated to signup form + entered email + checked privacy checkbox + submitted, returned the double-opt-in confirmation text. First production use of the feature. - Session-pool reuse across separate tool calls (executions
104708/104711) — setfreddy=test2on httpbin.org withdomain=httpbin.org, separate Telegram message minutes later calledGET /cookieswith the same domain and got{"freddy": "test2"}back. The v1 keep-alive design works end-to-end; persistent logins are real, just bounded by container lifetime. - Interactive 2FA round-trip on GitHub (executions
104757→104760→104763→104776) — login with username + password hits the 2FA wall and returns cleanly with a "send me the code" message. User sends the 6-digit code as the next Telegram message; agent enters it on the still-open form; GitHub redirects to dashboard. Follow-up tasks (Star repo, read private notifications inbox) inherit the authenticated session. First documented interactive-2FA flow in n8n-claw. - Multi-step browse + summarise (execution
104780) — top 5 HN stories with article-content summaries. 12 steps, 206 s, 5 different external sites opened, accurate 2-sentence summary each.
Breaking changes
None. No schema changes, no migration. The browser-bridge service is additive in docker-compose; the workflow + agent toolWorkflow are additive in n8n. Existing functionality is unaffected. setup.sh --force is required to install the new sub-workflow and re-seed the agents.browser_use system-prompt row.
Known limitations
- Anti-bot-protected sites are out of scope. Doctolib was the smoke test: two attempts, both timed out before reaching the appointment slots. Open-source headless Chromium without a residential-proxy network gets fingerprinted and slow-walked by serious bot detection (Cloudflare Bot Management, Datadome, etc.). Skyvern's Cloud product solves this with residential proxies + anti-bot fingerprint randomisation; open-source Skyvern hits the same wall. Plain mainstream sites without aggressive detection (GitHub, Hacker News, jens.marketing, httpbin, Substack-style forms) work fine.
- Hardware-key 2FA / WebAuthn / passkeys are not supported. Interactive 2FA covers TOTP, SMS code, and email-magic-link — anything where the second factor is a string the user can paste. WebAuthn requires a physical USB device the bridge cannot present.
- Sessions are in-memory only. Container restart (or
setup.sh --force) wipes every pooled browser. Persistence-across-reboots needs Browser Use to fixsave_storage_state(Issue #1002) — until then, expect to re-authenticate on each fresh deploy. The 30-min idle eviction also kills idle sessions inside one container lifetime. - GitHub Personal Access Tokens are not valid UI-login passwords. PATs work for
git pushover HTTPS and for the REST API, not forgithub.com/login. Use real password + interactive 2FA instead — that's the validated path. - CAPTCHAs. No solver. If a CAPTCHA appears the bridge returns the screenshot URL and asks the user to handle it. Browser Use 0.12.6 doesn't surface CAPTCHAs as cleanly as it does 2FA prompts — mileage may vary by site.
Resource impact
- ~500 MB – 1 GB RAM per active browser session. At the 5-session pool cap, expect up to ~3 GB peak.
mem_limit: 3gon the service is a hard ceiling. VPS recommendation stays at 2 GB minimum (idle bridge is ~200 MB; the heavy footprint only materialises while a task is running). - Container image is ~1.5 GB (Python 3.12-slim + Playwright + Chromium binary). One-time build; rebuilds via Docker layer cache are fast.
- LLM-token usage — typical task is 4–12 LLM round-trips with vision-enabled prompts (~5–20k tokens per round-trip including screenshot). A newsletter signup costs roughly the same as a moderate-length conversation turn.
Examples — what you can ask your agent
Plain natural language, no special prefixes. The agent routes anything that needs UI interaction to browser_action.
Newsletter / contact forms:
Sign me up for the Lenny's Newsletter on lennysnewsletter.com with my email
Agent finds the signup form, enters the email, submits, returns the confirmation.
Logged-in actions with interactive 2FA:
Log into github.com with username freddy-schuetz and password X — and star browser-use/browser-use after
Agent submits credentials, hits 2FA wall, asks for the code, you reply with the TOTP, agent enters it, then stars the repo. All on the same live browser session.
Multi-step research with content extraction:
Open the top 5 s...
v1.8.0 - Apify (6,000+ scrapers)
What's new
n8n-claw gets dynamic, instance-wide access to the entire Apify Store: Apify Actors, a bridge skill that wraps https://mcp.apify.com and exposes 8 meta-tools to the agent. The agent uses search-actors to discover scrapers by platform keyword, fetch-actor-details to read each Actor's live JSON input schema, and call-actor to execute any of the 6,000+ Actors in the Store — Google Maps places, Instagram posts, Trustpilot reviews, Booking.com hotels, LinkedIn profiles, Amazon bestsellers, you name it — without writing a single line of per-Actor glue code.
End-to-end validated on 2026-05-11 against a real Apify token (execution 103944: agent → search-actors → fetch-actor-details → call-actor → parsed dataset → 4 real Instagram comments formatted as a markdown table for Telegram, 101 seconds for the whole chain).
This is the first production bearer-auth MCP bridge in n8n-claw. The previous (and only) bridge skill, deepwiki, ran with auth_type: "none". The bearer-auth code path — mcp_registry.auth_type + auth_token written by the credential form, then read by the agent's inline MCP Client toolCode and injected as Authorization: Bearer <token> on every JSON-RPC call to the upstream MCP server — was wired since migration 006_mcp_bridge in v1.3.0 but had never been exercised end-to-end. Apify exercises it now. No code patches were needed in mcp-client.json, mcp-library-manager.json, or n8n-claw-agent.json to ship this skill: the infrastructure was already there.
Catalog grows to 71 skills.
Skill: Apify Actors (8 tools)
search-actors— discover Actors in the Apify Store by broad keyword (e.g.instagram,google maps,tiktok). Returns ranked Actor cards with name, description, pricing, usage stats, success rate, rating. Mandatory first step in the discovery chain — the agent picks the best-rated specialised scraper for the platform instead of guessing Actor names.fetch-actor-details— get full metadata for a specific Actor (username/nameformat): JSON input schema, README summary, pricing breakdown, output schema, deprecation status. Always called beforecall-actorso the agent reads the live input spec instead of inventing it.call-actor— run any Actor synchronously or asynchronously. Sync returnsdatasetIdplus preview items inline; async returns arunIdfor long-running scrapes. SupportscallOptions.memory(128 MB – 32 GB) andcallOptions.timeout. For MCP-server Actors uses theactorName:toolNameinvocation format.get-actor-run— check status and metadata of a specific Actor run byrunId(timestamps, stats, dataset reference) — used to poll async runs before fetching output.get-actor-output— fetch dataset items from a completed run. Supportsfields(comma-separated, with dot notation likecrawl.statusCode) andoffset+limit, so the agent can pull large scrapes piece by piece without blowing the LLM context.search-apify-docs— full-text search over Apify Platform / Crawlee-JS / Crawlee-Python documentation (docSourceparameter switches between them). Returns matching URLs + content snippets.fetch-apify-docs— fetch the full markdown content of a documentation page by URL.apify--rag-web-browser— pre-bundled web browser Actor for one-shot Google-search-and-scrape. Framed as a last-resort fallback in the manifest description; the agent is steered toward Crawl4AI (Web Reader) for plain page reads and SearXNG (Web Search) for general queries instead — to avoid spending Apify credits on what other skills handle for free.
Bridge install path — zero workflow imports
Bridges register directly into mcp_registry. Install flow:
- Library Manager fetches
manifest.jsonfrom the templates CDN, seestype: "bridge", skips workflow import entirely. - Inserts one row into
mcp_registrywithtemplate_type='bridge',mcp_url='https://mcp.apify.com',auth_type='bearer', the 8 tool names, and a NULLauth_token. - Generates a one-time
credential_tokenslink to the secure HTTPS credential form. - User pastes the Apify API Token into the form; on submit, the token is dual-written to
template_credentials(template_id='apify', cred_key='auth_token') and mirrored intomcp_registry.auth_tokenfor the matchingtemplate_id. - On reinstall after
remove_template, the existingtemplate_credentialsrow is reused — no re-entry needed.
The agent's existing MCP Client toolCode picks the new bridge up automatically: on every mcp_client call it queries mcp_registry by mcp_url, prepends Bearer for auth_type='bearer' (or uses the raw token verbatim for auth_type='header'), and injects the Authorization header into all three JSON-RPC roundtrips (initialize, notifications/initialized, tools/list for schema validation, tools/call). The same toolCode pre-fetches the upstream tools/list schema on each call and rewrites missing-required-args errors into schema-hint responses the LLM can self-correct from — which is why the agent recovers gracefully when it guesses query instead of keywords for search-actors.
Fixed (during release)
- The agent reached for
apify--rag-web-browserinstead of the discovery chain on the first install. Given the choice betweensearch-actors→fetch-actor-details→call-actorand the pre-bundled one-shot RAG meta-tool, Claude sometimes picked the shortcut and paid Apify compute units for what a generic Crawl4AI/SearXNG fetch would have handled. Same regression had to be patched on the OpenWebUI Apify adapter side. Fix: a stronger workflow nudge in the manifest description (templates v1.0.0 → v1.0.1, commitb522ae6) that the Library Manager pulls intomcp_registry.descriptionand the system-prompt builder shows to the LLM on every turn.apify--rag-web-browseris now explicitly framed as a last-resort fallback, and the description routes plain webpage reads to Crawl4AI and web search to SearXNG.
Validated
- Apify MCP endpoint —
https://mcp.apify.com(no/mcpsuffix), Streamable HTTP transport (MCP protocol2024-11-05), SSE-formatted JSON-RPC responses (event: message/id: …/data: {…}framing). Bearer auth viaAuthorizationheader confirmed working with a real token. Tool names use dashes, not snake_case (search-actors,fetch-actor-details,call-actor,apify--rag-web-browser) — passed through verbatim by the agent's MCP Client toolCode without rewriting. - End-to-end production test (execution 103944, 2026-05-11) — user message "Suche mir die letzten 10 Kommentare von dem Instagram Kanal ep_reisen, kein Zwischenstatus" → agent discovered the Instagram Actor via
search-actors, inspected its input schema viafetch-actor-details, ran it viacall-actor, parsed the returned dataset, formatted 4 real comments (with usernames, text, dates, like counts) as a Telegram-ready markdown table. Total runtime 101 seconds, 21 nodes green, no errors. First successful invocation of a bearer-auth bridge in n8n-claw.
Breaking changes
None. No schema changes, no migration. Existing skills are unaffected. The mcp_registry.auth_type + auth_token columns were already present since v1.3.0; this release is the first to put them to real use.
Known limitations
- Single instance-wide token. The Apify token lives in
mcp_registry.auth_token, one row per installed bridge skill. There is no per-user-credential mechanism intemplate_credentialsyet, so on multi-user instances (dmo-claw) every chat user consumes credits from the same Apify account and shares the same view of the data. A per-user-credential schema extension is plausible but out of scope for v1.8.0. - Manifest description is set once at install time. Description text changes pushed to the templates repo (like the v1.0.0 → v1.0.1 tool-selection-nudge fix in this release) require a
remove_template+install_templatecycle on existing instances to land inmcp_registry.description. Token is preserved across the cycle via thetemplate_credentialslookup. apify--rag-web-browseris still in the tool list. Hiding it via the manifest description (last-resort framing) is a behavioural nudge, not enforcement. Apify's MCP server exposes it unconditionally ontools/list. The framing usually steers the agent away, but does not guarantee it.
Examples — what you can ask your agent
You talk to your existing main agent (Telegram, OpenWebUI, or webhook) as usual. The agent routes anything Apify-related via mcp_client to the new bridge. Plain natural language, no special prefixes:
Sales — on-the-fly lead enrichment, single contact:
Just met Max from XY GmbH at the fair — get me his LinkedIn
Agent finds the profile, calls a LinkedIn Actor (e.g. dev_fusion/Linkedin-Profile-Scraper, ~$0.01 per profile), returns email + role + recent posts.
Hospitality — competitor / partner hotel reviews:
What are guests saying about Hotel Goldener Adler on Booking lately?
Agent picks voyager/booking-reviews-scraper (~$0.05 per 1,000 reviews), pulls the last batch, summarises rating trend + top complaints + top praise.
Reputation — competitor monitoring on Trustpilot:
What's the latest Trustpilot buzz about competitor X?
Agent uses memo23/trustpilot-scraper-ppe ($0.75 per 1,000 reviews, 4.86★), extracts the recent rating + recurring themes + red flags.
E-commerce — daily bestseller intel:
What's hot on Amazon DE Sports today?
Agent calls junglee/amazon-bestsellers (4.97★ in the Store), returns today's top-100 with prices and biggest movers. Schedulable via the existing scheduled_actions table for a fresh-every-morning digest.
Documentation — when an Actor's docs are unclear:
Search Apify docs for "standby actors"
Agent c...
v1.7.0 — Fitness Buddy (Beta)
What's new
n8n-claw gets a real fitness coach skill: Fitness Buddy — not a chat persona that pretends to track meals, but a 14-tool MCP skill backed by 9 dedicated PostgreSQL tables that owns every meal, workout, body measurement, hydration log, goal, and training session. Voice transcripts are parsed via gpt-4o-mini structured-output, meal photos go through gpt-4o-mini Vision with strict JSON-Schema for items + grams + confidence, and the multi-week training plan generator picks exercises from real wger.de IDs (verified live: 845 exercises in the anonymous /exerciseinfo/ endpoint, no auth, no LLM hallucination on the exercise list).
Companion read-only skill wger Exercises ships alongside — anonymous wger.de browsing for exercises standalone. Catalog grows to 70 skills with a new health category.
Disclaimer & scientific basis
Fitness Buddy is an experimental coaching skill and does not replace professional sports, fitness, or nutritional advice — use is at your own risk. Calorie targets are computed via the Mifflin-St-Jeor BMR formula × activity multiplier (1.2–1.9) × goal modifier; macros use 1.6–2.2 g protein/kg body weight (goal-dependent), 0.9 g fat/kg, carbs from the remainder; workout calorie burn is estimated via MET (Metabolic Equivalent of Task) values × bodyweight × duration. Nutrition data comes from OpenFoodFacts, exercise data from wger.de — both community-maintained sources whose entries vary in completeness and accuracy.
Skill: Fitness Buddy (14 tools)
fitness_profile— step-by-step conversational onboarding. The skill drives a multi-turn dialog: agent calls withsub_action='setup', skill replies with the next single question, repeats until all 6 required fields are in. Mifflin-St-Jeor BMR × Activity-Multiplier × Goal-Modifier → daily kcal/macro/hydration targets.log_meal— five input modes:from_text,from_voice(Whisper transcript),from_photo(file_ref → gpt-4o-mini Vision with strict JSON-Schema for items + grams + confidence),from_barcode,from_memory. Items resolve via OpenFoodFacts barcode → name search → LLM nutrition fallback. Plusedit,delete,clear_day.meal_memory— save frequently eaten meals as named templates ("My standard breakfast") for one-click re-logging.suggest_meal— gpt-4o-mini takes today's remaining macro budget, your allergies + dietary restrictions, plus your top-10 favorites, and returns 3 suggestions with macros that fit.log_workout— auto-extracts type / duration / intensity from text or voice. Calorie burn estimated via MET formula × profile weight × duration. Auto-links to today's plannedfitness_plan_session; auto-updates activeworkout_frequencygoals.log_body— weight, body fat %, muscle mass, circumferences.trendaction computes change over a configurable window.log_hydration— water intake in ml.todayshows progress vs target.set_targetoverrides the default 35ml/kg calculation.goals— set / list / archive. Types:weight,body_fat,workout_frequency,distance,strength,habit,streak.current_valueauto-updates as logs come in.summary—today/week/month. Aggregates kcal/macros/workouts/hydration vs targets, plus a streak count.training_plan—generate_customis the marquee feature: fetches 80 real exercises from wger.de's/exerciseinfo/endpoint, packs them into the LLM prompt as#1962 Step Jack [Cardio|none|Quads], instructs gpt-4o-mini to pick 4–6 exercises per session and reference them bywger_id, applies progressive overload + deload week. Result decomposed intofitness_plans+fitness_plan_sessions. Plustoday,get_active,complete_session,adjust.reminders— three presets (morning_meal,evening_summary,weekly_report) inserted intoscheduled_actions. Heartbeat fires them; agent receives the instruction and routes back to fitness-buddy.insights— periodic pattern detection. Aggregates 30 days of data, gets back 3–5 actionable insights, writes tomemory_longwithcategory='insight'. Main agent's existing v1.5.0 insight-recall picks them up automatically.export— CSV export of meals/workouts/body/hydration over a date range. Returns afile_reffor Telegram document send.nutrition_lookup— standalone OpenFoodFacts barcode/name lookup without logging.
Requires an OpenAI API key (Whisper + Vision + structured-output). If OPENAI_API_KEY is configured in .env during setup.sh, the key is pre-seeded into template_credentials so installing the skill does not re-prompt.
Skill: wger Exercises (7 tools)
Anonymous read-only wrapper around wger.de's exercise database. search_exercises (filter by muscle / equipment / category / language), get_exercise (full details by ID with images), list_categories, list_muscles, list_equipment. The list_public_templates / get_template_detail endpoints exist as stubs but return a clear "use generate_custom in fitness-buddy instead" message — wger's /public-templates/ endpoint is auth-protected (HTTP 403 to anonymous callers, discovered live during integration testing).
008_fitness_schema.sql migration
9 new fitness_* tables, idempotent, wired into the existing migration loop in setup.sh after 007_pg17_compat. All tables scoped via user_id text NOT NULL (matching the tasks / reminders pattern, port-ready for multi-user dmo-claw later). Tables: fitness_profile (1 row per user, computed targets persist), fitness_meals (denormalized totals + jsonb item-array), fitness_meal_memory (UNIQUE on user_id, name), fitness_workouts, fitness_body (time-series), fitness_hydration, fitness_goals (self-referencing parent_id for sub-goals), fitness_plans (partial unique index WHERE status='active' enforces one active plan per user), fitness_plan_sessions (FK to plan, indexed on (user_id, planned_for) for the today-query). PostgREST GRANT ALL to anon / authenticated / service_role. Final NOTIFY pgrst, 'reload schema' so new tables are reachable via REST immediately.
Infrastructure additions
- OpenAI key pre-seed:
setup.shnow writesOPENAI_API_KEYintotemplate_credentialsfor fitness-buddy automatically (INSERT … ON CONFLICT DO UPDATE, dollar-quoted SQL, silent-fails on errors). No re-entry needed when installing the skill. - Library Manager credential-skip extension: the OAuth-shared skip check in
install_templatenow fires for any credential — first checkingtemplate_credentialsfor(storeUnder, cred_key)wherestoreUnder = shared_id || templateId, and skipping the credential-form-link generation if a row exists. Picks up pre-seeded keys and any future skill that wants the same pattern. agents.fitness_routingsystem-prompt key: seeded bysetup.shalongside the existingmcp_instructions/tools/task_managementkeys. Documents which user phrases route to which fitness-buddy tool with whichsub_action, the empty-string-for-unknowns call convention (next paragraph), and the explicit forbidden alternatives — noexpert_agentdelegation, no Web Search / HTTP fallback, no fabrication on skill error. Loaded as its own top-level## fitness_routingsection in every agent turn.
Fixed
- OpenAI structured-output schemas were rejected with HTTP 400 in nested objects. Strict mode requires every property to appear in the
requiredarray — making a property semantically optional is done via a[type, "null"]union plus the property still being required (the LLM is then allowed to returnnull). The first-cut training_plan schema hadwger_id,weight_kg,rest_s,notestyped as[type, "null"]but missing fromrequired, with the same latent bug in log_workout (distance_km,perceived_exertion,notes). Fixed: every property is now inrequiredacross all structured-output calls in the skill. - OpenAI errors were swallowed as "Request failed with status code 400". The axios error from
helpers.httpRequestdid not propagate the response body. Fixed:openaiChat()wraps the call, extractserr.response?.bodyorerr.body, and re-throws with the actual OpenAI validation message in scope. Debugging structured-output regressions now surfaces the real reason instead of an axios placeholder. - n8n's mcpTrigger ignores
"required": falsein the toolWorkflow input schema. Every non-hardcodedvaluefield is exposed as required in the externaltools/listresponse regardless of the schema-array flag. So an agent callingfitness_profilewith just{sub_action: "setup"}was rejected by mcp_client validation. Workaround in the tool description: instruct the agent to include every parameter on every call, using""for fields the user has not provided yet. The skill's setup logic skips empty strings (input[f] !== ''), so multi-turn onboarding works unchanged once the call validates. Documented as a quirk for future MCP skills. - The agent fabricated training plans / onboarding questionnaires on initial tests. Two distinct routes: (a) "set up my profile" → improvised 12-field questionnaire instead of calling the skill, (b) "training plan" → delegated to research-expert sub-agent which web-searched a generic plan and presented it as if it came from the fitness skill. Neither path stored anything in
fitness_plansorfitness_meals. Fixed: the newfitness_routingsystem-prompt section explicitly forbids both — agent must call mcp_client → fitness-buddy for any fitness topic; on skill error it must surface the error verbatim and never fabricate or fall back to research-expert / Web Search / HTTP.
Breaking changes
None. The 9 fitness_* tables stay empty for users who do not install the skill — negligible storage. The fitness_routing agents key is benign when fitness-buddy is not regist...
v1.6.0 — PostgreSQL 17 by default
What's new
Supabase's platform support for PostgreSQL 15 winds down around May 2026. PostgreSQL community EOL for 15 is November 2027. Time to move. Fresh n8n-claw installs now ship on PostgreSQL 17.6 directly, and existing PG15 instances get an explicit ./setup.sh --upgrade-pg17 command that handles the data migration in one shot.
The right answer for n8n-claw turned out to be pg_dump + restore, not in-place pg_upgrade. Supabase's official upgrade tool is tightly coupled to their full self-host stack (vault encryption, db-config Docker volume, pgsodium key) which n8n-claw doesn't ship — pre-flight hard-fails. Dump/restore is also a better fit for n8n-claw's typical scale (< 1 GB DBs, simple schema, no cross-schema triggers): 3–5 minutes downtime, original data preserved as ./volumes/db/data.bak.pg15 for instant rollback, validated end-to-end on a 286 MB live instance before shipping.
--upgrade-pg17 for existing installs
- Pre-flight checks: PG version, disk space (
3× DB + 2 GB), incompatible extensions (timescaledb / plv8 / plls / plcoffee / pgjwt — none in n8n-claw, but blocks if you added them), replication slots, leftover artefacts from prior attempts - Backs the named volume up to a host bind dir, wipes the named volume
- Spins up a fresh PG17 cluster via
docker run(NOT compose) with oursupabase/migrationsmounted into/docker-entrypoint-initdb.d— this suppresses the supabase/postgres image's baked-in init that would otherwise createpg_graphqlwith a DDL event trigger that supautils eventuallypg_terminate_backend()s mid-restore - Restores the dump via Unix socket (TCP
-h localhostwas unreliable in the standalone-container scenario) - Sanity-checks
public.soulrow count after restore — if zero, abort with rollback instructions instead of advancing to a broken state - Switches the stack to compose with the PG17 image via auto-generated
docker-compose.override.yml - Hard-fails on
connection refusedpatterns (those used to be swallowed as harmless)
007_pg17_compat.sql migration
ALTER FUNCTION public.immutable_unaccent(text) SET search_path = public, pg_catalog- Pre-empts PG17's safe-search_path enforcement during maintenance ops (REINDEX, REFRESH MATERIALIZED VIEW, VACUUM) on the GIN index over
memory_long.search_vector - Idempotent and safe under PG15 — runs as part of the standard migration loop in
setup.sh, so fresh installs are forward-compatible too
Default image flipped
docker-compose.yml:supabase/postgres:15.8.1.085→supabase/postgres:17.6.1.063- Fresh
git clone + ./setup.shlands on PG17 directly — no override files, no special commands
Fixed
setup.shwould have crashed existing PG15 instances on the nextgit pull && ./setup.sh. With the default image flipped to PG17, an unprepared update lets docker compose recreate the db container with the new image, which then refuses to start withFATAL: database files are incompatible with server. Fixed: in update mode,setup.shnow reads/data/PG_VERSIONfrom the existingn8n-claw_db_datavolume, compares to the major version indocker-compose.yml(and anydocker-compose.override.yml), and aborts with a clear message routing the user to./setup.sh --upgrade-pg17if they don't match. Post-migration instances (with override file pinning PG17) match cleanly and proceed normally.
Breaking changes
None. Existing PG15 users see a friendly error on the next update telling them exactly which command to run; their data stays online on PG15 until they explicitly migrate.
Upgrade from v1.5.0
Existing installations (currently on PG15):
cd n8n-claw && git pull
sudo ./setup.sh --upgrade-pg17 # one-shot data migration (3–5 min downtime)A VM-level snapshot (Hetzner / Vultr / DO) before running is strongly recommended. The original PG15 data directory is preserved as ./volumes/db/data.bak.pg15 — keep it for 2–3 days while you verify, then sudo rm -rf it.
Fresh installs:
git clone https://github.com/freddy-schuetz/n8n-claw.git
cd n8n-claw && sudo ./setup.shLands on PG17 directly.
v1.5.0 — Memory that models the user
What's new
Memory in n8n-claw used to be a passive fact store — the agent saved what you said and looked it up later. v1.5.0 turns it into an active model of the user. The agent now extracts behavior patterns, tracks half-finished thoughts, and quietly carries that context into every future conversation.
3 new mechanisms, no schema migration, no breaking changes.
Pattern Extraction (nightly)
- memory-consolidation workflow now runs a second LLM pass after the daily summary — extracts 2–5 behavior patterns, communication styles, and stressors into
category='insight'memories - New patterns are tagged
new,reinforced, orcontradictedagainst the last 7 days of insights - Contradicted insights are flagged
metadata.outdated=trueinstead of being deleted — temporal validity, not destructive overwrite - Uses the same LLM provider as the existing summarize step (Claude, OpenAI, Ollama, etc.)
Open Loops
- New
category='open_loop'for half-finished thoughts the agent picks up from chat ("ich muss noch X prüfen", "vergiss nicht Y") - heartbeat workflow checks for unresolved loops older than 3 days and proactively asks: "Vor X Tagen wolltest du noch: Y. Ist das passiert?"
- Throttled to once every 24h via
heartbeat_config.last_open_loop_check - Closed via
metadata.closed=trueon shallow merge — original content preserved as audit trail
Insight Recall (every turn)
- n8n-claw-agent loads top-3 active insights into the system prompt on every message
- Insights shape behavior silently — the prompt explicitly instructs the model not to quote them
- Cost: ~200–500 extra input tokens per turn
Fixed
- memory_update —
metadatanow uses jsonb shallow merge instead of replace. Previously updating one field wiped the others. - setup.sh — workflow lookup paginates correctly past the first 100; deactivates before delete to avoid orphaned webhook registrations
- scheduled_actions —
[SKIP]marker no longer leaks into agent responses
Breaking changes
None. New category values are additive (no CHECK constraint on memory_long.category). No migration needed.
Upgrade
cd n8n-claw && git pull && ./setup.sh --forceInsights start appearing after the first nightly consolidation run. Open loops trigger after 3 days of inactivity on a topic.
v1.4.0 — Enterprise & Productivity Skills
What's new
The skill catalog now covers the core SaaS stack teams actually run their business on. CRM (HubSpot, Salesforce, Zoho), issue tracking (Jira, Confluence), billing (Stripe), project management (Asana, Airtable) — plus a handful of knowledge, media, and smart-home integrations.
16 new skills. Catalog grows to 64.
CRM & Sales
- HubSpot CRM (28 tools) — Contacts, Companies, Deals, Tickets, Notes, Tasks, Engagements via Private App token
- Salesforce CRM (35 tools) — Leads, Contacts, Accounts, Opportunities, Cases, Tasks; SOQL + SOSL; Client-Credentials OAuth (Connected App)
- Zoho CRM (37 tools) — full CRM +
convert_lead,coql_query,describe_module; Self-Client OAuth with auto-exchange grant code so the setup never leaves the chat; regional endpoints (.com / .eu / .in / .com.au / .jp / .com.cn) - Stripe (23 tools) — Customers, Payments, Subscriptions, Invoices, Products, Prices, Refunds
Productivity & Project Management
- Asana (16 tools) — Tasks, Projects, Sections, Stories, Users, Workspaces; full CRUD
- Jira Cloud (12 tools) + Confluence Cloud (14 tools) — JQL / CQL, transitions, comments, pages, blog posts, attachments; share a single Atlassian API token
- Airtable (7 tools) — Bases, Tables, Records
Knowledge, Finance & Media
- YouTube Data API, Finnhub Stocks, Open Library, Unsplash, OpenAQ Air Quality — free or generous-free-tier APIs for research, market data, books, photos, and air quality
Smart Home, Maps, Messaging
- Home Assistant — device control + a
speaktool that auto-routes to TTS-capable media players for voice output; newsmart-homecategory - Overpass OSM — OpenStreetMap queries with mirror fallback chain (main → de → fr → kumi), a
reverse_geocodetool, and auto-reverse-geocoded names infind_nearbyso the LLM gets street names instead of raw lat/lon; newmapscategory - ntfy — push notifications via ntfy.sh (self-hosted or hosted), with RFC 2047 header encoding so German umlauts in Title/Message survive the trip
Changed
mcp-client— empty strings now accepted for required parameters. Previously the pre-flight schema check rejected the call before the tool could apply its own default handling.- Route-planner moved from
transporttomapsto match the Overpass addition
Breaking changes
None.
Upgrade
cd n8n-claw && git pull && ./setup.sh --forceNo database migration. Install any of the new skills via chat — e.g. install hubspot, install zoho-crm, install jira, install asana, install home-assistant.
v1.3.2 — Discord adapter
💬 Discord as a second chat interface
Adds Discord alongside Telegram via an opt-in sidecar. Single y/N prompt in `setup.sh` — users who skip see nothing else.
What's new
- discord-bridge sidecar (`discord.js` v14 Gateway client + Express `/reply` endpoint) — joins the existing sidecar stack alongside `email-bridge`, `file-bridge`, and `crawl4ai`
- Opt-in via `COMPOSE_PROFILES=discord` — the container is not built or started for users who don't want Discord
- Single-token, single-point-of-trust — only the sidecar holds the Discord bot token; n8n never needs a Discord credential
- Reuses the existing Webhook Adapter path — messages flow through `/webhook/adapter` → agent → Route Response → new Discord Reply node → sidecar → Discord channel
- Per-channel session history (`session_id = discord:`) — isolated Kurzzeit-Kontext, kanalübergreifendes Langzeit-Memory
Setup
- `./setup.sh --force` → answer `y` when asked "Enable Discord as an additional chat interface?"
- Paste the Bot Token from https://discord.com/developers/applications (Bot → Reset Token)
- Enable Message Content Intent (privileged intent) in the Discord Developer Portal
- Invite the bot to your server with `bot` + `applications.commands` scopes
See the "Enabling Discord" section in README.md for the full flow.
Also in this release
- fix(setup): activate Webhook Adapter by default — the adapter was previously imported but never activated, which silently broke Discord, Paperclip, and any generic webhook consumer on every `--force` until the user manually flipped it on in the UI. Slack/Teams triggers inside are node-level disabled and stay dormant, and the generic webhooks are auth-protected via `WEBHOOK_SECRET`, so always-on is safe.
Closes
- #24 (Discord as chat interface)
v1.3.1 — Smarter MCP Tool Calls
What's new
Follow-up to v1.3.0 that fixes the "agent keeps guessing wrong parameter names" problem when talking to external MCP servers through the bridge.
When a bridge-backed tool is called (e.g. DeepWiki's ask_question), the LLM doesn't always know the exact parameter names the external server expects — repoUrl vs repoName, owner/repo vs https://..., and so on. v1.3.0 would pass those guesses through and return the raw pydantic validation error, which the LLM rarely recovered from. It also silently auto-filled missing required parameters with empty strings, which created validation errors on its own.
Schema-hint retry
The inline MCP client now does proper schema-based validation:
- Pre-flight — validates
argskeys against the tool'sinputSchema.propertiesreturned bytools/list(which is already fetched on every call). If the agent passed unknown keys or is missing required ones, the client short-circuits with the full schema as a hint. The roundtrip to the external server is skipped entirely. - Post-call — if the server returns a JSON-RPC error or
isError: true, the schema hint is appended to the error so the LLM can retry correctly. - Fallback — when
tools/listreturns no usable schema (stateless/legacy servers), behavior is identical to v1.3.0.
Applied to all three inline MCP client nodes (main agent, sub-agent runner, background checker).
Changed
- Removed the broken "auto-fill missing required params with empty string" logic from v1.3.0. Schemas are now enforced, not silently papered over.
Breaking changes
None. Native templates (weather-openmeteo, DZT, Gmail, etc.) hit the happy path on the first call, so the new code path never triggers for them. Behavior for auth_type='none' and auth_type='bearer' bridges remains unchanged on success.
Upgrade
cd n8n-claw && git pull && ./setup.sh --forceNo DB migration.