github / github/copilot-cli

MCP Sampling is Always Declined in Non-Interactive Mode

Đang mở
#2,882 1 bình luận 1 reaction 0 người được giao Xem trên GitHub
area:mcp area:non-interactive
Ngôn ngữ chính
Shell
Star
11.2k
Fork
1.9k
Merge trung bình
14 giờ 16 phút
Pull request đã merge (30 ngày)
6

Mô tả

### 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`**
```python
#!/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`**
```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**
```bash
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**
```bash
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:

```text
✗ 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
```

```text
✗ 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:

```text
[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:

```bash
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'"
```

```bash
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:

```text
duplicate (MCP: sampling-repro) · text: "alpha beta"
└ {"result":"alpha beta | alpha beta"}
```

```text
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

| Field | Value |
|-------|-------|
| Process log (redacted) | [process-1776747687370-23478-redacted.log](https://github.com/user-attachments/files/26940309/process-1776747687370-23478-redacted.log) |
| CLI version | GitHub Copilot CLI 1.0.31 |
| OS | Linux |
| Shell | bash |

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.