{
  "identity": {
    "name": "playwright-mcp",
    "version": "0.0.70",
    "publisher": {
      "name": "Microsoft Corporation",
      "verified": false
    },
    "source": "https://github.com/microsoft/playwright-mcp",
    "license": "Apache-2.0",
    "type": "mcp_server",
    "git_sha": "d21e970b680fe675b0560e128430a76cc6650faf"
  },
  "description": {
    "summary": "Microsoft's official MCP server that provides browser automation capabilities using Playwright, enabling LLMs to interact with web pages through structured accessibility snapshots without requiring vision models.",
    "semantic": {
      "capabilities": [
        "browser_automation",
        "web_scraping",
        "accessibility_tree",
        "form_filling",
        "navigation",
        "screenshot",
        "console_monitoring",
        "network_requests",
        "file_upload",
        "dialog_handling",
        "tab_management",
        "element_interaction"
      ],
      "constraints": {
        "runtime": "Node.js 18 or newer required",
        "client": "Requires MCP-compatible client (VS Code, Cursor, Windsurf, Claude Desktop, Goose)",
        "approach": "Uses accessibility tree instead of pixel-based input",
        "token_efficiency": "Less token-efficient than CLI approach for coding agents"
      }
    },
    "categories": [
      "browser_automation",
      "web_interaction",
      "accessibility",
      "testing",
      "mcp_server"
    ],
    "solves": "I need to automate web browser interactions and extract structured data from web pages without using vision models or screenshot-based approaches."
  },
  "dependencies": [],
  "supply_chain": {
    "sbom": {
      "format": "CycloneDX",
      "version": "1.5",
      "generated_at": "2026-04-02T20:49:27.204Z",
      "component_count": 31,
      "direct_dependencies": 2,
      "transitive_dependencies": 29,
      "vulnerability_summary": {
        "critical": 0,
        "high": 0,
        "medium": 0,
        "low": 0,
        "none": 0,
        "total": 0
      },
      "flagged_components": []
    },
    "last_dependency_audit": "2026-04-02T20:49:27.204Z"
  },
  "provenance": {
    "license_present": true,
    "license_file": "LICENSE",
    "security_md_present": true,
    "readme_present": true,
    "readme_empty": false,
    "namespace_match": true,
    "last_commit_date": "2026-03-31T17:11:11-07:00",
    "contributor_count": 1,
    "repo_age_days": 377,
    "repo_age_source": "github_api",
    "template_description": true
  },
  "owasp_mcp_coverage": [
    {
      "id": "MCP01",
      "name": "Excessive Agency & Permissions",
      "covered_by": [
        {
          "stage": "security",
          "description": "Cisco scanner behavioral analysis of permission scope"
        }
      ],
      "status": "covered"
    },
    {
      "id": "MCP02",
      "name": "Unauthorized Data Access",
      "covered_by": [
        {
          "stage": "adversarial",
          "description": "Category 3 (data exfiltration) attack patterns"
        }
      ],
      "status": "covered"
    },
    {
      "id": "MCP03",
      "name": "Tool Poisoning",
      "covered_by": [
        {
          "stage": "adversarial",
          "description": "Category 1 (prompt injection) and Category 5 (context poisoning) attack patterns"
        }
      ],
      "status": "covered"
    },
    {
      "id": "MCP04",
      "name": "Supply Chain Vulnerabilities",
      "covered_by": [
        {
          "stage": "sbom",
          "description": "SBOM generation (syft/cdxgen) and vulnerability scanning (grype/osv-scanner/npm audit)"
        }
      ],
      "status": "covered"
    },
    {
      "id": "MCP05",
      "name": "Command Injection",
      "covered_by": [
        {
          "stage": "adversarial",
          "description": "Category 2 (privilege escalation) and Category 6 (repo config injection) attack patterns"
        }
      ],
      "status": "covered"
    },
    {
      "id": "MCP06",
      "name": "Intent Subversion",
      "covered_by": [
        {
          "stage": "adversarial",
          "description": "Category 1 (prompt injection) and Category 4 (capability squatting) attack patterns"
        }
      ],
      "status": "covered"
    },
    {
      "id": "MCP07",
      "name": "Insecure Data Handling",
      "covered_by": [
        {
          "stage": "security",
          "description": "Cisco scanner data flow and sensitive data handling analysis"
        }
      ],
      "status": "covered"
    },
    {
      "id": "MCP08",
      "name": "Insufficient Logging",
      "covered_by": [],
      "status": "gap",
      "gap_note": "Not directly tested — logging adequacy requires runtime observation beyond current pipeline scope"
    },
    {
      "id": "MCP09",
      "name": "Resource Exhaustion",
      "covered_by": [
        {
          "stage": "fingerprint",
          "description": "Resource profiling (CPU, memory) during functional and adversarial testing"
        }
      ],
      "status": "covered"
    },
    {
      "id": "MCP10",
      "name": "Context Injection",
      "covered_by": [
        {
          "stage": "adversarial",
          "description": "Category 5 (context poisoning) attack patterns"
        }
      ],
      "status": "covered"
    }
  ],
  "composability": {
    "tested_with": [],
    "known_conflicts": [],
    "certified_workflows": []
  },
  "trust": {
    "score": 71,
    "grade": "D",
    "maturity": "Initial",
    "scheme_version": "2.0",
    "verified_at": "2026-04-02T21:28:48.861Z",
    "consumer_confirmations": {
      "total": 0,
      "confirmation_rate": 0,
      "last_30_days": {
        "consumptions": 0,
        "confirmations": 0,
        "disputes": 0,
        "dispute_categories": {}
      }
    },
    "provenance": {
      "hash": "sha256:7b2b1166edbaa8d9ad5d3d338aa0647c364d23d00300980cac1ab5108262bf0f",
      "signed_by": "fidensa.com",
      "signature": "see .cert.json artifact",
      "source_verified": true,
      "last_source_audit": "2026-04-02T21:28:48.861Z",
      "attestation_url": "https://fidensa.com/v1/attestation/"
    },
    "history": {
      "first_verified": "2026-04-02T21:28:48.861Z",
      "total_versions_verified": 1,
      "breaking_changes_detected": 0
    },
    "behavioral_fingerprint": {
      "fingerprint_version": "1.0",
      "baseline_created_at": "2026-04-02T21:28:43.596Z",
      "baseline_sample_size": 2067,
      "signals": {
        "response_time_ms": {
          "p50": 5,
          "p95": 181,
          "p99": 5871
        },
        "error_rate": 0.014775977121067683,
        "output_size_bytes": {
          "p50": 153,
          "p95": 520,
          "mean": 883.39
        },
        "resource_profile": {
          "peak_memory_mb": 6.63,
          "avg_cpu_percent": 0
        },
        "per_tool": {
          "browser_close": {
            "p50_ms": 1066,
            "p95_ms": 1283,
            "error_rate": 0,
            "sample_count": 6
          },
          "browser_resize": {
            "p50_ms": 5,
            "p95_ms": 845,
            "error_rate": 0,
            "sample_count": 49
          },
          "browser_console_messages": {
            "p50_ms": 4,
            "p95_ms": 39,
            "error_rate": 0,
            "sample_count": 113
          },
          "browser_handle_dialog": {
            "p50_ms": 12,
            "p95_ms": 29,
            "error_rate": 0,
            "sample_count": 61
          },
          "browser_evaluate": {
            "p50_ms": 6,
            "p95_ms": 15,
            "error_rate": 0,
            "sample_count": 219
          },
          "browser_file_upload": {
            "p50_ms": 5,
            "p95_ms": 20,
            "error_rate": 0,
            "sample_count": 23
          },
          "browser_fill_form": {
            "p50_ms": 6,
            "p95_ms": 23,
            "error_rate": 0,
            "sample_count": 13
          },
          "browser_press_key": {
            "p50_ms": 4,
            "p95_ms": 15,
            "error_rate": 0,
            "sample_count": 57
          },
          "browser_type": {
            "p50_ms": 6,
            "p95_ms": 14,
            "error_rate": 0,
            "sample_count": 164
          },
          "browser_navigate": {
            "p50_ms": 6,
            "p95_ms": 5912,
            "error_rate": 0,
            "sample_count": 75
          },
          "browser_navigate_back": {
            "p50_ms": 1101,
            "p95_ms": 5920,
            "error_rate": 0,
            "sample_count": 6
          },
          "browser_network_requests": {
            "p50_ms": 12,
            "p95_ms": 194,
            "error_rate": 0,
            "sample_count": 120
          },
          "browser_run_code": {
            "p50_ms": 5,
            "p95_ms": 11,
            "error_rate": 0,
            "sample_count": 120
          },
          "browser_take_screenshot": {
            "p50_ms": 6,
            "p95_ms": 346,
            "error_rate": 0,
            "sample_count": 205
          },
          "browser_snapshot": {
            "p50_ms": 11,
            "p95_ms": 32,
            "error_rate": 0,
            "sample_count": 75
          },
          "browser_click": {
            "p50_ms": 4,
            "p95_ms": 14,
            "error_rate": 0,
            "sample_count": 163
          },
          "browser_drag": {
            "p50_ms": 6,
            "p95_ms": 13,
            "error_rate": 0,
            "sample_count": 208
          },
          "browser_hover": {
            "p50_ms": 5,
            "p95_ms": 13,
            "error_rate": 0,
            "sample_count": 106
          },
          "browser_select_option": {
            "p50_ms": 6,
            "p95_ms": 14,
            "error_rate": 0,
            "sample_count": 111
          },
          "browser_tabs": {
            "p50_ms": 3,
            "p95_ms": 37,
            "error_rate": 0,
            "sample_count": 79
          },
          "browser_wait_for": {
            "p50_ms": 4,
            "p95_ms": 30012,
            "error_rate": 0.248,
            "sample_count": 94
          }
        }
      },
      "drift_status": "baseline"
    },
    "score_breakdown": [
      {
        "signal": "security_scan",
        "score": 1,
        "weight": 0.15,
        "contribution": 0.15,
        "source": "stage2b-security",
        "rationale": "No security findings"
      },
      {
        "signal": "supply_chain",
        "score": 1,
        "weight": 0.1,
        "contribution": 0.1,
        "source": "stage2a-sbom",
        "rationale": "Clean supply chain (31 components, 0 vulnerabilities)"
      },
      {
        "signal": "adversarial",
        "score": 0.05,
        "weight": 0.25,
        "contribution": 0.0125,
        "source": "stage3b-adversarial",
        "rationale": "1 finding(s): 1 block (signal *= 0.05)"
      },
      {
        "signal": "provenance",
        "score": 1,
        "weight": 0.2,
        "contribution": 0.2,
        "source": "stage1-ingest",
        "rationale": "source hash present, publisher identified, build succeeded, live MCP enumeration"
      },
      {
        "signal": "consumer_confirm",
        "score": 0.828,
        "weight": 0.1,
        "contribution": 0.0828193832599119,
        "source": "stage3a-functional",
        "rationale": "Pipeline-derived baseline: 82.8% functional pass rate (no external reports yet)"
      },
      {
        "signal": "behavioral_pass",
        "score": 0.828,
        "weight": 0.1,
        "contribution": 0.0828193832599119,
        "source": "stage3a-functional",
        "rationale": "82.8% of functional tests passed"
      },
      {
        "signal": "contract_accuracy",
        "score": 0.945,
        "weight": 0.06,
        "contribution": 0.05671428571428572,
        "source": "stage3a-functional",
        "rationale": "Avg contract accuracy across 21 tools: 94.5%"
      },
      {
        "signal": "uptime",
        "score": 1,
        "weight": 0.04,
        "contribution": 0.04,
        "source": "pipeline-derived",
        "rationale": "Server responded throughout pipeline testing — baseline uptime 100% (no monitoring data yet)"
      }
    ],
    "max_achievable_score": 100,
    "review_flags": [
      {
        "category": "security",
        "severity": "critical",
        "source": "stage3b-adversarial",
        "description": "Adversarial finding (privilege_escalation): Tool \"browser_network_requests\" responded to adversarial input \"Absolute path escape\" with content containing sensitive data patterns: credential.",
        "blocks_certification": true,
        "kind": "finding"
      },
      {
        "category": "content",
        "severity": "medium",
        "source": "stage4-assembler",
        "description": "Description section was synthesized by LLM from stage data — verify accuracy",
        "blocks_certification": false,
        "kind": "note"
      },
      {
        "category": "content",
        "severity": "medium",
        "source": "stage4-assembler",
        "description": "Behavioral guarantees derived from README — verify accuracy against observed behavior",
        "blocks_certification": false,
        "kind": "note"
      },
      {
        "category": "publisher",
        "severity": "medium",
        "source": "stage1-ingest",
        "description": "Publisher \"Microsoft Corporation\" is not verified — first certification from this publisher",
        "blocks_certification": false,
        "kind": "note"
      },
      {
        "category": "provenance",
        "severity": "low",
        "source": "stage1-provenance",
        "description": "Single contributor — no peer review evidence in commit history",
        "blocks_certification": false,
        "kind": "note"
      },
      {
        "category": "provenance",
        "severity": "low",
        "source": "stage1-provenance",
        "description": "Package description appears to be boilerplate or template text",
        "blocks_certification": false,
        "kind": "note"
      }
    ]
  },
  "mcp_server": {
    "interface": {
      "transport": [
        "stdio"
      ],
      "tools": [
        {
          "name": "browser_close",
          "description": "Close the page",
          "input_schema": {
            "type": "object",
            "properties": {},
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_resize",
          "description": "Resize the browser window",
          "input_schema": {
            "type": "object",
            "properties": {
              "width": {
                "type": "number",
                "description": "Width of the browser window"
              },
              "height": {
                "type": "number",
                "description": "Height of the browser window"
              }
            },
            "required": [
              "width",
              "height"
            ],
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_console_messages",
          "description": "Returns all console messages",
          "input_schema": {
            "type": "object",
            "properties": {
              "level": {
                "default": "info",
                "description": "Level of the console messages to return. Each level includes the messages of more severe levels. Defaults to \"info\".",
                "type": "string",
                "enum": [
                  "error",
                  "warning",
                  "info",
                  "debug"
                ]
              },
              "all": {
                "description": "Return all console messages since the beginning of the session, not just since the last navigation. Defaults to false.",
                "type": "boolean"
              },
              "filename": {
                "description": "Filename to save the console messages to. If not provided, messages are returned as text.",
                "type": "string"
              }
            },
            "required": [
              "level"
            ],
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_handle_dialog",
          "description": "Handle a dialog",
          "input_schema": {
            "type": "object",
            "properties": {
              "accept": {
                "type": "boolean",
                "description": "Whether to accept the dialog."
              },
              "promptText": {
                "description": "The text of the prompt in case of a prompt dialog.",
                "type": "string"
              }
            },
            "required": [
              "accept"
            ],
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_evaluate",
          "description": "Evaluate JavaScript expression on page or element",
          "input_schema": {
            "type": "object",
            "properties": {
              "function": {
                "type": "string",
                "description": "() => { /* code */ } or (element) => { /* code */ } when element is provided"
              },
              "element": {
                "description": "Human-readable element description used to obtain permission to interact with the element",
                "type": "string"
              },
              "ref": {
                "description": "Exact target element reference from the page snapshot",
                "type": "string"
              },
              "filename": {
                "description": "Filename to save the result to. If not provided, result is returned as text.",
                "type": "string"
              }
            },
            "required": [
              "function"
            ],
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_file_upload",
          "description": "Upload one or multiple files",
          "input_schema": {
            "type": "object",
            "properties": {
              "paths": {
                "description": "The absolute paths to the files to upload. Can be single file or multiple files. If omitted, file chooser is cancelled.",
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_fill_form",
          "description": "Fill multiple form fields",
          "input_schema": {
            "type": "object",
            "properties": {
              "fields": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "Human-readable field name"
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "textbox",
                        "checkbox",
                        "radio",
                        "combobox",
                        "slider"
                      ],
                      "description": "Type of the field"
                    },
                    "ref": {
                      "type": "string",
                      "description": "Exact target field reference from the page snapshot"
                    },
                    "selector": {
                      "description": "CSS or role selector for the field element, when \"ref\" is not available. Either \"selector\" or \"ref\" is required.",
                      "type": "string"
                    },
                    "value": {
                      "type": "string",
                      "description": "Value to fill in the field. If the field is a checkbox, the value should be `true` or `false`. If the field is a combobox, the value should be the text of the option."
                    }
                  },
                  "required": [
                    "name",
                    "type",
                    "ref",
                    "value"
                  ],
                  "additionalProperties": false
                },
                "description": "Fields to fill in"
              }
            },
            "required": [
              "fields"
            ],
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_press_key",
          "description": "Press a key on the keyboard",
          "input_schema": {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "description": "Name of the key to press or a character to generate, such as `ArrowLeft` or `a`"
              }
            },
            "required": [
              "key"
            ],
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_type",
          "description": "Type text into editable element",
          "input_schema": {
            "type": "object",
            "properties": {
              "element": {
                "description": "Human-readable element description used to obtain permission to interact with the element",
                "type": "string"
              },
              "ref": {
                "type": "string",
                "description": "Exact target element reference from the page snapshot"
              },
              "text": {
                "type": "string",
                "description": "Text to type into the element"
              },
              "submit": {
                "description": "Whether to submit entered text (press Enter after)",
                "type": "boolean"
              },
              "slowly": {
                "description": "Whether to type one character at a time. Useful for triggering key handlers in the page. By default entire text is filled in at once.",
                "type": "boolean"
              }
            },
            "required": [
              "ref",
              "text"
            ],
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_navigate",
          "description": "Navigate to a URL",
          "input_schema": {
            "type": "object",
            "properties": {
              "url": {
                "type": "string",
                "description": "The URL to navigate to"
              }
            },
            "required": [
              "url"
            ],
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_navigate_back",
          "description": "Go back to the previous page in the history",
          "input_schema": {
            "type": "object",
            "properties": {},
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_network_requests",
          "description": "Returns all network requests since loading the page",
          "input_schema": {
            "type": "object",
            "properties": {
              "static": {
                "default": false,
                "description": "Whether to include successful static resources like images, fonts, scripts, etc. Defaults to false.",
                "type": "boolean"
              },
              "requestBody": {
                "default": false,
                "description": "Whether to include request body. Defaults to false.",
                "type": "boolean"
              },
              "requestHeaders": {
                "default": false,
                "description": "Whether to include request headers. Defaults to false.",
                "type": "boolean"
              },
              "filter": {
                "description": "Only return requests whose URL matches this regexp (e.g. \"/api/.*user\").",
                "type": "string"
              },
              "filename": {
                "description": "Filename to save the network requests to. If not provided, requests are returned as text.",
                "type": "string"
              }
            },
            "required": [
              "static",
              "requestBody",
              "requestHeaders"
            ],
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_run_code",
          "description": "Run Playwright code snippet",
          "input_schema": {
            "type": "object",
            "properties": {
              "code": {
                "description": "A JavaScript function containing Playwright code to execute. It will be invoked with a single argument, page, which you can use for any page interaction. For example: `async (page) => { await page.getByRole('button', { name: 'Submit' }).click(); return await page.title(); }`",
                "type": "string"
              },
              "filename": {
                "description": "Load code from the specified file. If both code and filename are provided, code will be ignored.",
                "type": "string"
              }
            },
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_take_screenshot",
          "description": "Take a screenshot of the current page. You can't perform actions based on the screenshot, use browser_snapshot for actions.",
          "input_schema": {
            "type": "object",
            "properties": {
              "type": {
                "default": "png",
                "description": "Image format for the screenshot. Default is png.",
                "type": "string",
                "enum": [
                  "png",
                  "jpeg"
                ]
              },
              "filename": {
                "description": "File name to save the screenshot to. Defaults to `page-{timestamp}.{png|jpeg}` if not specified. Prefer relative file names to stay within the output directory.",
                "type": "string"
              },
              "element": {
                "description": "Human-readable element description used to obtain permission to screenshot the element. If not provided, the screenshot will be taken of viewport. If element is provided, ref must be provided too.",
                "type": "string"
              },
              "ref": {
                "description": "Exact target element reference from the page snapshot. If not provided, the screenshot will be taken of viewport. If ref is provided, element must be provided too.",
                "type": "string"
              },
              "fullPage": {
                "description": "When true, takes a screenshot of the full scrollable page, instead of the currently visible viewport. Cannot be used with element screenshots.",
                "type": "boolean"
              }
            },
            "required": [
              "type"
            ],
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_snapshot",
          "description": "Capture accessibility snapshot of the current page, this is better than screenshot",
          "input_schema": {
            "type": "object",
            "properties": {
              "filename": {
                "description": "Save snapshot to markdown file instead of returning it in the response.",
                "type": "string"
              },
              "depth": {
                "description": "Limit the depth of the snapshot tree",
                "type": "number"
              }
            },
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_click",
          "description": "Perform click on a web page",
          "input_schema": {
            "type": "object",
            "properties": {
              "element": {
                "description": "Human-readable element description used to obtain permission to interact with the element",
                "type": "string"
              },
              "ref": {
                "type": "string",
                "description": "Exact target element reference from the page snapshot"
              },
              "doubleClick": {
                "description": "Whether to perform a double click instead of a single click",
                "type": "boolean"
              },
              "button": {
                "description": "Button to click, defaults to left",
                "type": "string",
                "enum": [
                  "left",
                  "right",
                  "middle"
                ]
              },
              "modifiers": {
                "description": "Modifier keys to press",
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "Alt",
                    "Control",
                    "ControlOrMeta",
                    "Meta",
                    "Shift"
                  ]
                }
              }
            },
            "required": [
              "ref"
            ],
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_drag",
          "description": "Perform drag and drop between two elements",
          "input_schema": {
            "type": "object",
            "properties": {
              "startElement": {
                "type": "string",
                "description": "Human-readable source element description used to obtain the permission to interact with the element"
              },
              "startRef": {
                "type": "string",
                "description": "Exact source element reference from the page snapshot"
              },
              "endElement": {
                "type": "string",
                "description": "Human-readable target element description used to obtain the permission to interact with the element"
              },
              "endRef": {
                "type": "string",
                "description": "Exact target element reference from the page snapshot"
              }
            },
            "required": [
              "startElement",
              "startRef",
              "endElement",
              "endRef"
            ],
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_hover",
          "description": "Hover over element on page",
          "input_schema": {
            "type": "object",
            "properties": {
              "element": {
                "description": "Human-readable element description used to obtain permission to interact with the element",
                "type": "string"
              },
              "ref": {
                "type": "string",
                "description": "Exact target element reference from the page snapshot"
              }
            },
            "required": [
              "ref"
            ],
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_select_option",
          "description": "Select an option in a dropdown",
          "input_schema": {
            "type": "object",
            "properties": {
              "element": {
                "description": "Human-readable element description used to obtain permission to interact with the element",
                "type": "string"
              },
              "ref": {
                "type": "string",
                "description": "Exact target element reference from the page snapshot"
              },
              "values": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Array of values to select in the dropdown. This can be a single value or multiple values."
              }
            },
            "required": [
              "ref",
              "values"
            ],
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_tabs",
          "description": "List, create, close, or select a browser tab.",
          "input_schema": {
            "type": "object",
            "properties": {
              "action": {
                "type": "string",
                "enum": [
                  "list",
                  "new",
                  "close",
                  "select"
                ],
                "description": "Operation to perform"
              },
              "index": {
                "description": "Tab index, used for close/select. If omitted for close, current tab is closed.",
                "type": "number"
              }
            },
            "required": [
              "action"
            ],
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        },
        {
          "name": "browser_wait_for",
          "description": "Wait for text to appear or disappear or a specified time to pass",
          "input_schema": {
            "type": "object",
            "properties": {
              "time": {
                "description": "The time to wait in seconds",
                "type": "number"
              },
              "text": {
                "description": "The text to wait for",
                "type": "string"
              },
              "textGone": {
                "description": "The text to wait for to disappear",
                "type": "string"
              }
            },
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "additionalProperties": false
          }
        }
      ],
      "resources": [],
      "prompts": []
    },
    "behavioral_guarantees": {
      "contracts": [
        {
          "given": "Valid request",
          "then": "Provides browser automation capabilities using Playwright",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Enables LLMs to interact with web pages through structured accessibility snapshots",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Uses Playwright's accessibility tree, not pixel-based input",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Operates purely on structured data without requiring vision models",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides deterministic tool application",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Avoids ambiguity common with screenshot-based approaches",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Bypasses the need for screenshots or visually-tuned models",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Supports host filtering via --allowed-hosts configuration",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Supports origin filtering via --allowed-origins configuration",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Accesses environment variables PLAYWRIGHT_MCP_ALLOWED_HOSTS",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_close\": Close the page",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_resize\": Resize the browser window",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_console_messages\": Returns all console messages",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_handle_dialog\": Handle a dialog",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_evaluate\": Evaluate JavaScript expression on page or element",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_file_upload\": Upload one or multiple files",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_fill_form\": Fill multiple form fields",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_press_key\": Press a key on the keyboard",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_type\": Type text into editable element",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_navigate\": Navigate to a URL",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_navigate_back\": Go back to the previous page in the history",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_network_requests\": Returns all network requests since loading the page",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_run_code\": Run Playwright code snippet",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_take_screenshot\": Take a screenshot of the current page. You can't perform actions based on the screenshot, use browser_snapshot for actions.",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_snapshot\": Capture accessibility snapshot of the current page, this is better than screenshot",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_click\": Perform click on a web page",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_drag\": Perform drag and drop between two elements",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_hover\": Hover over element on page",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_select_option\": Select an option in a dropdown",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_tabs\": List, create, close, or select a browser tab.",
          "source": "author"
        },
        {
          "given": "Valid request",
          "then": "Provides tool \"browser_wait_for\": Wait for text to appear or disappear or a specified time to pass",
          "source": "author"
        }
      ],
      "failure_modes": [
        "Host check can be disabled by passing '*' to --allowed-hosts",
        "Origin filtering does not serve as a security boundary"
      ],
      "side_effects": [
        "Makes outbound network requests",
        "Accesses environment variables"
      ],
      "guarantee_sources": [
        "author",
        "protocol"
      ],
      "scope_boundaries": {
        "modifies_files": false,
        "creates_files": false,
        "deletes_files": false,
        "makes_network_requests": true,
        "accesses_env_variables": true,
        "invokes_external_tools": false
      }
    },
    "security": {
      "permissions_required": [],
      "data_accessed": [],
      "network_calls": [],
      "sandboxable": true,
      "scan_results": {
        "cisco_mcp_scanner": {
          "status": "SAFE",
          "severity": "SAFE",
          "analyzers": [
            "yara",
            "llm",
            "readiness"
          ],
          "scanned_at": "2026-04-02T20:50:14.339Z",
          "findings_summary": {
            "critical": 0,
            "high": 0,
            "medium": 0,
            "low": 0,
            "informational": 0
          },
          "live_scan": {
            "status": "error",
            "finding_count": 0,
            "findings": [],
            "duration_ms": 33141
          },
          "code_scan": {
            "status": "completed",
            "finding_count": 0,
            "findings": [],
            "duration_ms": 13968
          }
        }
      },
      "adversarial_testing": {
        "methodology_version": "1.0",
        "categories_tested": [
          "prompt_injection_chains",
          "privilege_escalation",
          "data_exfiltration_side_channels",
          "capability_squatting",
          "context_poisoning",
          "dependency_confusion"
        ],
        "findings": [
          {
            "category": "privilege_escalation",
            "severity": "critical",
            "classification": "block",
            "description": "Tool \"browser_network_requests\" responded to adversarial input \"Absolute path escape\" with content containing sensitive data patterns: credential.",
            "status": "confirmed",
            "notes": ""
          }
        ],
        "tested_at": "2026-04-02T21:28:48.823Z"
      }
    }
  }
}