The n8n AI Agent Node That Was Missing Its Connectors


This one is a short debugging note rather than a guide. I lost time to it, the wrong answer was extremely convincing, and the real cause was somewhere I was not looking.
I was self-hosting n8n. I dropped an AI Agent node onto the canvas and it did not look like the AI Agent node in any tutorial or template I had seen. Those had several connection points underneath, the ones you attach a chat model, memory and tools to. Mine had essentially one output. I could not wire it up the way every example showed, because the places you wire it into were not there.
The explanation that sounded right
My first thought was that I was on the free self-hosted version and this was a paid feature. My second was that n8n had changed the node in a recent release and the tutorials were stale.
That second one held up well. n8n moves quickly, tutorials go out of date fast, and the AI nodes in particular have been reworked more than once. I searched, and the answer I kept getting back, including from ChatGPT, was a version of the same thing: nothing is wrong, n8n simplified the AI Agent node, connect everything through the new single input.
It is a good explanation. It is coherent, it matches how the project actually behaves, and it would have been true at other points in n8n's history. I believed it for a while.
It was wrong.
Why I kept going
What stopped me accepting it was that the node did not just look different, it did not work like a working AI Agent node either. A redesign gives you a different way to connect things. This gave me no way to connect them. Those are not the same observation, and the explanation only covered the first one.
That gap is the only reason I carried on. Not because I suspected the real cause, which I could not have guessed, but because the story I had been given did not account for what was in front of me.
What it actually was
Eventually I found someone else who had hit the same thing, and their root cause had nothing to do with the AI Agent node, or n8n's version, or the licence tier.
It was their reverse proxy. Specifically, an overly restrictive Content-Security-Policy header that was preventing parts of the n8n editor from rendering. The connectors were not redesigned away. The browser was being told not to run the thing that drew them.
That got my attention immediately, because my n8n was also self-hosted behind a proxy.
The detail from their write-up that I would not have predicted: relaxing the policy was not enough. They tried loosening it, including unsafe-inline and frame-ancestors 'self', and the connectors still did not appear. It was removing the offending header entirely that brought the UI back.
There is a detail in n8n's own documentation that makes this easier to reason about after the fact. n8n exposes N8N_CONTENT_SECURITY_POLICY, described as setting "Content-Security-Policy headers as helmet.js nested directives object", and its default is {}. Empty. So out of the box n8n is not sending you a CSP at all. If your browser is receiving one, it came from somewhere else in the chain, which on a self-hosted box means your proxy, or something in front of it.
What I take from it
Two things, and the second is the one that actually cost me the time.
When a self-hosted web application looks partly broken, rather than down, widen the search past the application. Nginx, Caddy, Traefik, a CDN, a security header set by someone else's hardening guide. The application is the thing you are looking at, so it is the thing you suspect, and a UI that renders at ninety per cent looks like a bug in the ninety per cent rather than interference from outside it.
And a plausible explanation is not a diagnosis. The version-change answer was reasonable, widely repeated, and consistent with how n8n behaves. It just did not account for everything I could see. That is the test I should have applied sooner: not "does this sound right" but "does this explain all of it". If part of what you are observing sits outside the explanation, you do not have the explanation yet.
We hit the same shape of problem in voice work often enough that it is almost a house rule now. The advice everyone repeats is usually right for the case it came from and silently wrong for yours, which is why returning HTTP 200 on a failed tool call is correct on one Vapi tool type and destroys your only failure signal on the other. Same lesson, different layer.