Skip to content

Commit f12c51a

Browse files
committed
perf(engine): resolve codex native mcp names once per session start
1 parent c3b3be4 commit f12c51a

1 file changed

Lines changed: 103 additions & 103 deletions

File tree

‎packages/host/engine/src/session/start-options-resolver.ts‎

Lines changed: 103 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export class SessionStartOptionsResolver {
4545
const { accountId } = defaults;
4646
const account = accountId === undefined ? {} : { accountId };
4747
const { translator } = this;
48+
const providerMcpServerNames = this.providerMcpServerNames.bind(this);
4849
const withCustomMcpServers = this.withCustomMcpServers.bind(this);
4950
const withSimulatorMcp = this.withSimulatorMcp.bind(this);
5051
const withPluginMcpServers = this.withPluginMcpServers.bind(this);
@@ -69,8 +70,9 @@ export class SessionStartOptionsResolver {
6970
}),
7071
);
7172
}
72-
const custom = yield* withCustomMcpServers(defaults.options);
73-
const pluginInjected = yield* withPluginMcpServers(custom.options, custom.warnings);
73+
const nativeMcpNames = yield* providerMcpServerNames(defaults.options);
74+
const custom = withCustomMcpServers(defaults.options, nativeMcpNames);
75+
const pluginInjected = withPluginMcpServers(custom.options, custom.warnings, nativeMcpNames);
7476
const resolved = withSimulatorMcp(pluginInjected.options, sessionId);
7577
const upstream = translationUpstream(resolved);
7678
if (!upstream) return { options: resolved, ...account, warnings: pluginInjected.warnings };
@@ -118,64 +120,71 @@ export class SessionStartOptionsResolver {
118120
return names;
119121
}
120122

123+
/**
124+
* Enabled provider-native MCP names for Codex's shared, un-namespaced space — resolved once per
125+
* session start and shared by the custom-MCP and LinkCode-plugin folds, since each resolution is
126+
* a full discovery round trip (`plugin/list` plus per-plugin detail reads). `null` means the
127+
* preflight failed: an override cannot be ruled out, so consumers skip instead of injecting.
128+
*/
129+
private providerMcpServerNames(options: StartOptions): Effect.Effect<ReadonlySet<string> | null> {
130+
if (options.kind === 'codex' && this.plugins) {
131+
return this.plugins
132+
.enabledMcpServerNames('codex', { cwd: options.cwd })
133+
.pipe(Effect.match({ onSuccess: (names) => names, onFailure: () => null }));
134+
}
135+
return Effect.succeed(new Set<string>());
136+
}
137+
121138
/** Fold enabled custom MCP servers into the session's server list, warning instead of
122139
* silently dropping: unsupported agent kinds and name collisions are user-visible facts. */
123140
private withCustomMcpServers(
124141
options: StartOptions,
125-
): Effect.Effect<{ options: StartOptions; warnings: McpWarning[] }> {
142+
nativeMcpNames: ReadonlySet<string> | null,
143+
): { options: StartOptions; warnings: McpWarning[] } {
126144
const warnings: McpWarning[] = [];
127145
const enabled = this.customMcp?.listEnabled() ?? [];
128-
if (enabled.length === 0) return Effect.succeed({ options, warnings });
146+
if (enabled.length === 0) return { options, warnings };
129147
if (!MCP_CAPABLE_AGENT_KINDS.has(options.kind)) {
130148
for (const entry of enabled) {
131149
warnings.push({ serverName: entry.server.name, reason: 'agent-unsupported' });
132150
}
133-
return Effect.succeed({ options, warnings });
151+
return { options, warnings };
134152
}
135-
const pluginNames =
136-
options.kind === 'codex' && this.plugins
137-
? this.plugins
138-
.enabledMcpServerNames('codex', { cwd: options.cwd })
139-
.pipe(Effect.match({ onSuccess: (names) => names, onFailure: () => null }))
140-
: Effect.succeed(new Set<string>());
141-
return pluginNames.pipe(
142-
Effect.map((names) => {
143-
const servers = [...(options.mcpServers ?? [])];
144-
for (const entry of enabled) {
145-
if (names === null) {
146-
warnings.push({
147-
serverName: entry.server.name,
148-
reason: 'provider-preflight-failed',
149-
});
150-
continue;
151-
}
152-
if (
153-
options.kind === 'codex' &&
154-
entry.server.type === 'http' &&
155-
entry.server.headers !== undefined &&
156-
!isObjectEmpty(entry.server.headers)
157-
) {
158-
warnings.push({ serverName: entry.server.name, reason: 'provider-unsupported' });
159-
continue;
160-
}
161-
if (
162-
names.has(entry.server.name) ||
163-
servers.some((server) => server.name === entry.server.name)
164-
) {
165-
warnings.push({ serverName: entry.server.name, reason: 'name-conflict' });
166-
continue;
167-
}
168-
servers.push(entry.server);
169-
}
170-
return {
171-
options:
172-
servers.length === 0 && options.mcpServers === undefined
173-
? options
174-
: { ...options, mcpServers: servers },
175-
warnings,
176-
};
177-
}),
178-
);
153+
const servers = [...(options.mcpServers ?? [])];
154+
for (const entry of enabled) {
155+
const names = nativeMcpNames;
156+
if (names === null) {
157+
warnings.push({
158+
serverName: entry.server.name,
159+
reason: 'provider-preflight-failed',
160+
});
161+
continue;
162+
}
163+
if (
164+
options.kind === 'codex' &&
165+
entry.server.type === 'http' &&
166+
entry.server.headers !== undefined &&
167+
!isObjectEmpty(entry.server.headers)
168+
) {
169+
warnings.push({ serverName: entry.server.name, reason: 'provider-unsupported' });
170+
continue;
171+
}
172+
if (
173+
names.has(entry.server.name) ||
174+
servers.some((server) => server.name === entry.server.name)
175+
) {
176+
warnings.push({ serverName: entry.server.name, reason: 'name-conflict' });
177+
continue;
178+
}
179+
servers.push(entry.server);
180+
}
181+
return {
182+
options:
183+
servers.length === 0 && options.mcpServers === undefined
184+
? options
185+
: { ...options, mcpServers: servers },
186+
warnings,
187+
};
179188
}
180189

