Skip to content

mcp: server stays "connected" while tool calls fail with 401 after re-authentication #53942

Open

Description

@vvo

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

  1. Configure a remote OAuth MCP server and sign in. It shows as connected.
  2. 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.
  3. 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 successful mcp oauth request ... operation=refresh (200), then another 401, then failed to call MCP tool.
  • The connection status stays connected for 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 reported status.status=failed, then needs_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/call never 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> then opencode mcp auth <server>.

Activity

  1. opencode-agent commented on Oct 8, 2026

    @opencode-agent
    Contributor

    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.

    • Every tool call fails with Server returned 401 after re-authentication (HTTP 401).
    • The server status (/mcps and the status API) stays Connected.
    • Each failing call does a new refresh_token grant, then fails again.

    It still happens on the latest v2 branch (0621ea9). In the code, the server status is only updated during connect: auth failures during tools/call are returned to the model as a tool error and never change the status to needs_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> then opencode mcp auth <server>) is the way to recover for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions