feat: implement centralized artifact storage with session isolation

Add comprehensive artifact storage system with session-specific directories:

- Add --artifact-dir CLI option and PLAYWRIGHT_MCP_ARTIFACT_DIR env var
- Create ArtifactManager class for session-specific artifact organization
- Implement ArtifactManagerRegistry for multi-session support
- Add tool call logging with JSON persistence in tool-calls.json
- Update screenshot, video, and PDF tools to use centralized storage
- Add browser_configure_artifacts tool for per-session control
- Support dynamic enable/disable without server restart
- Maintain backward compatibility when artifact storage not configured

Directory structure: {artifactDir}/{sessionId}/[artifacts, videos/, tool-calls.json]

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ryan Malloy 2025-08-15 06:42:16 -06:00
parent ecedcc48d6
commit d8202f6694
12 changed files with 727 additions and 93 deletions

View file

@ -24,6 +24,7 @@ import type { BrowserContextOptions, LaunchOptions } from 'playwright';
export type CLIOptions = {
allowedOrigins?: string[];
artifactDir?: string;
blockedOrigins?: string[];
blockServiceWorkers?: boolean;
browser?: string;
@ -81,6 +82,7 @@ export type FullConfig = Config & {
},
network: NonNullable<Config['network']>,
outputDir: string;
artifactDir?: string;
server: NonNullable<Config['server']>,
};
@ -131,9 +133,9 @@ export function configFromCLIOptions(cliOptions: CLIOptions): Config {
channel,
executablePath: cliOptions.executablePath,
};
if (cliOptions.headless !== undefined) {
if (cliOptions.headless !== undefined)
launchOptions.headless = cliOptions.headless;
}
// --no-sandbox was passed, disable the sandbox
if (cliOptions.sandbox === false)
@ -196,6 +198,7 @@ export function configFromCLIOptions(cliOptions: CLIOptions): Config {
saveSession: cliOptions.saveSession,
saveTrace: cliOptions.saveTrace,
outputDir: cliOptions.outputDir,
artifactDir: cliOptions.artifactDir,
imageResponses: cliOptions.imageResponses,
};
@ -205,6 +208,7 @@ export function configFromCLIOptions(cliOptions: CLIOptions): Config {
function configFromEnv(): Config {
const options: CLIOptions = {};
options.allowedOrigins = semicolonSeparatedList(process.env.PLAYWRIGHT_MCP_ALLOWED_ORIGINS);
options.artifactDir = envToString(process.env.PLAYWRIGHT_MCP_ARTIFACT_DIR);
options.blockedOrigins = semicolonSeparatedList(process.env.PLAYWRIGHT_MCP_BLOCKED_ORIGINS);
options.blockServiceWorkers = envToBoolean(process.env.PLAYWRIGHT_MCP_BLOCK_SERVICE_WORKERS);
options.browser = envToString(process.env.PLAYWRIGHT_MCP_BROWSER);