github / github/copilot-cli

Authorization header dropped on JSON-RPC tools/call after successful MCP initialize (Streamable HTTP + OAuth 2.1 / DCR)

Đang mở
#3,015 0 bình luận 1 reaction 0 người được giao Xem trên GitHub
area:authentication area:mcp
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

## Summary

After a successful OAuth 2.1 + DCR flow against an MCP server using Streamable HTTP, Copilot CLI sends the `Authorization: Bearer …` header on `initialize` but **omits it on subsequent JSON-RPC requests** (`tools/list`, `tools/call`).
The server-side session is shown as "connected" in `/mcp`, but every tool invocation fails with 401.

## Environment

- `copilot --version` → **1.0.37** (latest at time of report)
- macOS (Darwin 25.4.0)
- MCP server: own implementation, Rust, Streamable HTTP via `rmcp` 1.4.0
- Auth: OAuth 2.1 + RFC 7591 (Dynamic Client Registration), public client (PKCE, `token_endpoint_auth_method=none`)
- AS metadata exposed at `/.well-known/oauth-authorization-server` (RFC 8414)
- Same server works correctly with Claude Desktop and Gemini CLI

**Expected**: Tool call succeeds (Bearer sent on the JSON-RPC `tools/call` HTTP request).

**Observed**: Tool call fails. Server logs show the JSON-RPC `tools/call` arrived with no `Authorization` header.

## Server-side evidence

```json
{
"level": "WARN",
"service": "backend",
"target": "rmcp::service",
"message": "response error",
"id": "4",
"error": "ErrorData { code: ErrorCode(-32600), message: \"UNAUTHORIZED: missing Authorization header\", data: None }"
}
```

JSON-RPC id `4` corresponds to a `tools/call` (ids 0–2 are the MCP handshake: `initialize`, `notifications/initialized`, `tools/list`).

The DCR registration of the Copilot CLI client succeeded:

| field | value |
|---|---|
| `client_name` | `GitHub Copilot CLI` |
| `client_type` | `public` |
| `grant_types` | `authorization_code, refresh_token` |
| `redirect_uris` | `http://127.0.0.1:/` |
| `dynamically_registered` | `true` |

So the OAuth flow itself completes — the bug is downstream, in the MCP transport layer not propagating the Bearer to subsequent JSON-RPC HTTP requests.

### Affected version

GitHub Copilot CLI 1.0.37.

### Steps to reproduce the behavior

1. Configure the MCP server in `~/.copilot/mcp-config.json` with `"type": "http"` pointing at a Streamable HTTP MCP that requires Bearer on every request.
2. Start Copilot CLI, `/mcp` lists the server as connected (browser opens, OAuth flow completes, refresh + access tokens stored).
3. Ask Copilot to invoke any tool exposed by the server.

### Expected behavior

Tool call succeeds (Bearer sent on the JSON-RPC `tools/call` HTTP request).

### Additional context

## Cross-client check

The exact same server, with the exact same DCR + OAuth config, works correctly with:

- **Claude Desktop** — Bearer sent on every JSON-RPC request
- **Gemini CLI MCP client** — Bearer sent on every JSON-RPC request

So the server is compliant with the [MCP Streamable HTTP spec (2025-03-26)](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http). The bug is specific to Copilot CLI's handling of the access token
after `initialize`.

## Likely cause

Per the MCP Streamable HTTP spec, **each JSON-RPC message is an independent HTTP POST** to `/mcp`. The `Authorization` header must be attached to **every** request, not just to `initialize` or to the SSE long-lived stream.

It looks like Copilot CLI's OAuthProvider/transport binding only attaches the Bearer at session establishment (or to the SSE stream open), not on subsequent POSTs that carry the JSON-RPC payloads.

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

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

Hướng nghiên cứu

Reproduce the failure using the HTTP MCP entry in ~/.copilot/mcp-config.json and a server requiring Bearer authentication. Start by tracing the Streamable HTTP transport and OAuthProvider binding after initialize; done means Authorization is present on notifications/initialized, tools/list, and tools/call requests and the tool call succeeds.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
rust
Lĩnh vực
api, authentication
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
45/100

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.