Skip to content

Unreachable local MCP server silently hides all file-based commands from the TUI palette #36288

Closed as not planned

Description

@dcaixinha

Description

When a configured local MCP server is unreachable at startup (its command connects to a service that isn't running), the TUI's slash-command / ctrl+p command palette silently drops all file-based custom commands — only built-in commands (/init, /help, /review, …) are shown.

The commands are actually loaded correctly by the server: the GET /command endpoint returns them in full (name, description, agent, model, template). The failure is purely in the TUI's command-list population, and it is triggered by the failing MCP server, not by anything about the commands themselves.

Reproduction

  1. Configure a local MCP server that points at a service which is not running, e.g.:

    {
      "$schema": "https://opencode.ai/config.json",
      "mcp": {
        "tidewave": {
          "type": "local",
          "enabled": true,
          "command": ["/path/to/mcp-proxy", "http://localhost:4000/tidewave/mcp"]
        }
      }
    }

    (Here the proxy targets a Phoenix dev server on localhost:4000 that is currently down.)

  2. Add any file-based custom command, e.g. ~/.config/opencode/commands/zz-test.md:

    ---
    description: throwaway test command
    ---
    This is a test.
  3. Launch the TUI in a project where that MCP config applies. Open the command
    palette (/ or ctrl+p) and search for the command.

Expected: zz-test appears in the palette.
Actual: Only built-in commands appear. zz-test (and every other file-based command) is missing. The log shows repeated message="server unavailable" key=<mcp> type=local status=failed.

Confirmation that the command is loaded (server is fine)

Running opencode serve and querying the API returns the command regardless of MCP state:

$ curl -s localhost:PORT/command | jq '.[].name'
"init"
"review"
"zz-test"          # present in API
...

Only the TUI palette omits it.

Workaround

Disabling the unreachable MCP server makes all file-based commands reappear immediately:

OPENCODE_CONFIG_CONTENT='{"$schema":"https://opencode.ai/config.json","mcp":{"tidewave":{"enabled":false}}}' opencode

or set "enabled": false for the offending server.

Impact

A single unreachable local MCP server takes out the entire custom-command palette in the TUI, with no error surfaced in the UI — only a WARN server unavailable line in the log. This is very hard to diagnose (the commands load fine via the API, so it looks like a command-loading problem when it is actually MCP startup blocking/failing the TUI palette).

A failing MCP server should degrade gracefully: its own tools/prompts can be omitted, but built-in and file-based commands should still populate.

Environment

  • opencode: 1.17.18 (also reproduced on 1.17.13)
  • Install: opencode-bin (AUR)
  • OS: Arch Linux, kernel 7.1.2-arch3-1, x86_64

Activity

  1. dcaixinha commented on Jul 10, 2026

    @dcaixinha
    Author

    Follow-up: in my case the offending server was configured as type: local running a stdio MCP proxy binary (mcp-proxy <url>). When the upstream service was down, the proxy process was spawned but its stdio handshake never completed, and that hang is what wiped the file-based commands from the TUI palette.

    Switching the same server to the native type: remote transport ("type": "remote", "url": "http://localhost:PORT/...") fixed it completely: with the service down the remote connection fails fast and the palette populates normally; with it up, the server connects and its tools appear.

    So the blocking appears to be specific to a local stdio server that hangs during handshake, rather than MCP failure in general. A hung/slow local MCP handshake should still not block built-in/file-based command population in the TUI.

  2. RenanMsV commented on Jul 28, 2026

    @RenanMsV

    Can confirm that these commands can become unavailable in OpenCode 1.18.9.

    My local stdio MCP server is enabled in opencode.json, but the server itself isn't running. Commands such as /init do not appear.

    After marking that MCP configuration as Disabled and restarting OpenCode, the /init command reappears.

    {
      "$schema": "https://opencode.ai/config.json",
      "mcp": {
        "my-mcp-server": {
          "type": "remote",
          "url": "http://localhost:5858/sse",
          "enabled": true
        }
      }
    }
  3. luochen1990 commented on Sep 12, 2026

    @luochen1990
    Contributor

    Same root cause here — confirmed by measurement: Command.init awaits mcp.prompts(), and the MCP InstanceState init blocks until every enabled server settles (30s timeout each), so GET /command doesn't return until then. With a slow-but-eventually-connecting server you get a multi-second delay (5.6s measured with 9 servers); with a server whose handshake never completes, the palette stays empty until timeout — which matches what you're seeing.

    I've opened #48630, which makes /command return file-based commands immediately and merge MCP prompts asynchronously via a command.updated event. An unreachable server no longer holds file commands hostage, so this case should be covered too. Would appreciate if you could test it against your repro.

  4. thdxr commented on Oct 11, 2026

    @thdxr
    Member

    Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.

    — from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊

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

Metadata

Metadata

Assignees

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