Skip to content

Commit 08f98e4

Browse files
committed
added a validation step to detect a profile mismatch
1 parent 0abdf77 commit 08f98e4

3 files changed

Lines changed: 41 additions & 2 deletions

File tree

src/browser.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,21 @@ function makeTargetFilter() {
4343
};
4444
}
4545

46+
//Extracts the profile directory name from a user data dir path.
47+
function getProfileNameFromUserDataDir(userDataDir: string): string {
48+
const normalized = userDataDir.replace(/\\/g, '/');
49+
const parts = normalized.split('/');
50+
return parts[parts.length - 1] || 'Default';
51+
}
52+
4653
export async function ensureBrowserConnected(options: {
4754
browserURL?: string;
4855
wsEndpoint?: string;
4956
wsHeaders?: Record<string, string>;
5057
devtools: boolean;
5158
channel?: Channel;
5259
userDataDir?: string;
60+
profileDirectory?: string;
5361
}) {
5462
const {channel} = options;
5563
if (browser?.connected) {
@@ -126,6 +134,36 @@ export async function ensureBrowserConnected(options: {
126134
},
127135
);
128136
}
137+
138+
if (options.profileDirectory && options.userDataDir) {
139+
try {
140+
const portPath = path.join(options.userDataDir, 'DevToolsActivatePort');
141+
const fileContent = await fs.promises.readFile(portPath, 'utf8');
142+
const lines = fileContent.split('\n').map(line => line.trim()).filter(line => line);
143+
144+
if (lines.length >= 2) {
145+
const browserPath = lines[1];
146+
const actualProfile = getProfileNameFromUserDataDir(browserPath);
147+
const requestedProfile = options.profileDirectory;
148+
149+
if (actualProfile !== requestedProfile) {
150+
await browser.disconnect();
151+
throw new Error(
152+
`Profile mismatch: Requested profile "${requestedProfile}" but Chrome is running with profile "${actualProfile}". ` +
153+
`Please close Chrome and restart with the correct profile, or remove the --profile-directory flag.`
154+
);
155+
}
156+
157+
logger(`Successfully validated profile: ${actualProfile}`);
158+
}
159+
} catch (error) {
160+
if ((error as Error).message.includes('Profile mismatch')) {
161+
throw error;
162+
}
163+
164+
logger('Could not validate profile directory: ', error);
165+
}
166+
}
129167
logger('Connected Puppeteer');
130168
return browser;
131169
}

src/cli.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,10 @@ export const cliOptions = {
200200
},
201201
profileDirectory: {
202202
type: 'string',
203-
description:
204-
'Specify which Chrome profile to use by specifying its directory name (e.g., "Profile 1", "Default") inside a chrome user data directory. Only works with --autoConnect or when launching Chrome via the Chrome DevTools MCP server.',
203+
description: 'Specify which Chrome profile to use by specifying its directory name (e.g., "Profile 1", "Default") inside a chrome user data directory. Only works with --autoConnect or when launching Chrome via the Chrome DevTools MCP server.',
205204
alias: 'profile-dir',
206205
conflicts: ['browserUrl', 'wsEndpoint'],
206+
},
207207
usageStatistics: {
208208
type: 'boolean',
209209
// Marked as `false` until the feature is ready to be enabled by default.

src/main.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ async function getContext(): Promise<McpContext> {
7272
channel: args.autoConnect ? (args.channel as Channel) : undefined,
7373
userDataDir: args.userDataDir,
7474
devtools,
75+
profileDirectory: args.profileDirectory,
7576
})
7677
: await ensureBrowserLaunched({
7778
headless: args.headless,

0 commit comments

Comments
 (0)