Skip to content

Conversation

Skn0tt
Copy link
Member

@Skn0tt Skn0tt commented Aug 4, 2025

No description provided.

@Skn0tt Skn0tt changed the title chore(vscode): add vscode method for browser_connect chore(vscode): browser_connect_vscode via out of process proxy Aug 6, 2025
@Skn0tt Skn0tt changed the title chore(vscode): browser_connect_vscode via out of process proxy chore(vscode): browser_connect_vscode via MCP Switcher and out of process backend Aug 7, 2025
@Skn0tt Skn0tt changed the title chore(vscode): browser_connect_vscode via MCP Switcher and out of process backend chore(vscode): browser_connect via MCP Switcher and out of process backend Aug 7, 2025
@pavelfeldman
Copy link
Member

Can we go lower level and implement it in src/mcp?

onChangeProxyTarget: ServerBackend['onChangeProxyTarget'];
}

export class ServerBackendProxy implements ServerBackend {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ServerBackendSwitcher?

src/program.ts Outdated
const proxy = new ServerBackendProxy(
new BrowserServerBackend(config, factories),
{
async onChangeProxyTarget(target) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd inline this logic into ServerBackendProxy and have it accept a list of backed factories.

this._target.onChangeProxyTarget = this._handleChangeProxyTarget;
if (this._initializeInfo) {
old.serverClosed?.();
await this.initialize(this._initializeInfo);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
await this.initialize(this._initializeInfo);
await this._target.initialize?.(this._initializeInfo);

constructor(private readonly _targetFactories: Record<string, (options: any) => ServerBackend>) {
const defaultTargetFactory = this._targetFactories[''];
this._target = defaultTargetFactory({});
this._target.onChangeProxyTarget = this._handleChangeProxyTarget;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this._handleChangeProxyTarget.bind(this) ?

private _initializeInfo?: InitializeInfo;

constructor(private readonly _targetFactories: Record<string, (options: any) => ServerBackend>) {
const defaultTargetFactory = this._targetFactories[''];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use "default" key for the default factory?

@@ -210,6 +210,10 @@ export class Context {
for (const page of browserContext.pages())
this._onPageCreated(page);
browserContext.on('page', page => this._onPageCreated(page));
browserContext.on('close', () => {
this._browserContextPromise = undefined;
this._closeBrowserContextPromise = undefined;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should resolve this promise in case there are waiting close calls?

].join('\n'),
inputSchema: z.object({
method: z.enum(factories.map(factory => factory.name) as [string, ...string[]]).default(factories[0].name).describe('The method to use to connect to the browser'),
method: z.enum(contextSwitchers.map(c => c.name) as [string, ...string[]]).describe('The method to use to connect to the browser'),
options: askForOptions ? z.any().optional().describe('options for the connection method') : z.void(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not define this parameter if askForOptions is false

name: factory.name,
description: factory.description,
switch: async () => {
await this._setContextFactory(factory);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like that we now mix them and have 2 ways to switch how we connect to the browser. Maybe migrate the context factories to the backend switchers as well or what is the plan?

this._extraEnv = env;
}

async startRunner(runnerParams: any, options: { onStdOut?: (chunk: Buffer | string) => void, onStdErr?: (chunk: Buffer | string) => void } = {}): Promise<ProcessExitData | undefined> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is Runner ?

const old = this._target;
old.onChangeProxyTarget = undefined;
this._target = target;
this._target.onChangeProxyTarget = this._handleChangeProxyTarget;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we have to assign onChangeProxyTarget to the target while we could just handle that particular tool call in this class ant spare all other backends from the knowledge about onChangeProxyTarget? Basically similar to how we switch between context factories but just intercept the backend switch call here.

@Skn0tt
Copy link
Member Author

Skn0tt commented Aug 12, 2025

Yury added a backend switcher in #854, so i'm rebasing this effort onto that. closing in favour of #868.

@Skn0tt Skn0tt closed this Aug 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants