Files
n8n-io__skills/opencode
liamdmcgarrigle 207637a9e0 Merge main; rework OpenCode plugin for desktop/CLI loading and one-line install
Fixes Node (desktop app) loading, derives hook matchers from hooks.json, self-registers skills via the config hook, and splits install docs into CLI and desktop paths.
2026-08-21 18:22:52 -04:00
..

OpenCode Plugin for n8n Skills

This plugin bridges the n8n-skills bash hooks into OpenCode's plugin event system, achieving feature parity with the Claude Code and Codex plugins.

What it does

  • Registers the bundled skills/ directory with OpenCode via the config hook, so the n8n capability skills are discoverable without a manual skills.paths entry
  • Injects the using-n8n-skills-official meta-skill into the system prompt on every LLM call, so the agent always has the n8n skill protocol in context
  • Survives compaction: the meta-skill is injected into compaction context so it persists across context compression
  • Appends hook reminders to n8n MCP tool results: after each n8n MCP tool call, the corresponding bash hook script fires and its reminder is appended to the tool output

Prerequisites

  • An n8n instance with the instance-level MCP server enabled (setup guide)
  • OpenCode (plugin event names verified against @opencode-ai/plugin 1.4.10 / OpenCode 1.18.15)
  • bash and jq available on the system

Two events used (experimental.chat.system.transform, experimental.session.compacting) are on OpenCode's experimental plugin surface and may change between versions. If skill injection stops working after an OpenCode upgrade, check these event names against your installed @opencode-ai/plugin.

Installation

See the main README for install steps. The OpenCode CLI (one-line config entry) and the desktop app (clone plus a symlink into the plugins folder) install differently.

How it works

The plugin is glue code. All actual hook logic (node-specific warnings, antipattern detection, skill routing) stays in the existing hooks/ bash scripts maintained by the n8n team.

OpenCode event n8n hook equivalent What happens
config (install-time setup) Bundled skills/ dir pushed into config.skills.paths so skills are discoverable
experimental.chat.system.transform SessionStart Meta-skill injected into system prompt on every LLM call
experimental.session.compacting SessionStart (compact) Meta-skill injected into compaction context
tool.execute.after PreToolUse + PostToolUse Bash hook scripts fire after n8n MCP tool calls, reminders appended to tool output

Tool name matching

The plugin derives the tool-name suffixes and their hook scripts from hooks/hooks.json (the same source of truth Claude Code and Codex use), so a new hook added there fires in OpenCode too without editing the plugin. It matches a suffix like validate_workflow against the tool name rather than hardcoding an MCP server prefix, since server names are user-configurable in OpenCode.

The connected n8n MCP server must be named with n8n in it (the default). The suffixes (update_workflow, execute_workflow, etc.) also appear on unrelated CI-automation MCP servers, so the plugin requires n8n in the tool name to avoid firing on the wrong tools. If your server is named without n8n, no hooks fire.

Path resolution

The plugin resolves the repo root from its own file location via dirname(fileURLToPath(import.meta.url)), which works on both runtimes OpenCode uses: the CLI (Bun) and the desktop app (Node/Electron). It deliberately avoids Bun's import.meta.dir, which is undefined under Node and would throw at load, silently disabling the plugin. Both runtimes resolve the module URL through any symlink to the real file, so the root points at the actual install, not the symlink.

MCP tool output shapes

OpenCode passes different output object shapes to tool.execute.after depending on the tool type: built-in tools get { output: string }, but MCP tools get { content: [{type, text}] } (the raw MCP CallResult). The plugin's appendToOutput() helper detects which shape is present and appends text accordingly. Without this, output.output += "..." silently fails for MCP tools because output.output is undefined.

Silent failure

All hook calls use spawnSync with a 10-second timeout and are wrapped in try/catch. If a hook script fails (missing jq, file permissions, timeout, etc.), the tool result passes through unmodified. Hook errors never block tool execution.

Updating

CLI install: if you pinned a version (...skills.git#v1.2.0), bump it in opencode.jsonc and restart. If you tracked the branch unpinned, clear the cached package and restart to re-resolve:

rm -rf ~/.cache/opencode/packages/n8n-skills@git+*

Desktop (symlink) install: git pull in your clone. Either way, no plugin edits are needed when n8n changes a hook's warnings or adds a new hook to hooks/hooks.json: the plugin reads that file at load and shells out to the bash scripts, so hooks/ stays the single source of truth.