Describe the bug
When running the CLI in ACP mode (--acp), the --available-tools and
--excluded-tools flags have no effect. The flags are parsed correctly but
never applied to the session — the model sees the full tool list regardless.
Affected version
1.0.34
Steps to reproduce the behavior
copilot --acp --stdio --excluded-tools bash edit view
The model can still call bash, edit, view etc. as if the flags were not
passed.
Expected behavior
--available-tools foo bar restricts the model to only foo and bar.
--excluded-tools bash edit hides bash and edit from the model's tool
list, matching the behaviour in interactive and non-interactive modes.
Additional context
Root cause (source-located)
In index.js, the ACP startup path branches and returns early before
availableTools/excludedTools are applied:
// Line ~4375 (main command handler)
if (t.acp) {
await startACPMode({ ..., options: t, rules: E, ... }, authManager)
return // ← early exit; ae/ce computed below never run
}
ae = normalise(t.availableTools) // only reached for interactive/non-interactive
ce = normalise(t.excludedTools)
The raw CLI options object t is forwarded as options: t, so
this.options.options.availableTools / this.options.options.excludedTools are
accessible inside the Jpt class. However, Jpt.newSession() and
Jpt.loadSession() never read them:
// Jpt.newSession — current code
let l = await this.sessionManager.createSession({ sessionId, workingDirectory, ... })
this.mcpHost && l.updateOptions({ mcpServers: ..., mcpHost: ... })
// ← availableTools / excludedTools never set
Compare to interactive mode (Mto) and non-interactive mode (Cul), both of
which correctly call:
session.updateOptions({ ..., availableTools: s, excludedTools: l, ... })
Minimal fix
In Jpt.newSession() and Jpt.loadSession(), after the existing
updateOptions call for mcpHost, add:
const _opts = this.options.options
if (_opts?.availableTools || _opts?.excludedTools)
session.updateOptions({
availableTools: _opts.availableTools,
excludedTools: _opts.excludedTools
})
Workaround
--deny-tool does work in ACP mode because it populates rules.denied, which
is passed to createSessionPermissionService and consulted before any
session/request_permission is sent to the ACP client. However, this only
controls the permission layer — the tools still appear in the model's tool list.
Describe the bug
When running the CLI in ACP mode (
--acp), the--available-toolsand--excluded-toolsflags have no effect. The flags are parsed correctly butnever applied to the session — the model sees the full tool list regardless.
Affected version
1.0.34
Steps to reproduce the behavior
copilot --acp --stdio --excluded-tools bash edit viewThe model can still call bash, edit, view etc. as if the flags were not
passed.
Expected behavior
--available-tools foo barrestricts the model to only foo and bar.--excluded-tools bash edithides bash and edit from the model's toollist, matching the behaviour in interactive and non-interactive modes.
Additional context
Root cause (source-located)
In
index.js, the ACP startup path branches and returns early beforeavailableTools/excludedToolsare applied:// Line ~4375 (main command handler)
if (t.acp) {
await startACPMode({ ..., options: t, rules: E, ... }, authManager)
return // ← early exit; ae/ce computed below never run
}
ae = normalise(t.availableTools) // only reached for interactive/non-interactive
ce = normalise(t.excludedTools)
The raw CLI options object
tis forwarded asoptions: t, sothis.options.options.availableTools/this.options.options.excludedToolsareaccessible inside the
Jptclass. However,Jpt.newSession()andJpt.loadSession()never read them:// Jpt.newSession — current code
let l = await this.sessionManager.createSession({ sessionId, workingDirectory, ... })
this.mcpHost && l.updateOptions({ mcpServers: ..., mcpHost: ... })
// ← availableTools / excludedTools never set
Compare to interactive mode (
Mto) and non-interactive mode (Cul), both ofwhich correctly call:
session.updateOptions({ ..., availableTools: s, excludedTools: l, ... })
Minimal fix
In
Jpt.newSession()andJpt.loadSession(), after the existingupdateOptionscall formcpHost, add:const _opts = this.options.options
if (_opts?.availableTools || _opts?.excludedTools)
session.updateOptions({
availableTools: _opts.availableTools,
excludedTools: _opts.excludedTools
})
Workaround
--deny-tooldoes work in ACP mode because it populatesrules.denied, whichis passed to
createSessionPermissionServiceand consulted before anysession/request_permissionis sent to the ACP client. However, this onlycontrols the permission layer — the tools still appear in the model's tool list.