Exposes self-hosted n8n chat agents behind /v1/chat/completions and /v1/models. Model -> n8n webhook routing via a GenServer registry, so multiple agents map to multiple models. Plug + Bandit, req for the n8n webhook call, Bearer auth (ADAPTER_API_KEY). Ships a flake.nix (beamPackages.mixRelease) so it can be consumed as a NixOS flake input.
2.4 KiB
n8n-openai-adapter
An OpenAI-compatible HTTP adapter that exposes self-hosted n8n chat agents
behind a standard /v1/chat/completions API, so any OpenAI client (Cursor,
LibreChat, the openai SDK, a custom app) can talk to your n8n agents as if
they were OpenAI models.
n8n itself does not ship an inbound OpenAI-compatible endpoint (its "AI
Gateway" is an outbound proxy to n8n Cloud). This small Elixir service is the
bridge: one /v1/chat/completions endpoint, routed to whichever n8n agent you
name in the model field.
How it works
Your OpenAI client
POST /v1/chat/completions {"model":"scholar-agent","thread_id":"abc","messages":[...]}
|
v
n8n-openai-adapter (Plug + Bandit)
- authorize (Bearer <ADAPTER_API_KEY>)
- look up "scholar-agent" -> n8n chat webhook URL (AgentRegistry GenServer)
- take the last user message
- forward to the n8n webhook {sessionId: thread_id, action: sendMessage, chatInput}
|
v
n8n agent (its MCP tools, memory, etc. run as usual)
|
v
returns OpenAI-shaped {"choices":[{"message":{"role":"assistant","content":...}}]}
Multiple agents = multiple model names, each mapped to a different n8n webhook
in the AGENTS env var.
Configuration (env vars)
| Var | Required | Purpose |
|---|---|---|
AGENTS |
yes | JSON map of model -> n8n chat webhook URL. e.g. {"scholar-agent":"https://..."} |
ADAPTER_API_KEY |
yes | Bearer key that OpenAI clients send. |
PORT |
no | HTTP port (default 8000). |
CHAT_WEBHOOK_BASIC |
no | "user:password" if your n8n Chat Trigger is Basic-auth protected. |
Building & running
mix deps.get
mix compile
ADAPTER_API_KEY=secret AGENTS='{"scholar-agent":"https://n8n.bueso.eu/webhook/<id>/chat"}' \
PORT=8000 mix run --no-halt
Testing
MIX_ENV=test mix test
Nix
The repo ships a flake.nix exporting overlays.default and a packages.default
(the packaged BEAM release), so it can be consumed as a flake input from your
NixOS config just like any other flake — e.g.:
inputs.n8n-openai-adapter.url = "git+https://gitea.bueso.eu/<owner>/n8n-openai-adapter";