`resumeSession` silently ignores the `mcpServers` config field
还没有人认领这个 Issue。
评估
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 新手友好度
- 68/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 冷清
- 技术栈
- javascript
- 领域
- api
调研方向
从入口点 CopilotClient.resumeSession 开始,将其对 mcpServers 的处理与 createSession 进行比较,并使用提供的复现步骤和 session.mcp_servers_loaded 事件进行检查。当使用 { memory: ... } 恢复时仅发出 ["memory"]、断开连接或隐藏之前的 everything 服务器,并且只暴露替代服务器的工具时,即表示完成。
由索引模型根据 Issue 内容生成。
描述
CopilotClient.resumeSession(id, { mcpServers: ... }) does not apply the mcpServers value passed on resume. The servers connected during the
original createSession call remain connected; any servers declared on resume are never loaded. Other fields in ResumeSessionConfig (tools,
skillDirectories, systemMessage) are applied on the same call, so the behaviour is asymmetric.
Reproduction
import { CopilotClient } from '@github/copilot-sdk'
const baseConfig = {
model: 'gpt-4.1',
streaming: true,
onPermissionRequest: async () => ({ decision: 'allow', persist: false })
}
// Two different public MCP reference servers — distinct tool sets.
const mcpEverything = {
type: 'local',
command: 'npx',
args: ['-y', '@modelcontextprotocol/server-everything'],
tools: '*'
}
const mcpMemory = {
type: 'local',
command: 'npx',
args: ['-y', '@modelcontextprotocol/server-memory'],
tools: '*'
}
const LIST_PROMPT =
'Pick any MCP tool you actually have access to right now and call it ' +
'(any reasonable args). Then in one short sentence, name the tool you ' +
'just called and which MCP server it belongs to.'
async function ask (session, prompt) {
const response = await session.sendAndWait({ prompt }, 60_000)
return response?.data?.content ?? ''
}
const client = new CopilotClient({ autoStart: true })
await client.start()
const logServers = (phase) => (event) => {
if (event.type === 'session.mcp_servers_loaded') {
const names = (event.data?.servers ?? []).map(s => s.name)
console.log(` [SDK event in ${phase}] session.mcp_servers_loaded → ${JSON.stringify(names)}`)
}
}
console.log('\n=== 1. createSession with mcpServers = { everything } ===')
const sessionA = await client.createSession({
...baseConfig,
mcpServers: { everything: mcpEverything }
})
sessionA.on(logServers('createSession'))
console.log(' LLM reply: ' + await ask(sessionA, LIST_PROMPT))
console.log('\n=== 2. resumeSession(sameId, mcpServers = { memory }) ===')
const sessionB = await client.resumeSession(sessionA.id ?? sessionA.sessionId, {
...baseConfig,
mcpServers: { memory: mcpMemory } // ← DIFFERENT server
})
sessionB.on(logServers('resumeSession'))
console.log(' LLM reply: ' + await ask(sessionB, LIST_PROMPT))
await client.disconnect?.()
process.exit(0)
Run with:
npm i @github/copilot-sdk
node repro.mjs
(Node 22, npx on PATH, and a logged-in Copilot CLI — run
./node_modules/.bin/copilot login once.)
Observed behavior
=== 1. createSession with mcpServers = { everything } ===
[SDK event in createSession] session.mcp_servers_loaded → ["everything"]
LLM reply: I called the get-sum tool from the "everything" MCP server.
=== 2. resumeSession(sameId, mcpServers = { memory }) ===
[SDK event in resumeSession] session.mcp_servers_loaded → ["everything"]
LLM reply: I called the get-tiny-image tool from the "everything" MCP server.
After step 2 the SDK is still publishing ["everything"] in session.mcp_servers_loaded, and the LLM can only call tools from everything — even though the resume config explicitly passed { memory: ... } and did not include everything.
Expected behavior
After resumeSession(id, { mcpServers: { memory: ... } }):
session.mcp_servers_loadedshould emit["memory"].- The previously-loaded
everythingserver should be disconnected (or at least no longer be visible as a tool source). - The LLM should only be able to call tools from
memory(e.g.read_graph,create_entities).
Impact
Prevents agent-switching mid-conversation (same use case as #567). Only workaround is deleteSession + createSession — which wipes history, defeating the point of resumeSession.
Environment
@github/copilot-sdk0.2.1 and 0.2.2 (both affected)- CLI binary 1.0.34, Node 22.14, Linux
- 主要语言
- Java
- 星标
- 10.5k
- 派生
- 1.5k
- 平均合并
- 1 天 9 小时
- 30 天内合并 PR
- 130
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
github/copilot-sdk 的其他 Issue
-
agentic-workflows
难度 2/5 1-3 小时 新手友好度 65/100
github/copilot-sdk#2760 ·
-
难度 2/5 1-3 小时 新手友好度 65/100
github/copilot-sdk#2759 ·
-
documentation
难度 1/5 1 小时以内 新手友好度 85/100
github/copilot-sdk#2758 ·
-
agentic-workflows
难度 2/5 1-3 小时 新手友好度 68/100
github/copilot-sdk#2709 · 1 条评论 ·
-
难度 1/5 1 小时以内 新手友好度 78/100
github/copilot-sdk#2673 ·
查看 github/copilot-sdk 的全部 Issue
相似的 Issue
-
documentation
难度 2/5 1-3 小时 新手友好度 65/100
inu-appcenter/memorIN-backend#288 ·
-
难度 2/5 1-3 小时 新手友好度 65/100
-
frontend maui-pilot pilot-ask question
难度 2/5 1-3 小时 新手友好度 75/100
-
难度 2/5 1-3 小时 新手友好度 75/100
-
area/plugin
难度 2/5 1-3 小时 新手友好度 75/100
kestra-io/plugin-kestra#190 ·