Skip to content

mcp: opencode_console 403 - console refused access to the workspace, silent reconnect every ~6s #59806

Open

Description

@GHR-STEAM

Summary

The opencode_console MCP server (HTTP + OAuth) is refused for the session workspace with 403 {"error":"forbidden","message":"The console refused access to the workspace."}. opencode then reconnects roughly every 6 seconds for several minutes and never surfaces an actionable error to the user — the failure only exists in the log.

Environment

  • opencode version: 2.2.0 (opencode v2.2.0), desktop build (%LOCALAPPDATA%\Programs\@opencode-aidesktop, app.asar)
  • OS: Microsoft Windows NT 10.0.26300.0 — Windows 11 Pro
  • Terminal: PowerShell 5.1.26100.9807 inside the opencode desktop app (TERM=xterm-256color, TERM_PROGRAM and COLORTERM unset)
  • Shell: C:\WINDOWS\system32\cmd.exe
  • Install/channel: latest (log line: message="cli starting" version=2.2.0 channel=latest local=false)
  • Active plugins: Unavailable — reading ~/.config/opencode/opencode.json* is excluded by a local policy; no files exist under ~/.config/opencode/plugin or ~/.opencode/plugin

Reproduction

  1. Configure the opencode_console MCP server over HTTP with OAuth in the user config.
  2. Open a session whose workspace directory is the Windows home directory (C:\Users\<user>).
  3. Start opencode (or let it reconnect after startup).

Expected Behavior

One clear warning that the console refused this workspace, then either a bounded backoff or no further retries — and a user-visible message that the MCP server is unavailable for this workspace.

Actual Behavior

Every cycle performs OAuth, is rejected with 403, and the connect is retried ~6 s later. 14 cycles in a single run, still retrying ~10 minutes later. Nothing is shown to the user.

Trimmed log lines:

timestamp=2026-10-28T02:01:22.896Z level=WARN message="mcp http authentication rejected" status=403
  server=opencode_console directory="C:\\Users\\<user>"
timestamp=2026-10-28T02:01:22.901Z level=WARN message="mcp transport error" server=opencode_console
  error="Error POSTing to endpoint: {\"error\":\"forbidden\",\"message\":\"The console refused access to the workspace.\"} (HTTP 403)"
  http.span=345435
timestamp=2026-10-28T02:01:22.904Z level=WARN message="mcp connect failed" server=opencode_console
  status.status=failed status.error="Error POSTing to endpoint: {..forbidden..console refused access to the workspace..} (HTTP 403)"

Cycle timestamps in one run (all identical failures):

02:01:22  02:01:23  02:01:29  02:01:35  02:01:41  02:01:59  02:04:15  02:11:28

An earlier cycle in the same run shows the OAuth path being taken first:

level=WARN message="mcp http authentication rejected" status=401
  server=opencode_console methodID=mcp_... oauthAttemptID=...

The same workspace is also probed as a subdirectory (directory="C:\\Users\\<user>\\data", 2 of the 14 refusals), so the refusal is not limited to the home directory itself.