181190
/** Fold enabled LinkCode plugin mcp-server components into the session's server list, resolving
@@ -186,11 +195,12 @@ export class SessionStartOptionsResolver {
186195
private withPluginMcpServers(
187196
options: StartOptions,
188197
warnings: McpWarning[],
189-
): Effect.Effect<{ options: StartOptions; warnings: McpWarning[] }> {
198+
nativeMcpNames: ReadonlySet<string> | null,
199+
): { options: StartOptions; warnings: McpWarning[] } {
190200
const store = this.linkCodePluginStore;
191-
if (store === undefined) return Effect.succeed({ options, warnings });
201+
if (store === undefined) return { options, warnings };
192202
const entries = store.list().filter((entry) => entry.installed.enabled);
193-
if (entries.length === 0) return Effect.succeed({ options, warnings });
203+
if (entries.length === 0) return { options, warnings };
194204
if (!MCP_CAPABLE_AGENT_KINDS.has(options.kind)) {
195205
for (const entry of entries) {
196206
for (const component of entry.manifest.components) {
@@ -199,61 +209,51 @@ export class SessionStartOptionsResolver {
199209
}
200210
}
201211
}
202-
return Effect.succeed({ options, warnings });
212+
return { options, warnings };
203213
}
204-
const pluginNames =
205-
options.kind === 'codex' && this.plugins
206-
? this.plugins
207-
.enabledMcpServerNames('codex', { cwd: options.cwd })
208-
.pipe(Effect.match({ onSuccess: (names) => names, onFailure: () => null }))
209-
: Effect.succeed(new Set<string>());
210-
return Effect.map(pluginNames, (names) => {
211-
const servers = [...(options.mcpServers ?? [])];
212-
for (const entry of entries) {
213-
const settings = store.getSettings(entry.installed.id);
214-
for (const component of entry.manifest.components) {
215-
if (component.kind !== 'mcp-server') continue;
216-
if (names === null) {
217-
// Without the native name set an override cannot be ruled out — skip, don't inject.
218-
warnings.push({ serverName: component.name, reason: 'provider-preflight-failed' });
219-
continue;
220-
}
221-
if (
222-
names.has(component.name) ||
223-
servers.some((server) => server.name === component.name)
224-
) {
225-
warnings.push({ serverName: component.name, reason: 'name-conflict' });
226-
continue;
227-
}
228-
const env: Record<string, string> = {};
229-
if (component.env) {
230-
for (const [envVar, settingId] of Object.entries(component.env)) {
231-
if (settingId in settings) env[envVar] = String(settings[settingId]);
232-
}
214+
const names = nativeMcpNames;
215+
const servers = [...(options.mcpServers ?? [])];
216+
for (const entry of entries) {
217+
const settings = store.getSettings(entry.installed.id);
218+
for (const component of entry.manifest.components) {
219+
if (component.kind !== 'mcp-server') continue;
220+
if (names === null) {
221+
// Without the native name set an override cannot be ruled out — skip, don't inject.
222+
warnings.push({ serverName: component.name, reason: 'provider-preflight-failed' });
223+
continue;
224+
}
225+
if (names.has(component.name) || servers.some((server) => server.name === component.name)) {
226+
warnings.push({ serverName: component.name, reason: 'name-conflict' });
227+
continue;
228+
}
229+
const env: Record<string, string> = {};
230+
if (component.env) {
231+
for (const [envVar, settingId] of Object.entries(component.env)) {
232+
if (settingId in settings) env[envVar] = String(settings[settingId]);
233233
}
234-
// No missing-config advisory yet: shipped clients validate `reason` against the old enum
235-
// and would drop the whole session.started frame, so emission waits for a tolerant floor.
236-
const server: McpServer = {
237-
type: 'stdio',
238-
name: component.name,
239-
command: component.command,
240-
...(component.entry && {
241-
args: [resolvePath(entry.installed.path, component.entry), ...(component.args ?? [])],
242-
}),
243-
...(!component.entry && component.args && { args: component.args }),
244-
...(!isObjectEmpty(env) && { env }),
245-
};
246-
servers.push(server);
247234
}
235+
// No missing-config advisory yet: shipped clients validate `reason` against the old enum
236+
// and would drop the whole session.started frame, so emission waits for a tolerant floor.
237+
const server: McpServer = {
238+
type: 'stdio',
239+
name: component.name,
240+
command: component.command,
241+
...(component.entry && {
242+
args: [resolvePath(entry.installed.path, component.entry), ...(component.args ?? [])],
243+
}),
244+
...(!component.entry && component.args && { args: component.args }),
245+
...(!isObjectEmpty(env) && { env }),
246+
};
247+
servers.push(server);
248248
}
249-
return {
250-
options:
251-
servers.length === 0 && options.mcpServers === undefined
252-
? options
253-
: { ...options, mcpServers: servers },
254-
warnings,
255-
};
256-
});
249+
}
250+
return {
251+
options:
252+
servers.length === 0 && options.mcpServers === undefined
253+
? options
254+
: { ...options, mcpServers: servers },
255+
warnings,
256+
};
257257
}
258258

259259
/** Append the session's simulator MCP endpoint for agents whose SDK can consume it. */

0 commit comments

Comments
 (0)