You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
mcp: ?codemode=false is appended to remote MCP URLs; Google's Workspace MCP servers return 404 for it #55336
For every remote MCP server without codemode: false, opencode adds ?codemode=false to the configured URL before it connects. Google's hosted Workspace MCP servers (gmailmcp.googleapis.com, drivemcp.googleapis.com, calendarmcp.googleapis.com) return HTTP 404 for any URL with that query string. On /mcp/v1, the 404 is Google's HTML error page.
The connect path catches 400/404 and retries the original URL, so the servers do connect. But:
every connect and reconnect makes an extra failing request first, and logs a large mcp transport error with the full HTML 404 page for each Google server;
the fallback covers only 400 and 404. A server that answers an unknown query string differently, for example with 401/403 or a redirect, gets the modified URL with no fallback;
the URL the user configured is not the URL opencode calls. This is surprising and is not in the MCP docs;
Start opencode and check ~/.local/share/opencode/log/opencode.log:
message="mcp transport error" server=google-gmail error="Error POSTing to endpoint: <!DOCTYPE html> … The requested URL <code>/mcp/v1?codemode=false</code> was not found on this server. … (HTTP 404)"
Direct check with a valid token: POST https://gmailmcp.googleapis.com/mcp/v1 (initialize) returns 200, and POST https://gmailmcp.googleapis.com/mcp/v1?codemode=false returns 404.
Expected
Do not change user-configured URLs. If servers need the Code Mode hint, send it in a header, which servers ignore when they do not know it, or as an MCP capability. At minimum, do not log the full HTML body for the expected fallback.
Thanks for the detailed report. I reproduced this with a local mock MCP server standing in for Google's: it serves /mcp/v1 normally and rejects any URL with a query string.
Mock returns 404: opencode's first request is POST /mcp/v1?codemode=false. The log gets a mcp transport error with the whole HTML 404 page, then opencode retries the configured /mcp/v1 and connects.
Mock returns 403: only POST /mcp/v1?codemode=false is sent and the connection fails (mcp connect failed ... HTTP 403). The configured URL is never tried.
This happens on 2.0.28 and still happens on the latest dev (3a69bae). The script below reproduces both cases.
The triage comment above shows the 403 failure. When the server sends 403 for the ?codemode=false request, opencode does not retry the configured URL, and the connection fails. When the server sends 400 or 404, opencode retries the configured URL and connects.
Two fixes are possible:
Add 403 to the retry statuses for the configured URL.
Keep the configured URL unchanged. Send the Code Mode hint in a different way, for example in a request header. Servers ignore unknown headers.
The test "does not retry MCP beyond the query fallback" in packages/core/test/mcp.test.ts sets 403 to one attempt. Thus, the current behavior can be intentional. Which fix is preferred? A PR can follow the decision.
Yeah we tested quite a few mcp servers (30+ of major ones) and didn't find any that had issues w/ the extra param. We send that param because some servers actually respect it, it's not quite a standard yet tho, so for now for best experience (unless we can show that majority of major servers actually reject this param) we will do explicit blacklisting to prevent it from being sent and wasting time. So for now I think not sending it to servers w/ .google.apis is sufficient.
Ofc you can completely prevent it by adding codemode: false to your mcp server config (which DOESNT send the parameter) it makes it so the mcp server tools are available as is. The codemode=false query param is to tell mcp servers DO NOT implement codemode on your end, let the client own codemode instead.
Activity
opencode-agent commentedon Oct 14, 2026
Thanks for the detailed report. I reproduced this with a local mock MCP server standing in for Google's: it serves
/mcp/v1normally and rejects any URL with a query string.POST /mcp/v1?codemode=false. The log gets amcp transport errorwith the whole HTML 404 page, then opencode retries the configured/mcp/v1and connects.POST /mcp/v1?codemode=falseis sent and the connection fails (mcp connect failed ... HTTP 403). The configured URL is never tried.This happens on 2.0.28 and still happens on the latest
dev(3a69bae). The script below reproduces both cases.Related:
codemode: falseis ignored: server tools stay behindexecute(2.0.25–2.0.28,opencode acp) #55079:codemode: falseis ignored in some paths.Reproduction script (repro.sh)
Run it:
bash repro.shjethac commentedon Oct 15, 2026
The triage comment above shows the 403 failure. When the server sends 403 for the
?codemode=falserequest, opencode does not retry the configured URL, and the connection fails. When the server sends 400 or 404, opencode retries the configured URL and connects.Two fixes are possible:
The test "does not retry MCP beyond the query fallback" in
packages/core/test/mcp.test.tssets 403 to one attempt. Thus, the current behavior can be intentional. Which fix is preferred? A PR can follow the decision.rekram1-node commentedon Oct 15, 2026
Yeah we tested quite a few mcp servers (30+ of major ones) and didn't find any that had issues w/ the extra param. We send that param because some servers actually respect it, it's not quite a standard yet tho, so for now for best experience (unless we can show that majority of major servers actually reject this param) we will do explicit blacklisting to prevent it from being sent and wasting time. So for now I think not sending it to servers w/
.google.apisis sufficient.Ofc you can completely prevent it by adding
codemode: falseto your mcp server config (which DOESNT send the parameter) it makes it so the mcp server tools are available as is. Thecodemode=falsequery param is to tell mcp servers DO NOT implement codemode on your end, let the client own codemode instead.