Skip to content

[FEATURE]: ACP - allow disabling codemode for MCP servers passed via session/new #58476

Open

Description

@reinholdk

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

MCP servers configured in the opencode config JSON can opt out of codemode with codemode: false. MCP servers that an ACP client registers through session/new (mcpServers) have no equivalent. They are always exposed through codemode. Please add a way to disable codemode for those servers.

Problem

An ACP client registers an HTTP MCP server like this:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "session/new",
  "params": {
    "cwd": "/abs/path/to/project",
    "mcpServers": [
      {
        "type": "http",
        "name": "my-server",
        "url": "http://127.0.0.1:8123/mcp",
        "headers": [
          { "name": "Authorization", "value": "Bearer <token>" }
        ]
      }
    ]
  }
}

The agent then runs the tools of my-server inside codemode. The client receives generic execute tool call updates in session/update:

{
  "method": "session/update",
  "params": {
    "sessionId": "sess_1",
    "update": {
      "sessionUpdate": "tool_call_update",
      "toolCallId": "call_1",
      "title": "execute",
      "kind": "other",
      "status": "in_progress",
      "rawInput": { "code": "...await my_server.read_file({ path: '/abs/path/to/project/README.md' })" }
    }
  }
}

This causes three problems:

  • The client cannot tell which MCP tool ran, so it cannot show a meaningful title or kind (read, edit, search, and so on).
  • The user sees a code blob where they should see tool input { path: '/abs/path/to/project/README.md' }.

The same server declared in the opencode config JSON with codemode: false produces one tool call per MCP tool:

{
  "mcp": {
    "my-server": {
      "type": "remote",
      "url": "http://127.0.0.1:8123/mcp",
      "codemode": false
    }
  }
}
{
  "sessionUpdate": "tool_call_update",
  "toolCallId": "call_1",
  "title": "my-server_read_file",
  "kind": "read",
  "status": "in_progress",
  "rawInput": { "path": "/abs/path/to/project/README.md" }
}

The ACP path has no way to get this behavior.

Adding a possibility for ACP clients to opt-out from codemode , e.g. via _meta on the mcpServers entry would be helpful.

Activity

  1. opencode-agent commented on Oct 23, 2026

    @opencode-agent
    Contributor

    Thanks for the detailed write-up, @reinholdk!

    Your request: let ACP clients turn off Code Mode for MCP servers they register through session/new (for example with a _meta field on the mcpServers entry), the way codemode: false already works for servers in the config. Then clients would get one tool call per MCP tool with a proper title, kind and rawInput, instead of a generic execute call. Right now the ACP layer creates these servers without a codemode setting, so they always get the default (Code Mode on). Maintainers will consider adding a per-server option.

    Workaround with a plugin

    Servers registered through ACP go through the same MCP config pipeline as config-declared ones, and plugins can edit that pipeline. This plugin turns off Code Mode for the server names you list. If you leave out servers, it applies to every server that doesn't set codemode explicitly. I haven't been able to test it, so please let me know if it doesn't work.

    Save it as .opencode/plugins/acp-mcp-direct.ts in the project, or as ~/.config/opencode/plugins/acp-mcp-direct.ts to use it everywhere:

    import { Plugin } from "@opencode/plugin"
    
    // Turns Code Mode off for MCP servers by name, including ones an ACP client
    // registers through session/new. Servers with `codemode` set explicitly are left alone.
    export default Plugin.define({
      id: "acp-mcp-direct",
      setup: async (ctx) => {
        const names = Array.isArray(ctx.options.servers) ? ctx.options.servers.map(String) : undefined
        await ctx.mcp.transform((editor) => {
          for (const [name, server] of editor.list()) {
            if (server.codemode !== undefined) continue
            if (names && !names.includes(name)) continue
            server.codemode = false
          }
        })
      },
    })

    To restrict it to specific servers, put the plugin in a directory (for example ./plugins/acp-mcp-direct/index.ts) and set options in opencode.json:

    {
      "plugins": [
        { "package": "./plugins/acp-mcp-direct", "options": { "servers": ["my-server"] } }
      ]
    }

    This is set on the OpenCode side, not by the ACP client for each session, so a _meta option would still be the cleaner fix.

    Related issues:

  2. reinholdk commented on Oct 23, 2026

    @reinholdk
    Author

    Thanks for suggesting the workaround. An ACP client typically doesn't ship or manage agent-specific plugins, so this would require users to configure OpenCode separately. A per-server option in session/new, for example via _meta, would let the client request this behavior without additional user setup.

  3. UweGrensing commented on Nov 7, 2026

    @UweGrensing

    Confirmed: plugin workaround works with Obsidian Copilot (Windows, OpenCode 2.2.6)

    I encountered this exact issue using Obsidian Copilot with its OpenCode ACP integration.

    Environment:

    • Windows 11
    • Obsidian Copilot 4.0.18
    • OpenCode 2.2.6
    • Miyo 0.4.1
    • Ollama with local models (Gemma 4 and LFM3)

    Copilot registers its MCP server through ACP session/new. Its server descriptor contains the server name, URL and authorization headers, but does not provide a codemode setting.

    As a result, the Miyo MCP tools were exposed through Code Mode rather than as native model tools.

    Smaller local models sometimes attempted to invoke obsidian-copilot.miyo_search directly. OpenCode rejected these calls with:

    No tool named "obsidian-copilot.miyo_search" is currently available.

    The plugin workaround suggested in this issue solved the problem.

    I installed the plugin under:

    ~/.config/opencode/plugins/acp-mcp-direct/index.ts

    and configured it in opencode.jsonc:

    {
      "$schema": "https://opencode.ai/config.json",
      "plugins": [
        {
          "package": "./plugins/acp-mcp-direct",
          "options": {
            "servers": ["obsidian-copilot"]
          }
        }
      ]
    }

    After restarting Obsidian, Miyo search worked and the previous Unknown tool errors disappeared.

    This confirms that the plugin workaround also works with a real ACP client that dynamically registers an HTTP MCP server.

    One further improvement would be to support an ACP-level option, for example _meta["opencode/codemode"] = false, so clients such as Obsidian Copilot can request native MCP tool exposure without requiring users to install an additional OpenCode plugin.

  4. mahammedmahieousman commented on Nov 7, 2026

    @mahammedmahieousman
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