Repository navigation
Open
Labels
Description
Summary
When a remote MCP server keeps rejecting tokens after a successful OAuth refresh, every tool call fails with Server returned 401 after re-authentication (HTTP 401), but /mcps and the sidebar keep showing the server as Connected. The user gets no signal that they need to sign in again. Only the model sees the error.
Environment
- opencode version: 2.0.25
- OS: Darwin 25.6.0 (darwin arm64)
- Terminal: iTerm.app (TERM=xterm-256color, COLORTERM=truecolor)
- Shell: /bin/zsh
- Install/channel: latest (Homebrew
anomalyco/tap/opencode-v2) - Active plugins: none found in config
Reproduction
- Configure a remote OAuth MCP server and sign in. It shows as connected.
- Make the server reject the current access token while the refresh token stays valid. In our case the server accepted the token but the identity behind it lost a required claim, so every new access token was rejected too.
- Call any tool on that server.
Expected Behavior
After 401 after re-authentication, the server status changes to needs_auth (or failed) and the UI shows it, like it does when the failure happens during connect. Ideally OpenCode stops refreshing on every call once it knows a refresh does not help.
Actual Behavior
- Each tool call logs
mcp http authentication rejected status=401, then a successfulmcp oauth request ... operation=refresh(200), then another 401, thenfailed to call MCP tool. - The connection status stays
connectedfor the whole time. We saw this for about 35 minutes (10:48 to 11:24 UTC) across several sessions. - The status only changed after
opencode mcp logout <server>, when the reconnect hit the same 401 and reportedstatus.status=failed, thenneeds_auth.
Redacted log excerpt:
11:24:29.581Z WARN mcp http authentication rejected status=401 server=example-mcp
11:24:29.582Z INFO mcp oauth request started operation=refresh origin=https://auth.example.com
11:24:29.812Z INFO mcp oauth request succeeded status=200 operation=refresh
11:24:30.227Z WARN mcp http authentication rejected status=401 server=example-mcp
11:24:30.228Z WARN mcp transport error error="Server returned 401 after re-authentication (HTTP 401)"
11:24:30.228Z WARN failed to call MCP tool server=example-mcp
... (status still "connected" in /mcps)
11:25:17.834Z WARN mcp connect failed status.status=failed status.error="Server returned 401 after re-authentication (HTTP 401)"
Additional Context
- Status seems to update only on (re)connect. Auth failures during
tools/callnever feed back into it. - Each failing call also triggers a fresh refresh request, so a broken server gets a token refresh on every call.
- Workaround:
opencode mcp logout <server>thenopencode mcp auth <server>.
Reacted by Clayton Matulich and rboegheim
Activity
opencode-agent commentedon Oct 8, 2026
Thanks for the detailed report. I was able to reproduce this on 2.0.25.
Setup: a local OAuth-protected MCP server. After a successful login, it starts returning 401 for every access token while its refresh endpoint keeps issuing new tokens.
Server returned 401 after re-authentication (HTTP 401)./mcpsand the status API) stays Connected.refresh_tokengrant, then fails again.It still happens on the latest
v2branch (0621ea9). In the code, the server status is only updated during connect: auth failures duringtools/callare returned to the model as a tool error and never change the status toneeds_auth/failed.Related: #53804 (a server with no stored credentials also shows as connected) and #53468 (OAuth for servers that only return 401 on
tools/call).Your workaround (
opencode mcp logout <server>thenopencode mcp auth <server>) is the way to recover for now.fix(mcp): mark a server needs_auth when a tool call is rejected with 401