mirror of
https://github.com/wu736139669/hapi.git
synced 2026-11-07 01:21:37 +00:00
feat(codex): support user-configured MCP servers in remote sessions (#1789)
* feat(codex): load user MCP servers in HAPI sessions * feat(codex): proxy Windows MCP command shims * fix(codex): address MCP review feedback * fix(codex): use HAPI-owned MCP proxy * fix(codex): preserve Windows MCP argv boundaries * fix(codex): keep remote MCP placement unchanged
This commit is contained in:
@@ -1560,6 +1560,77 @@ describe('codexRemoteLauncher', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('forwards user-configured MCP servers into fresh and resumed threads', async () => {
|
||||
harness.configReadResponse = {
|
||||
config: {
|
||||
mcp_servers: {
|
||||
'package-manager': {
|
||||
command: 'uvx',
|
||||
args: ['example-mcp', 'serve'],
|
||||
environment_id: 'local',
|
||||
enabled: true,
|
||||
tool_timeout_sec: 60
|
||||
},
|
||||
remote: {
|
||||
url: 'https://example.test/mcp',
|
||||
bearer_token_env_var: 'REMOTE_MCP_TOKEN'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const fresh = createSessionStub();
|
||||
await codexRemoteLauncher(fresh.session as never);
|
||||
const freshConfig = harness.startThreadParams[0]?.config as Record<string, unknown> | undefined;
|
||||
const freshPackageManager = freshConfig?.['mcp_servers.package-manager'] as {
|
||||
command?: string;
|
||||
args?: string[];
|
||||
} | undefined;
|
||||
expect(harness.startThreadParams[0]?.config).toMatchObject({
|
||||
'mcp_servers.remote': {
|
||||
url: 'https://example.test/mcp',
|
||||
bearer_token_env_var: 'REMOTE_MCP_TOKEN'
|
||||
}
|
||||
});
|
||||
expect(freshPackageManager).toEqual(expect.objectContaining({
|
||||
environment_id: 'local',
|
||||
enabled: true,
|
||||
tool_timeout_sec: 60
|
||||
}));
|
||||
if (process.platform === 'win32') {
|
||||
expect(freshPackageManager?.args).toContain('mcp-proxy');
|
||||
} else {
|
||||
expect(freshPackageManager).toMatchObject({
|
||||
command: 'uvx',
|
||||
args: ['example-mcp', 'serve']
|
||||
});
|
||||
}
|
||||
|
||||
harness.startThreadParams = [];
|
||||
const resumed = createSessionStub();
|
||||
resumed.session.sessionId = 'thread-existing';
|
||||
await codexRemoteLauncher(resumed.session as never);
|
||||
const resumedConfig = harness.resumeThreadParams[0]?.config as Record<string, unknown> | undefined;
|
||||
const resumedPackageManager = resumedConfig?.['mcp_servers.package-manager'] as {
|
||||
command?: string;
|
||||
args?: string[];
|
||||
} | undefined;
|
||||
expect(harness.resumeThreadParams[0]?.config).toMatchObject({
|
||||
'mcp_servers.remote': {
|
||||
url: 'https://example.test/mcp'
|
||||
}
|
||||
});
|
||||
expect(resumedPackageManager).toBeDefined();
|
||||
if (process.platform === 'win32') {
|
||||
expect(resumedPackageManager?.args).toContain('mcp-proxy');
|
||||
} else {
|
||||
expect(resumedPackageManager).toMatchObject({
|
||||
command: 'uvx',
|
||||
args: ['example-mcp', 'serve']
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it('keeps remote sessions working when config/read is unavailable', async () => {
|
||||
harness.failConfigRead = true;
|
||||
const { session } = createSessionStub();
|
||||
|
||||
Reference in New Issue
Block a user