Additional Context

  • The refusal is account-level, not workspace-level: the same 403 was reproduced from three different working directories (~, ~\data, and a scratch dir under %LOCALAPPDATA%\Temp). The token itself is fine — the OAuth round trip returns 200 and a refresh token, then the very next POST is refused. So the directory="..." attribute in the log is misleading; it looks like a local path problem but is not.
  • Auth works from the UI at /mcps only. opencode mcp auth from the terminal opens a browser and then waits forever, never completing.
  • Workaround that stops the silent loop: opencode mcp logout opencode_console. Afterwards opencode mcp list no longer shows the server retrying; a healthy connect would show connected.
  • No model/provider failures in the same period: the last "stream error" in the log predates this run by more than two weeks, and a live generation against the active opencode/*-free model succeeded while this was happening. This is isolated to MCP.
  • A second, probably unrelated startup bug: message="failed to sync GitHub Copilot models" cause="Error: Failed to fetch Copilot models: 401" fires on every startup (61 occurrences in this log) when the Copilot provider is configured but not authenticated. Worth suppressing or reporting separately.
  • Frequency: 100% reproducible on this workspace; it stops only when the app is restarted.
  • Workaround tried: none yet. Disabling the opencode_console server locally would stop the retry loop but loses the MCP tools.

Activity

  1. opencodejr commented on Oct 28, 2026

    @opencodejr

    Thanks for the detailed report and logs. I tried to reproduce this on v2.2.0 with a mock remote MCP server that sends back exactly the console's response (403 {"error":"forbidden","message":"The console refused access to the workspace."}). I tested it with and without an OAuth flow in front (401, discovery, registration, token with a refresh token, then 403 on every authenticated request).

    In every case OpenCode logged the same three lines you posted (mcp http authentication rejected status=403, mcp transport error, mcp connect failed) once. It then left the server as failed and never retried, even after several minutes. opencode mcp list showed ✗ … failed: … (HTTP 403). Opening a subdirectory as a new workspace caused one more attempt, which matches the ~ / ~\data entries in your log, but it did not loop either.

    The server on its own doesn't retry a failed MCP connection on a timer, so something on your side seems to be starting each new attempt. I tested with opencode serve on Linux, not the Windows desktop app, so it may be specific to the desktop app. These would help narrow it down:

    1. One full retry cycle from the log, unedited apart from personal details, plus the lines just before it. Lines mentioning credential created / credential activated, location services booted, mcp oauth request … or any HTTP request to the MCP endpoints would be especially useful.
    2. Whether the loop also happens with the CLI (opencode in a terminal, desktop app closed), or only in the desktop app.
    3. What was open in the app while it was retrying (for example the /mcps page, or several sessions or projects).
    4. Your MCP server config entry for opencode_console, with any secrets removed.

    Related issues:

    You can reply here with the details, or edit the issue. If you edit it, please also leave a comment saying you've updated it.

  2. GHR-STEAM commented on Oct 28, 2026

    @GHR-STEAM
    Author

    Corrections from a closer log read. The behaviour below is reproducible from the exact lines quoted; the counts in the original report were off.

    1. OAuth succeeds once — this is not an auth loop. 02:00:59.411 mcp oauth authorization started → 02:01:22.506 mcp oauth authorization completed hasRefreshToken=true expiresIn=2591999. During the whole retry cluster that follows (02:01–02:19) there is no further authorization attempt: every request reuses that stored token and is refused. So a credential that is apparently valid is rejected by the server, and the client keeps reconnecting.

      (Two later oauth authorization started lines do exist — 02:20:26.723 and 02:21:58.723, i.e. after logout — but neither completed; both ended in 401 needs_auth.)

    2. Nine rejected attempts, not fourteen:
      02:01:22.896, 02:01:23.201, 02:01:29.894, 02:01:35.524, 02:01:41.814, 02:01:59.830, 02:04:15.587, 02:14:34.473, 02:19:09.925
      The 14 came from counting the paired WARN lines — each attempt emits mcp http authentication rejected, mcp transport error and mcp connect failed for a single request.

    3. 02:11:28 is not an MCP cycle. It is a message="spawning process" line from an unrelated shell command and should be dropped from the list.

    4. The interval is not a fixed ~6 s loop: 0.3 s, 6.7 s, 5.6 s, 6.3 s, 18 s, 136 s, 619 s, then 275 s. It grows, then resets. Retries continue for ~18 minutes rather than converging, and nothing is surfaced to the user — no toast, no banner, no state change beyond the initial connecting.

    5. ~\data accounts for 1 of the 9 refusals (02:01:23.201), not 2 of 14.

    6. The refusal is workspace-scoped, not a dead credential. The same stored credential is accepted for inference: opencode run -m opencode/deepseek-v4.1-flash-free returns normally. It is only the workspace-scoped MCP endpoint at /console/mcp that answers 403 {"error":"forbidden","message":"The console refused access to the workspace."}. That rules out "the token is simply expired/invalid" and points at workspace authorisation for the MCP endpoint.

    The defect stands: 403 is treated as retryable, retries back off but never stop within the session, and the failure is not surfaced.

    Workaround on this machine: after opencode mcp logout opencode_console, opencode mcp list reports needs authentication and no further 403 is logged — verified: the last one is 02:19:09.925Z, and none appear afterwards. That matches the state described in the report; the earlier "stops only when the app is restarted" line was wrong.

    (Side note: this account has author_association: NONE, so labels could not be applied at filing time.)

  3. opencodejr commented on Oct 31, 2026

    @opencodejr

    Closing this for now since we haven't heard back. When we tested v2.2.0 against a mock server returning the same 403 forbidden response, OpenCode tried to connect once per workspace, marked the server as failed and didn't retry. We couldn't reproduce the reconnect every ~6 seconds, and without the details we asked for we can't tell what starts each new attempt in your setup.

    If it still happens, please reopen this issue or open a new one with:

    • one full, unedited retry cycle from the log, plus the lines just before it
    • whether it also happens with the CLI while the desktop app is closed
    • your opencode_console config entry, with any secrets removed

    Thanks for the detailed report.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions