MCP diagnostics are process-global, so one project's discovery erases another's
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 55/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- typescript
調査の方向性
packages/opencode/src/mcp/discover.ts と packages/opencode/src/config/variable.ts にある名前付きの record から始め、次に cli/cmd/mcp.ts、session/prompt.ts、config/config.ts にあるそれらの呼び出し元を追ってください。完了条件は、diagnostics が projectDir 単位で分離され、あるプロジェクトの discovery が別のプロジェクトの discovery を消去または上書きしなくなり、#1121 の stale-entry fix が引き続き機能することです。
索引モデルが issue の本文から書いたものです。
説明
Summary
The four MCP diagnostic records are module-level singletons keyed by server name alone, with no notion of which project they belong to. In a process serving more than one project — altimate serve, which is how the extension and every hosted user reach the agent — a second project's discovery erases the first's diagnostics, and two projects that reuse a server name overwrite each other.
| record | file |
|---|---|
_unresolvedEnv |
packages/opencode/src/mcp/discover.ts:53 |
_drift |
packages/opencode/src/mcp/discover.ts:83 |
_discoveredSource |
packages/opencode/src/mcp/discover.ts:156 |
_blankedEnv |
packages/opencode/src/config/variable.ts:37 |
Reproduction
Two temp projects, each with a .vscode/mcp.json whose server has one unresolved {env:VAR}. Run against d00931b5e6 (current main):
after A: unresolvedEnvVars('alpha') = ["ALTIMATE_REPRO_VAR_A"]
after B: unresolvedEnvVars('alpha') = [] ← erased
after B: unresolvedEnvVars('beta') = ["ALTIMATE_REPRO_VAR_B"]
And with both projects using the same server name:
shared name: unresolvedEnvVars('datamate') = ["ALTIMATE_REPRO_VAR_B"] ← A's answer gone
datamate is not a hypothetical collision — it is the name the extension sync writes into every project.
Why it happens
discoverExternalMcp(projectDir) clears all three of its records at the top of the run and repopulates them afterwards. That was deliberate — it is what stops a variable that has since been fixed from being reported forever (#1121) — but the clear is global, so it takes the other project's entries with it. _blankedEnv has the same shape: blankedEnvVars() returns every config source ever parsed in the process, not the active project's.
The clear also sits before the first await while the writes happen after several, so concurrent discovery can interleave one project's clear with another's writes.
Impact
mcp list, mcp status and /mcps are the surfaces people use when a server will not connect. Under altimate serve — the path users actually run, not a niche debugging mode — they can report:
- nothing, for a project whose diagnostics another project cleared
- another project's variable names, under a shared server name
- drift attributed to a file belonging to a different project
A wrong answer here is worse than none, because the whole point of #1121/#701/#790/#878 was to stop people guessing.
Suggested fix
Key each record by projectDir and take the project as a parameter:
export function unresolvedEnvVars(server: string, projectDir: string): string[]
export function configDrift(projectDir: string): { server: string; source: string; fields: string[] }[]
export function discoveredSource(server: string, projectDir: string): string | undefined
export function blankedEnvVars(projectDir: string): { source: string; names: string[] }[]
A discovery run then clears only its own project's entries, which keeps the staleness fix from #1121 while making the clear harmless to everyone else. This is the InstanceState convention the rest of the codebase already follows for per-directory state.
Call sites to update: cli/cmd/mcp.ts (reportConfigDiagnostics), session/prompt.ts (/mcps), and config/config.ts (drift recording).
Provenance
Flagged independently by cubic, kilo, and the harness bot across #1159 and #1160, and deliberately deferred from both as too broad for those PRs.
- 主要言語
- TypeScript
- スター
- 815
- フォーク
- 135
- 平均マージ
- 1日 12時間
- マージ済み PR(30日)
- 53
環境構築
このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
AltimateAI/altimate-code のほかの issue
-
test: MCP tests fail when the developer's ~/.claude.json has MCP servers (HOME is not sandboxed)オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
AltimateAI/altimate-code#1386 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
AltimateAI/altimate-code#1384 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
AltimateAI/altimate-code#1378 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
AltimateAI/altimate-code#1359 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
AltimateAI/altimate-code#1323 ·
メンテナーはふだん 1 日以内に返信
AltimateAI/altimate-code の issue をすべて見る
似ている issue
-
Mend: dependency security vulnerability untriaged
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
opensearch-project/security-dashboards-plugin#2545 ·
メンテナーはふだん 1 日以内に返信
-
Add: Dream TR SDオープンcheck:passed streams:add
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
メンテナーはふだん 1 日以内に返信
-
doctor integrity sample scans soft-deleted pages on Postgres (batch path has no deleted_at filter)オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 72/100
SocialGouv/egapro#4672 · コメント 1 件 ·
メンテナーはふだん 2 日以内に返信
-
area:agents area:tui bug
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
anthropics/claude-code#98358 ·
メンテナーはふだん 1 日以内に返信