Hi everyone. I’m running self-hosted n8n (v2.21.0) on EasyPanel, single replica, behind Traefik. I use the MCP Server Trigger node (Streamable HTTP) on the /mcp path, with Retell AI as the MCP client.
Short-response tools (Get many events) work perfectly and show up in Executions. But longer-response tools (Create event) return “error parsing json response from mcp server” to the client, and the Create node never executes. The data sent by the client is correct (valid Start/End with timezone).
This started right after I reinstalled the server. Per the n8n docs, this needs proxy buffering and gzip compression disabled for the /mcp endpoint. What’s the correct way to configure this on EasyPanel/Traefik? Any working example of the labels/middleware would be hugely appreciated. Thanks!
@Luis_Morello youve basically nailed the cause, just narrowing it down, its the gzip/compress side specifically, not the buffering. traefiks compress middleware only fires on responses over ~1KB (minResponseBodyBytes defaults to 1024), so your Get-many output slips under that and passes through clean, but the bigger Create response crosses it, gets gzipped, and Retell cant parse the compressed stream so you get “error parsing json” and the node never runs. thats exactly your short-works long-fails split, and it lining up with the reinstall fits too if the proxy defaults came back.
so the fix is just making sure /mcp responses arent gzipped. on easypanel that lives in a custom traefik file at /etc/easypanel/traefik/config/custom.yaml, then restart traefik from settings. the key bit is excluding the mcp content types from compression:
http:
middlewares:
mcp-nocompress:
compress:
excludedContentTypes:
- text/event-stream
- application/json
both types are in there because streamable-HTTP can answer as either one depending on response size, so excluding only event-stream sometimes misses it. cleanest is to make sure /mcp routes through something that uses this (or no compress middleware at all) rather than easypanels default compress.
how are you exposing n8n in easypanel right now, the built-in domain box or your own custom labels? that decides whether you just tweak the existing compress or add a dedicated /mcp router, tell me which and ill give you the exact lines to drop in.
Add the following labels to your n8n service in the EasyPanel → Service → Advanced → Custom Labels section:
traefik.http.middlewares.n8n-mcp-compress.compress=true
traefik.http.middlewares.n8n-mcp-compress.compress.excludedcontenttypes=text/event-stream
This tells Traefik to compress everything except the MCP stream.
traefik.http.middlewares.n8n-mcp-headers.headers.customResponseHeaders.Cache-Control=no-transform
This ensures that no other proxy or cache between Traefik and Retell AI attempts to modify the stream.
Crucial Step: You must find your router name (visible in the Traefik dashboard if you have it, or usually follows a pattern like https-n8n-your-project). However, a common way to apply this in EasyPanel/Traefik is:
traefik.http.routers.n8n-router.middlewares=n8n-mcp-compress,n8n-mcp-headers
(Replace n8n-router with the actual router name used by EasyPanel for your service. If you cannot find the router name, check the “Labels” tab in EasyPanel to see what traefik.http.routers.XXXX.rule is currently set to—the XXXX is your router name.)
Thanks @achamm, that 1KB threshold explanation makes complete sense and matches my short-works/long-fails split exactly. I’m exposing n8n through EasyPanel’s built-in domain box (the auto-generated *.easypanel.host domain), not custom Docker labels — the “Middleware 1” field I found is under Domains → edit → Middlewares on that built-in domain. Single replica, Streamable HTTP on /mcp. Given that setup, what exact lines should I drop into custom.yaml, and how do I make sure /mcp bypasses EasyPanel’s default compress rather than just stacking on top of it? I’d rather not take down the whole domain by guessing. Thanks!
@Luis_Morello yeah stacking another compress there wont do it, the built-in domains middleware applies to every path so traefik still runs the default compress alongside it, thats why /mcp isnt bypassing. since youre single replica and the n8n editor doesnt actually need gzip, the simplest no-downtime fix is to drop compress off that domain entirely instead of fighting it per-path. does that Middlewares field let you clear or replace the default compress, or only add on top of it? thats what decides whether this is a one-field change or a small custom.yaml router just for /mcp.
Thank you @kjooleng, this is really helpful and lines up with the compression diagnosis. Two things I want to make sure I understand before I touch anything, since I’m on EasyPanel’s built-in domain box (not custom router labels) and I’d rather not break the whole domain by guessing:
- The
traefik.http.routers.<router>.middlewares=...line — doesn’t that replace the full middleware list on the router rather than append to it? My worry is that EasyPanel already manages its own middlewares on that router (HTTPS redirect, etc.) behind the scenes, so overwriting the list might drop those. Is there a safe way to add these two middlewares without wiping EasyPanel’s
Thank you @kjooleng, this is really helpful and lines up with the compression diagnosis. Two things I want to make sure I understand before I touch anything, since I’m on EasyPanel’s built-in domain box (not custom router labels) and I’d rather not break the whole domain by guessing:
- The
traefik.http.routers.<router>.middlewares=...line — doesn’t that replace the full middleware list on the router rather than append to it? My worry is that EasyPanel already manages its own middlewares on that router (HTTPS redirect, etc.) behind the scenes, so overwriting the list might drop those. Is there a safe way to add these two middlewares without wiping EasyPanel’s managed ones? - @achamm mentioned that n8n’s Streamable HTTP can answer as either
text/event-streamorapplication/jsondepending on response size, and suggested excluding both content types. Your snippet only excludestext/event-stream— would it be safer to addapplication/jsontoexcludedcontenttypesas well?
I really like the Cache-Control: no-transform header idea, I’ll keep that regardless. Just want to get the router part right so I don’t take the domain down. Thanks again!
@Luis_Morello youre right to worry, the .middlewares= line sets the whole ordered list for that router, its not an append, so overwriting it on easypanels managed router would drop their https-redirect and anything else they put there. thats exactly why id leave that routers middleware chain alone on the built-in domain. safest is a separate higher-priority router for /mcp in custom.yaml that doesnt touch easypanels router at all, /mcp just matches yours first with no compress and every other path keeps their managed chain untouched. if you paste your n8n service name (easypanel shows it in the service config) i can write you that exact router block.
Based on your concerns, here are the exact labels to use.
Step A: Define the Middlewares (These are safe; they don’t overwrite anything)
traefik.http.middlewares.n8n-mcp-compress.compress=true
traefik.http.middlewares.n8n-mcp-compress.compress.excludedcontenttypes=text/event-stream,application/json
traefik.http.middlewares.n8n-mcp-headers.headers.customResponseHeaders.Cache-Control=no-transform
Step B: Attach to Router (The “Caution” Step) Check your existing labels. If you see traefik.http.routers.XYZ.middlewares=ABC, use:
traefik.http.routers.XYZ.middlewares=ABC,n8n-mcp-compress,n8n-mcp-headers
One final check: After you deploy, if you want to be 100% sure it’s working, use a curl command on a tool that you know returns a “long” response: curl -I -H "Accept: application/json" https://your-n8n-domain.com/mcp/your-tool-path Look for the Content-Encoding header. If it says gzip, the middleware isn’t attached correctly. If that header is missing, you’ve won.
Hey @Luis_Morello, since you’re on EasyPanel’s built-in domain and @achamm confirmed a separate /mcp router is the safest path, here’s the exact custom.yaml block to drop into /etc/easypanel/traefik/config/
http:
middlewares:
mcp-nocompress:
compress:
excludedContentTypes:
- text/event-stream
- application/json
mcp-notransform:
headers:
customResponseHeaders:
Cache-Control: "no-transform"
routers:
n8n-mcp:
rule: "Host(`your-instance.easypanel.host`) && PathPrefix(`/mcp`)"
priority: 100
service: "your-n8n-service@docker"
middlewares:
- mcp-nocompress
- mcp-notransform
tls: {}
Replace your-instance.easypanel.host with your actual domain and your-n8n-service@docker with the service name shown in EasyPanel (usually -@docker). The priority: 100 ensures this router matches /mcp first, before EasyPanel’s managed router picks it up, so their HTTPS redirect and other middlewares stay completely untouched.
After saving, restart Traefik from EasyPanel Settings, then run @kjooleng curl -I check to confirm Content-Encoding: gzip is gone from the response.
Closing this out — it turned out NOT to be a Traefik issue. I verified with wget that the MCP endpoint returned identical responses internally (localhost:5678) and externally (public URL through Traefik): same text/event-stream, chunked, no gzip, no truncation. The real cause was on the Retell side — my phone number was pinned to an old agent version that still used a dead n8n URL, so real calls hit a 404 on the MCP handshake. Re-linking the number to the current published version fixed it. No Traefik changes were needed. Thanks for the pointers!