How Isolated Mode Manages Temporary User Data Directories in Chrome DevTools MCP
TLDR: Chrome DevTools MCP's --isolated flag forces every browser instance to use a disposable temporary profile stored in the OS temp directory, which Puppeteer automatically cleans up when the browser closes, preventing profile conflicts between concurrent sessions.
When automating Chrome through the Model Context Protocol (MCP), managing user data directories becomes critical for preventing profile corruption and enabling parallel browser instances. The ChromeDevTools/chrome-devtools-mcp repository provides an isolated mode that manages temporary user data directories by delegating profile creation to Puppeteer's built-in temporary directory mechanism. This approach eliminates the need for manual cleanup while ensuring complete separation between browser sessions.
What Is Isolated Mode?
Isolated mode is a launch configuration that creates a fresh, temporary Chrome profile for every browser instance. Unlike the default persistent mode—which caches user data in $HOME/.cache/chrome-devtools-mcp for faster subsequent launches—isolated mode ensures that no data persists between sessions. This is essential when running multiple browser instances simultaneously or when you need a guaranteed clean state for each automation task.
How the --isolated Flag Works
The isolated mode functionality flows through three core components: the CLI argument parser, the main entry point, and the browser launcher.
CLI Option Definition in src/cli.ts
The --isolated flag is defined in src/cli.ts as a boolean option with a clear description of its cleanup behavior:
// src/cli.ts (lines 101-105)
{
name: 'isolated',
type: Boolean,
description: 'creates a temporary user-data-dir that is automatically cleaned up after the browser is closed',
}
This definition makes the flag available to users running the MCP server from the command line.
Propagation to the Launcher in src/main.ts
Once parsed, the isolated value is stored in args.isolated and forwarded to the launch routine. In src/main.ts, the argument is passed through to the browser launch configuration:
// src/main.ts (lines 101-104)
const browser = await launch({
...launchOptions,
isolated: args.isolated,
});
This propagation ensures that the CLI flag ultimately controls the browser launch behavior.
Launch Logic and Temporary Directory Management
The core logic for managing temporary user data directories resides in src/browser.ts, where the launch function determines which profile strategy to use based on the isolated flag.
Conditional userDataDir Creation in src/browser.ts
The launch function in src/browser.ts (lines 138-141) receives an McpLaunchOptions object containing the isolated boolean. The implementation uses a conditional block to decide whether to create a persistent directory:
// src/browser.ts
let userDataDir = options.userDataDir;
if (!isolated && !userDataDir) {
// Non-isolated mode: reuse a persistent directory under $HOME/.cache/chrome-devtools-mcp
userDataDir = path.join(os.homedir(), '.cache', 'chrome-devtools-mcp', profileDirName);
await fs.promises.mkdir(userDataDir, {recursive: true});
}
When isolated is true, this block is skipped entirely, leaving userDataDir as undefined.
Puppeteer's Built-in Cleanup Mechanism
By leaving userDataDir undefined, the implementation delegates temporary directory management to Puppeteer. When puppeteer.launch receives no userDataDir option, it automatically:
- Creates a temporary Chrome profile in the operating system's temp directory (
os.tmpdir()) - Launches Chrome with this disposable profile
- Deletes the temporary directory when the browser process exits
This mechanism requires no explicit cleanup code in the MCP implementation because Chrome itself handles the removal of the temporary user data directory.
Error Handling for Profile Conflicts
When running in non-isolated mode, attempting to launch a second browser instance using the same persistent profile triggers an error. The launch function in src/browser.ts (lines 221-227) catches this condition and provides a helpful message:
// src/browser.ts (lines 221-227)
if (error.message.includes('user data directory is already in use')) {
throw new Error(
`Failed to launch browser: user data directory is already in use. ` +
`Try using the --isolated flag to create a temporary profile.`
);
}
This error handling explicitly guides users toward the --isolated flag when they encounter profile locking issues.
Implementation Examples
Command-Line Usage
To start the MCP server with a fresh, disposable Chrome profile, pass the --isolated flag:
# Start MCP with a temporary user data directory
npx chrome-devtools-mcp@latest --headless --isolated \
--executable-path "$(which chrome)"
This configuration ensures that Chrome launches with a temporary profile in the OS temp directory, which is automatically removed when the browser closes.
Programmatic Usage (TypeScript)
When using the browser launcher directly in TypeScript, set the isolated option to true:
import {launch} from './src/browser.js';
async function startIsolatedBrowser() {
const browser = await launch({
headless: true,
isolated: true, // Enables temporary profile mode
executablePath: '/usr/bin/google-chrome-stable',
devtools: false,
});
// Use the browser instance...
await browser.close(); // Temporary profile is removed automatically
}
By omitting the userDataDir option and setting isolated: true, you delegate temporary directory management to Puppeteer's built-in mechanism.
Switching Between Isolated and Persistent Modes
The following example demonstrates how to configure both modes:
import {launch} from './src/browser.js';
// Persistent mode: Reuses a cached profile under $HOME/.cache/chrome-devtools-mcp
await launch({
headless: true,
isolated: false, // Default behavior
userDataDir: '/my/custom/profile', // Optional explicit location
executablePath: '/usr/bin/chrome',
});
// Isolated mode: Clean, throw-away profile
await launch({
headless: true,
isolated: true,
executablePath: '/usr/bin/chrome',
});
Testing Isolated Mode
The repository includes comprehensive tests verifying the isolated mode functionality.
End-to-End Verification
The test suite in tests/index.test.ts (lines 22-31) validates the full client-server flow with the --isolated flag:
// tests/index.test.ts (lines 22-31)
test('should work with isolated mode', async () => {
const client = new Client(
{
command: 'node',
args: [
'--experimental-strip-types',
'src/main.ts',
'--isolated', // Enable isolated mode for testing
],
},
// ... transport config
);
});
Profile Conflict Detection
Unit tests in tests/browser.test.ts (lines 36-42) verify that the correct error message appears when attempting to reuse a non-isolated profile:
// tests/browser.test.ts (lines 36-42)
test('should throw an error when trying to use the same profile twice', async () => {
const browser = await launch({headless: true});
await expect(launch({headless: true})).rejects.toThrow(
/Try using the --isolated flag/
);
await browser.close();
});
These tests ensure that isolated mode correctly manages temporary user data directories and provides clear guidance when profile conflicts occur.
Summary
- Isolated mode in Chrome DevTools MCP creates a fresh, temporary Chrome profile for every browser instance by passing
isolated: trueto the launch function. - The
--isolatedCLI flag is defined insrc/cli.tsand propagated throughsrc/main.tsto the browser launcher insrc/browser.ts. - When
isolatedis enabled, the launcher skips creating the persistent cache directory under$HOME/.cache/chrome-devtools-mcp, leavinguserDataDirundefined. - Puppeteer automatically creates and cleans up a temporary user data directory in the OS temp folder when
userDataDiris not specified, requiring no explicit cleanup code. - Non-isolated mode reuses persistent profiles for faster subsequent launches, but triggers an error suggesting
--isolatedwhen attempting concurrent access to the same profile.
Frequently Asked Questions
What happens to temporary user data when the browser closes in isolated mode?
When running in isolated mode, Puppeteer automatically deletes the temporary user data directory when the browser process exits. Because the userDataDir parameter remains undefined in src/browser.ts, Puppeteer creates the profile in the operating system's temp directory and handles complete cleanup internally without requiring explicit deletion code in the MCP implementation.
Can I specify a custom user data directory while using isolated mode?
No, specifying a custom userDataDir while setting isolated: true would be contradictory. Isolated mode specifically works by not setting a userDataDir, which triggers Puppeteer's temporary profile mechanism. If you need a specific persistent directory, use non-isolated mode with the userDataDir option explicitly set, though this prevents running multiple instances simultaneously.
How do I resolve "user data directory is already in use" errors?
When you encounter this error in non-isolated mode, it indicates another Chrome instance is using the persistent profile under $HOME/.cache/chrome-devtools-mcp. You have two options: close the existing browser instance, or launch with the --isolated flag to create a separate temporary profile. The error handling in src/browser.ts (lines 221-227) explicitly suggests using --isolated for this scenario.
Does isolated mode affect browser startup performance?
Isolated mode may have a slight performance impact on the first launch because Chrome must initialize a fresh profile rather than reusing cached data. However, this trade-off provides guaranteed isolation between sessions and eliminates profile corruption risks. For CI/CD pipelines or parallel testing scenarios where multiple browser instances run simultaneously, isolated mode is essential despite any minor startup overhead.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →