Describe the bug
MCP sampling (#1748) works in interactive mode, but the same MCP server reaches a denied permissions prompt in -p non-interactive mode, even when --allow-all is enabled.
With --allow-all, the CLI does invoke the MCP tool in -p mode. The tool starts, the server receives CallToolRequest, and then the sampling call back into the CLI fails with Method not found.
The same server, config, CLI version, and prompts work in interactive mode. In that control case, the CLI logs Received sampling request from sampling-repro and the tool returns successfully.
Affected version
GitHub Copilot CLI 1.0.31
Steps to reproduce the behavior
1. Create a minimal FastMCP server that uses sampling
sampling_server.py
#!/usr/bin/env python3
"""Minimal FastMCP server that exercises sampling/createMessage."""
from mcp.server.fastmcp import Context, FastMCP
from mcp.types import SamplingMessage, TextContent
mcp = FastMCP("sampling-repro")
async def sample_text(ctx: Context, prompt: str, system_prompt: str) -> str:
result = await ctx.session.create_message(
messages=[
SamplingMessage(
role="user",
content=TextContent(type="text", text=prompt),
)
],
max_tokens=256,
system_prompt=system_prompt,
)
parts = getattr(result, "content", None)
if isinstance(parts, list):
text = "".join(
part.text for part in parts if getattr(part, "type", None) == "text"
).strip()
if text:
return text
text = getattr(getattr(result, "content", None), "text", None)
if isinstance(text, str) and text.strip():
return text.strip()
raise RuntimeError(f"Unexpected sampling response: {result!r}")
@mcp.tool()
async def summarize(text: str, ctx: Context) -> str:
"""Summarize the given text in one sentence."""
summary = await sample_text(
ctx,
prompt=f"Summarize in exactly one sentence:\n\n{text}",
system_prompt="You are a concise summarizer. Reply with exactly one sentence.",
)
return f"Summary: {summary}"
@mcp.tool()
async def duplicate(text: str, ctx: Context) -> str:
"""Repeat the given text exactly twice with a separator."""
repeated = await sample_text(
ctx,
prompt=(
"Repeat the following text exactly twice, separated by ' | ', and add no "
f"other words:\n\n{text}"
),
system_prompt="Return only the duplicated text.",
)
return repeated
if __name__ == "__main__":
mcp.run()
2. Create a minimal MCP config file
mcp-config.json
{
"mcpServers": {
"sampling-repro": {
"command": "/path/to/python3",
"args": [
"/path/to/sampling_server.py"
],
"env": {}
}
}
}
3. Run the same prompts in -p mode
Summarize example
copilot \
--log-level=all \
--log-dir /path/to/logs \
--additional-mcp-config @/path/to/mcp-config.json \
--disable-builtin-mcps \
--no-custom-instructions \
--allow-all \
-p "Use the summarize tool from the sampling-repro MCP server exactly once to summarize this text: 'The quick brown fox jumps over the lazy dog. This sentence contains every letter of the alphabet and is often used for typing practice.'"
Duplication example
copilot \
--log-level=all \
--log-dir /path/to/logs \
--additional-mcp-config @/path/to/mcp-config.json \
--disable-builtin-mcps \
--no-custom-instructions \
--allow-all \
-p "Use the duplicate tool from the sampling-repro MCP server exactly once with this text: 'alpha beta'"
4. Check the outputs
Both non-interactive runs fail the same way:
✗ summarize (MCP: sampling-repro) · text: "The quick brown fox jumps over the lazy dog. This senten…
└ MCP server 'sampling-repro': Error executing tool summarize: Method not found
✗ duplicate (MCP: sampling-repro) · text: "alpha beta"
└ MCP server 'sampling-repro': Error executing tool duplicate: Method not found
Redacted log excerpt from the -p summarize run:
[DEBUG] Tool calls count: 2
[ERROR] [mcp server sampling-repro stderr] ... Processing request of type CallToolRequest
[DEBUG] Tool invocation result: Error executing tool summarize: Method not found
Expected behavior
If --allow-all is set, sampling/createMessage should work in -p mode the same way it works in interactive mode.
The non-interactive session cannot show approval prompts, but --allow-all already bypasses tool, path, and URL confirmations. Once the tool call is allowed to run, the CLI should expose the sampling handler to the MCP server instead of returning Method not found.
Control: interactive mode works
Run the same prompts in interactive mode:
copilot \
--log-level=all \
--log-dir /path/to/logs \
--additional-mcp-config @/path/to/mcp-config.json \
--disable-builtin-mcps \
--no-custom-instructions \
--allow-all \
-i "Use the duplicate tool from the sampling-repro MCP server exactly once with this text: 'alpha beta'"
copilot \
--log-level=all \
--log-dir /path/to/logs \
--additional-mcp-config @/path/to/mcp-config.json \
--disable-builtin-mcps \
--no-custom-instructions \
--allow-all \
-i "Use the summarize tool from the sampling-repro MCP server exactly once to summarize this text: 'The quick brown fox jumps over the lazy dog. This sentence contains every letter of the alphabet and is often used for typing practice.'"
These succeed with the same server and config:
duplicate (MCP: sampling-repro) · text: "alpha beta"
└ {"result":"alpha beta | alpha beta"}
summarize (MCP: sampling-repro) · text: "The quick brown fox jumps over the lazy dog. This sentence c…"
└ {"result":"Summary: \"The quick brown fox jumps over the lazy dog\" is a pangram containing every letter of the alphabet and is commonly used for typing practice."}
Expected behavior
MCP sampling should be allowed through non-interactive sessions when using -p and --allow-all.
Additional context
Describe the bug
MCP sampling (#1748) works in interactive mode, but the same MCP server reaches a denied permissions prompt in
-pnon-interactive mode, even when--allow-allis enabled.With
--allow-all, the CLI does invoke the MCP tool in-pmode. The tool starts, the server receivesCallToolRequest, and then the sampling call back into the CLI fails withMethod not found.The same server, config, CLI version, and prompts work in interactive mode. In that control case, the CLI logs
Received sampling request from sampling-reproand the tool returns successfully.Affected version
GitHub Copilot CLI 1.0.31
Steps to reproduce the behavior
1. Create a minimal FastMCP server that uses sampling
sampling_server.py2. Create a minimal MCP config file
mcp-config.json{ "mcpServers": { "sampling-repro": { "command": "/path/to/python3", "args": [ "/path/to/sampling_server.py" ], "env": {} } } }3. Run the same prompts in
-pmodeSummarize example
copilot \ --log-level=all \ --log-dir /path/to/logs \ --additional-mcp-config @/path/to/mcp-config.json \ --disable-builtin-mcps \ --no-custom-instructions \ --allow-all \ -p "Use the summarize tool from the sampling-repro MCP server exactly once to summarize this text: 'The quick brown fox jumps over the lazy dog. This sentence contains every letter of the alphabet and is often used for typing practice.'"Duplication example
copilot \ --log-level=all \ --log-dir /path/to/logs \ --additional-mcp-config @/path/to/mcp-config.json \ --disable-builtin-mcps \ --no-custom-instructions \ --allow-all \ -p "Use the duplicate tool from the sampling-repro MCP server exactly once with this text: 'alpha beta'"4. Check the outputs
Both non-interactive runs fail the same way:
Redacted log excerpt from the
-psummarize run:Expected behavior
If
--allow-allis set,sampling/createMessageshould work in-pmode the same way it works in interactive mode.The non-interactive session cannot show approval prompts, but
--allow-allalready bypasses tool, path, and URL confirmations. Once the tool call is allowed to run, the CLI should expose the sampling handler to the MCP server instead of returningMethod not found.Control: interactive mode works
Run the same prompts in interactive mode:
copilot \ --log-level=all \ --log-dir /path/to/logs \ --additional-mcp-config @/path/to/mcp-config.json \ --disable-builtin-mcps \ --no-custom-instructions \ --allow-all \ -i "Use the duplicate tool from the sampling-repro MCP server exactly once with this text: 'alpha beta'"copilot \ --log-level=all \ --log-dir /path/to/logs \ --additional-mcp-config @/path/to/mcp-config.json \ --disable-builtin-mcps \ --no-custom-instructions \ --allow-all \ -i "Use the summarize tool from the sampling-repro MCP server exactly once to summarize this text: 'The quick brown fox jumps over the lazy dog. This sentence contains every letter of the alphabet and is often used for typing practice.'"These succeed with the same server and config:
Expected behavior
MCP sampling should be allowed through non-interactive sessions when using
-pand--allow-all.Additional context