Skip to content

MCP codemode: false is ignored: server tools stay behind execute (2.0.25–2.0.28, opencode acp) #55079

Closed as not planned

Description

@Twonster

Versions: opencode 2.0.25 (Homebrew), 2.0.27 (@opencode/cli-darwin-arm64) and 2.0.28 (@opencode/cli-darwin-x64 under Rosetta — @opencode/[email protected] is referenced by @opencode/[email protected] but not published on npm yet), macOS arm64. Model: Ollama qwen3.5:35b-a3b through the ollama provider; also seen with qwen3.5:9b.

Config ($XDG_CONFIG_HOME/opencode/opencode.json, the only config source; OPENCODE_DISABLE_PROJECT_CONFIG=1):

{
  "$schema": "https://opencode.ai/config.json",
  "model": "ollama/qwen3.5:35b-a3b",
  "providers": { "ollama": { "settings": { "baseURL": "http://<lan-host>:11434/v1" } } },
  "mcp": {
    "servers": {
      "myserver": {
        "type": "local",
        "command": ["node", "/path/to/server.js"],
        "environment": { "EXAMPLE": "1" },
        "codemode": false
      }
    }
  },
  "permissions": [
    { "action": "*", "resource": "*", "effect": "ask" },
    { "action": "read", "resource": "*", "effect": "allow" },
    { "action": "glob", "resource": "*", "effect": "allow" },
    { "action": "grep", "resource": "*", "effect": "allow" },
    { "action": "myserver_submit_result", "resource": "*", "effect": "allow" }
  ]
}

server.js is a stdio MCP server exposing one tool, submit_result; its tools/list over stdio returns it.

Steps

  1. Start opencode acp with that config through an ACP client; session/new with mcpServers: [] (the server comes from config only).
  2. Prompt: "When done, call the submit_result tool of myserver with your answer."

Expected: with codemode: false (docs, MCP servers: "Set codemode to false to expose tools directly instead of through Code Mode"), myserver_submit_result is on the model's native tool list.

Actual

  • The model's native tools are only glob, grep, read and execute; it reaches the server only by writing JavaScript for execute ("the only callable tools are those explicitly listed in the Code Mode catalog").
  • A direct call fails: "No tool named 'submit_result' is currently available".
  • Same when the server is passed in ACP session/new instead of config.
  • Adding { "action": "execute", "resource": "*", "effect": "deny" } makes the tool unreachable altogether.

opencode debug config with the same XDG dirs shows the key loaded:

"mcp": { "servers": { "myserver": { "type": "local", "command": ["node", "/path/to/server.js"], "environment": { "EXAMPLE": "1" }, "codemode": false } } }

Impact: clients that need one MCP tool called reliably (a structured-answer tool) cannot use smaller local models — they don't produce valid Code Mode JavaScript. A larger model (qwen3-coder-next) did manage through execute.

Question: is codemode honoured for servers in opencode acp sessions, or is there another switch (per agent or global) to keep MCP tools native?

Activity

  1. opencode-agent commented on Oct 13, 2026

    @opencode-agent
    Contributor

    Thanks for the detailed report. I wasn't able to reproduce this on 2.0.28 (Linux), but I found one setup that gives the same symptom.

    What I tried: I ran opencode acp with your config: the ollama provider pointed at a mock endpoint that records requests, a stdio MCP server myserver with one tool submit_result and codemode: false, the same permissions, OPENCODE_DISABLE_PROJECT_CONFIG=1, and session/new with mcpServers: []. Then I checked the tool list in the actual request sent to the model:

    • Server only in config: myserver_submit_result was sent as a direct tool, next to execute, and it was not in the Code Mode catalog. The request also included shell, edit, write and the other built-in tools, not just glob/grep/read/execute. So the list you got may be the model's own description of its tools, not what OpenCode sent.
    • The ACP client also sends a server named myserver in session/new: that entry replaces the one from config, and ACP's server format has no codemode field. The server then goes back to Code Mode and the tool is reachable only through execute. That is exactly what you describe. Could you check what your client actually sends in mcpServers? Some clients forward their own MCP servers even when you don't expect them to.
    • Prompt sent right after session/new: if the MCP server hasn't finished connecting, its tools are missing from the first request entirely (First prompt after start has no MCP tools: tool list does not wait for pending MCP connections #51812). In that case the tool isn't reachable through execute either.

    What would help:

    1. The raw session/new request your client sends, especially mcpServers.
    2. The tool names in the actual request to Ollama, not the model's description of them. For example, put a logging proxy between OpenCode and Ollama, or start opencode acp --print-logs.
    3. Whether the same thing happens with opencode run "..." using the same config, outside ACP.

    Related issues:

  2. rekram1-node commented on Oct 15, 2026

    @rekram1-node
    Collaborator

    codemode: false is honored, I'm unable to reproduce, if you can still reproduce plz provide more info, perhaps checking the outbound network requests to see what's actually happening, ex:

    proxy opencode --standalone

    Where proxy is something like:

    proxy () {
            if [[ -z "$1" ]]
            then
                    echo "Usage: proxy <command>"
                    return 1
            fi
            mitmweb --listen-host 127.0.0.1 --listen-port 58888 --web-open-browser &> /dev/null &
            local pid=$!
            echo -n "Waiting for mitmweb..."
            while ! nc -z 127.0.0.1 58888 2> /dev/null
            do
                    sleep 0.2
            done
            echo " ready"
            local cert="$HOME/.mitmproxy/mitmproxy-ca-cert.pem"
            local proxy_url="http://127.0.0.1:58888"
            export NODE_EXTRA_CA_CERTS="$cert"
            export NODE_USE_ENV_PROXY="1"
            export CODEX_CA_CERTIFICATE="$cert"
            export HTTPS_PROXY="$proxy_url"
            export HTTP_PROXY="$proxy_url"
            export ALL_PROXY="$proxy_url"
            export WS_PROXY="$proxy_url"
            export WSS_PROXY="$proxy_url"
            export NO_PROXY="localhost,127.0.0.1"
            "$@"
            local exit_status=$?
            kill "$pid" 2> /dev/null
            wait "$pid" 2> /dev/null
            unset NODE_EXTRA_CA_CERTS NODE_USE_ENV_PROXY CODEX_CA_CERTIFICATE
            unset HTTPS_PROXY HTTP_PROXY ALL_PROXY WS_PROXY WSS_PROXY NO_PROXY
            return "$exit_status"
    }
    

    (we rlly need better network debugging --- coming soon)

  3. opencode-agent commented on Oct 16, 2026

    @opencode-agent
    Contributor

    Closing this for now since we haven't heard back. On 2.0.28, with myserver defined only in config and codemode: false, myserver_submit_result was sent to the model as a direct tool. I could only get the tool stuck behind execute when the ACP client also passed a server with the same name in session/new. That entry replaces the config one, and ACP has no way to carry codemode.

    If you're still seeing this, please reopen or comment with:

    • the raw mcpServers your client sends in session/new
    • the tool names in the actual request to Ollama

    That should be enough to tell which case it is. Thanks again 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