Skip to content

browser_take_screenshot: custom filenames bypass --output-dir, save to workspace root instead #1390

@LeeorNahum

Description

@LeeorNahum

Description

When --output-dir is configured, browser_take_screenshot only respects it for auto-generated filenames. Custom filenames bypass --output-dir entirely and save to the workspace root.

Scenario Where file saves Expected
No filename (auto-generated page-{timestamp}.png) --output-dir Correct
Custom filename (e.g. test.png) Workspace root ❌ Should go to --output-dir

Steps to Reproduce

  1. Start the MCP server with --output-dir /tmp/playwright-mcp
  2. Navigate to any page
  3. Call browser_take_screenshot without a filename → file saves to /tmp/playwright-mcp/page-{timestamp}.png
  4. Call browser_take_screenshot with filename: "test.png" → file saves to {workspace}/test.png

Root Cause

In response.ts, the resolveClientFile method uses workspaceFile() when a suggestedFilename is provided, but outputFile() when no filename is given:

async resolveClientFile(template: FilenameTemplate, title: string): Promise<ResolvedFile> {
    let fileName: string;
    if (template.suggestedFilename)
      fileName = await this._context.workspaceFile(template.suggestedFilename, this._clientWorkspace);  // ← workspace root
    else
      fileName = await this._context.outputFile(template, { origin: 'llm' });  // ← --output-dir

Both paths should use outputFile(). The context.outputFile() method already handles suggestedFilename correctly — it uses it as the basename and resolves against outputDir. The checkFile() security check still validates the path is within allowed directories.

Proposed Fix

One-line change in packages/playwright/src/mcp/browser/response.ts:

   if (template.suggestedFilename)
-    fileName = await this._context.workspaceFile(template.suggestedFilename, this._clientWorkspace);
+    fileName = await this._context.outputFile(template, { origin: 'llm' });

I have a PR ready with this fix targeting microsoft/playwright.

Related Issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions