forked from jsnbuchanan/crowd-funder-for-time-pwa
docs: reorganize documentation structure with 7-item folder limits
- Create logical sub-folder classification for all documentation - Organize 91 migration files into component-specific folders - Separate user guides, build system, migration, and development docs - Maintain maximum 7 items per folder for easy navigation - Add comprehensive README and reorganization summary - Ensure all changes tracked in git with proper versioning Structure: - user-guides/ (3 items): user-facing documentation - build-system/ (3 items): core, platforms, automation - migration/ (6 items): assessments, testing, templates - development/ (4 items): tools and standards - architecture/, testing/, examples/ (ready for future docs) Total: 24 folders created, all within 7-item limits
This commit is contained in:
677
docs/development/chrome_devtools.md
Normal file
677
docs/development/chrome_devtools.md
Normal file
@@ -0,0 +1,677 @@
|
||||
# Chrome DevTools MCP
|
||||
|
||||
A Model Context Protocol (MCP) server that provides Chrome DevTools Protocol integration through MCP. This allows you to debug web applications by connecting to Chrome's developer tools.
|
||||
|
||||
**Available as a Claude Desktop Extension (.dxt)** for easy one-click installation!
|
||||
|
||||
## What This Does
|
||||
|
||||
This MCP server acts as a bridge between Claude and Chrome's debugging capabilities. Once installed in Claude Desktop, you can:
|
||||
- Connect Claude to any web application running in Chrome
|
||||
- Debug network requests, console errors, and performance issues
|
||||
- Inspect JavaScript objects and execute code in the browser context
|
||||
- Monitor your application in real-time through natural conversation with Claude
|
||||
|
||||
**Note**: This is an MCP server that runs within Claude Desktop - you don't need to run any separate servers or processes.
|
||||
|
||||
## Features
|
||||
|
||||
- **Network Monitoring**: Capture and analyse HTTP requests/responses with filtering options
|
||||
- **Console Integration**: Read browser console logs, analyse errors, and execute JavaScript
|
||||
- **Performance Metrics**: Timing data, resource loading, and memory utilisation
|
||||
- **Page Inspection**: DOM information, page metrics, and multi-frame support
|
||||
- **Storage Access**: Read cookies, localStorage, and sessionStorage
|
||||
- **Real-time Monitoring**: Live console output tracking
|
||||
- **Object Inspection**: Inspect JavaScript objects and variables
|
||||
|
||||
## Installation
|
||||
|
||||
### Option 1: Claude Desktop Extension (Easiest)
|
||||
|
||||
**Download the pre-built extension:**
|
||||
1. Download the latest `.dxt` file from [Releases](https://github.com/benjaminr/chrome-devtools-mcp/releases)
|
||||
2. Open Claude Desktop
|
||||
3. Go to Extensions and install the downloaded `.dxt` file
|
||||
4. Configure Chrome path if needed in extension settings
|
||||
|
||||
The extension includes all dependencies and is ready to use immediately!
|
||||
|
||||
### Option 2: MCP CLI (Advanced)
|
||||
|
||||
**Quick Install (most common):**
|
||||
```bash
|
||||
git clone https://github.com/benjaminr/chrome-devtools-mcp.git
|
||||
cd chrome-devtools-mcp
|
||||
mcp install server.py -n "Chrome DevTools MCP" --with-editable .
|
||||
```
|
||||
|
||||
**All Installation Options:**
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone https://github.com/benjaminr/chrome-devtools-mcp.git
|
||||
cd chrome-devtools-mcp
|
||||
|
||||
# The --with-editable flag uses pyproject.toml to install dependencies
|
||||
|
||||
# Basic installation with local dependencies
|
||||
mcp install server.py --with-editable .
|
||||
|
||||
# Install with custom name
|
||||
mcp install server.py -n "Chrome DevTools MCP" --with-editable .
|
||||
|
||||
# Install with environment variables
|
||||
mcp install server.py -n "Chrome DevTools MCP" --with-editable . -v CHROME_DEBUG_PORT=9222
|
||||
|
||||
# Install with additional packages if needed
|
||||
mcp install server.py -n "Chrome DevTools MCP" --with-editable . --with websockets --with aiohttp
|
||||
|
||||
# Install with environment file (copy .env.example to .env first)
|
||||
cp .env.example .env
|
||||
# Edit .env with your settings
|
||||
mcp install server.py -n "Chrome DevTools MCP" --with-editable . -f .env
|
||||
```
|
||||
|
||||
### Option 3: Claude Code Integration
|
||||
|
||||
**For Claude Code CLI users:**
|
||||
|
||||
1. **Clone this repository**
|
||||
```bash
|
||||
git clone https://github.com/benjaminr/chrome-devtools-mcp.git
|
||||
cd chrome-devtools-mcp
|
||||
```
|
||||
|
||||
2. **Install dependencies**
|
||||
```bash
|
||||
uv sync # or pip install -r requirements.txt
|
||||
```
|
||||
|
||||
3. **Add MCP server using Claude CLI**
|
||||
|
||||
**Quick setup (recommended):**
|
||||
```bash
|
||||
# Add the server with environment variable
|
||||
claude mcp add chrome-devtools python server.py -e CHROME_DEBUG_PORT=9222
|
||||
```
|
||||
|
||||
**With custom scope:**
|
||||
```bash
|
||||
# Add to user scope (available across all projects)
|
||||
claude mcp add chrome-devtools python server.py -s user -e CHROME_DEBUG_PORT=9222
|
||||
|
||||
# Add to project scope (only for this project)
|
||||
claude mcp add chrome-devtools python server.py -s project -e CHROME_DEBUG_PORT=9222
|
||||
```
|
||||
|
||||
4. **Verify installation**
|
||||
```bash
|
||||
# List configured MCP servers
|
||||
claude mcp list
|
||||
|
||||
# Get details about the server
|
||||
claude mcp get chrome-devtools
|
||||
```
|
||||
|
||||
### Option 4: Manual Claude Desktop Setup
|
||||
|
||||
1. **Clone this repository**
|
||||
```bash
|
||||
git clone https://github.com/benjaminr/chrome-devtools-mcp.git
|
||||
cd chrome-devtools-mcp
|
||||
```
|
||||
|
||||
2. **Install dependencies**
|
||||
|
||||
**With uv (recommended):**
|
||||
```bash
|
||||
uv sync
|
||||
```
|
||||
|
||||
**With pip:**
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
3. **Add to Claude Desktop configuration**
|
||||
|
||||
Edit your Claude Desktop config file:
|
||||
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
||||
- **Windows**: `%APPDATA%/Claude/claude_desktop_config.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"chrome-devtools": {
|
||||
"command": "python",
|
||||
"args": ["/absolute/path/to/chrome-devtools-mcp/server.py"],
|
||||
"env": {
|
||||
"CHROME_DEBUG_PORT": "9222"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
4. **Restart Claude Desktop**
|
||||
|
||||
### Verify Installation
|
||||
|
||||
After installation (either method), verify the server is available:
|
||||
1. Open Claude Desktop
|
||||
2. Look for MCP tools in the conversation
|
||||
3. Try a simple command: `get_connection_status()`
|
||||
|
||||
### Alternative MCP Clients
|
||||
|
||||
For other MCP clients, run the server directly:
|
||||
```bash
|
||||
python server.py
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
Once installed in Claude Desktop, you can start debugging any web application:
|
||||
|
||||
### Debug Your Web Application
|
||||
|
||||
**One-step setup (recommended):**
|
||||
```
|
||||
start_chrome_and_connect("localhost:3000")
|
||||
```
|
||||
*Replace `localhost:3000` with your application's URL*
|
||||
|
||||
**If Chrome isn't found automatically:**
|
||||
```
|
||||
start_chrome_and_connect("localhost:3000", chrome_path="/path/to/chrome")
|
||||
```
|
||||
*Use the `chrome_path` parameter to specify a custom Chrome location*
|
||||
|
||||
This command will:
|
||||
- Start Chrome with debugging enabled
|
||||
- Navigate to your application
|
||||
- Connect the MCP server to Chrome
|
||||
|
||||
**Manual setup (if you prefer step-by-step):**
|
||||
```
|
||||
start_chrome()
|
||||
navigate_to_url("localhost:3000")
|
||||
connect_to_browser()
|
||||
```
|
||||
|
||||
### Start Debugging
|
||||
|
||||
Once connected, use these commands:
|
||||
- `get_network_requests()` - View HTTP traffic
|
||||
- `get_console_error_summary()` - Analyse JavaScript errors
|
||||
- `inspect_console_object("window")` - Inspect any JavaScript object
|
||||
|
||||
## Available MCP Tools
|
||||
|
||||
### Chrome Management
|
||||
- `start_chrome(port?, url?, headless?, chrome_path?, auto_connect?)` - Start Chrome with remote debugging and optional auto-connection
|
||||
- `start_chrome_and_connect(url, port?, headless?, chrome_path?)` - Start Chrome, connect, and navigate in one step
|
||||
- `connect_to_browser(port?)` - Connect to existing Chrome instance
|
||||
- `navigate_to_url(url)` - Navigate to a specific URL
|
||||
- `disconnect_from_browser()` - Disconnect from browser
|
||||
- `get_connection_status()` - Check connection status
|
||||
|
||||
### Network Monitoring
|
||||
- `get_network_requests(filter_domain?, filter_status?, limit?)` - Get network requests with filtering
|
||||
- `get_network_response(request_id)` - Get detailed response data including body
|
||||
|
||||
### Console Tools
|
||||
- `get_console_logs(level?, limit?)` - Get browser console logs
|
||||
- `get_console_error_summary()` - Get organized summary of errors and warnings
|
||||
- `execute_javascript(code)` - Execute JavaScript in browser context
|
||||
- `clear_console()` - Clear the browser console
|
||||
- `inspect_console_object(expression)` - Deep inspect any JavaScript object
|
||||
- `monitor_console_live(duration_seconds)` - Monitor console output in real-time
|
||||
|
||||
### Page Analysis
|
||||
- `get_page_info()` - Get comprehensive page metrics and performance data
|
||||
- `evaluate_in_all_frames(code)` - Execute JavaScript in all frames/iframes
|
||||
- `get_performance_metrics()` - Get detailed performance metrics and resource timing
|
||||
|
||||
### Storage & Data
|
||||
- `get_storage_usage_and_quota(origin)` - Get storage usage and quota information
|
||||
- `clear_storage_for_origin(origin, storage_types?)` - Clear storage by type and origin
|
||||
- `get_all_cookies()` - Get all browser cookies
|
||||
- `clear_all_cookies()` - Clear all browser cookies
|
||||
- `set_cookie(name, value, domain, path?, expires?, http_only?, secure?, same_site?)` - Set a cookie
|
||||
- `get_cookies(domain?)` - Get browser cookies with optional domain filtering
|
||||
- `get_storage_key_for_frame(frame_id)` - Get storage key for a specific frame
|
||||
- `track_cache_storage(origin, enable?)` - Enable/disable cache storage tracking
|
||||
- `track_indexeddb(origin, enable?)` - Enable/disable IndexedDB tracking
|
||||
- `override_storage_quota(origin, quota_size_mb?)` - Override storage quota
|
||||
|
||||
## Use Cases
|
||||
|
||||
### Debugging API Calls in Your Web Application
|
||||
|
||||
When your web application makes API calls that fail or return unexpected data:
|
||||
|
||||
**Easy setup:** Use the one-step command to start Chrome and navigate to your app:
|
||||
|
||||
**Example workflow:**
|
||||
```
|
||||
You: "I need to debug my React app at localhost:3000"
|
||||
Claude: I'll start Chrome with debugging enabled and navigate to your app.
|
||||
|
||||
start_chrome_and_connect("localhost:3000")
|
||||
|
||||
Perfect! Chrome is now running with debugging enabled and connected to your app. Let me check for any failed network requests:
|
||||
|
||||
get_network_requests(filter_status=500)
|
||||
|
||||
I can see there are 3 failed requests to your API. Let me get the details of the first one:
|
||||
|
||||
get_network_response("request-123")
|
||||
```
|
||||
|
||||
**Manual setup (if you prefer):**
|
||||
1. **Start Chrome**: Use `start_chrome()`
|
||||
2. **Navigate to your app**: Use `navigate_to_url("localhost:3000")`
|
||||
3. **Connect**: Use `connect_to_browser()`
|
||||
4. **Monitor network traffic**: Use `get_network_requests()` to see all API calls
|
||||
|
||||
### Checking JavaScript Console Errors
|
||||
|
||||
When your web application has JavaScript errors or unexpected behaviour:
|
||||
|
||||
1. **Navigate to your application** in the connected Chrome instance
|
||||
2. **Check for console errors**: Use `get_console_error_summary()` to see all errors
|
||||
3. **Monitor live errors**: Use `monitor_console_live(10)` to watch for new errors as you interact
|
||||
4. **Inspect variables**: Use `inspect_console_object("myVariable")` to examine application state
|
||||
|
||||
**Example workflow:**
|
||||
```
|
||||
You: "My React component isn't updating properly"
|
||||
Claude: Let me check the JavaScript console for any errors.
|
||||
|
||||
get_console_error_summary()
|
||||
|
||||
I can see there are 2 JavaScript errors. Let me also monitor the console while you interact with the component:
|
||||
|
||||
monitor_console_live(15)
|
||||
|
||||
Now try clicking the component that isn't working. I'll watch for any new errors or warnings.
|
||||
```
|
||||
|
||||
### Performance Debugging
|
||||
|
||||
When your web application loads slowly or uses too much memory:
|
||||
|
||||
1. **Load your application** in the connected browser
|
||||
2. **Check page metrics**: Use `get_page_info()` to see load times and resource counts
|
||||
3. **Analyse performance**: Use `get_performance_metrics()` to see detailed timing data
|
||||
4. **Monitor memory usage**: Check the memory information in the performance metrics
|
||||
|
||||
**Example workflow:**
|
||||
```
|
||||
You: "My application takes too long to load"
|
||||
Claude: Let me analyse the performance of your application.
|
||||
|
||||
get_page_info()
|
||||
|
||||
I can see your page has 47 scripts and took 3.2 seconds to load. Let me get more detailed performance data:
|
||||
|
||||
get_performance_metrics()
|
||||
|
||||
The main bottleneck is the initial JavaScript bundle which is 2.1MB. The DOM processing also takes 800ms.
|
||||
```
|
||||
|
||||
### Debugging Authentication Issues
|
||||
|
||||
When login or session management isn't working:
|
||||
|
||||
1. **Navigate to your login page**
|
||||
2. **Check cookies**: Use `get_cookies()` to see authentication cookies
|
||||
3. **Monitor network during login**: Use `monitor_console_live()` and `get_network_requests()` during the login process
|
||||
4. **Examine stored data**: Use JavaScript execution to check localStorage/sessionStorage
|
||||
|
||||
**Example workflow:**
|
||||
```
|
||||
You: "Users can't stay logged in"
|
||||
Claude: Let me check the authentication setup.
|
||||
|
||||
get_cookies()
|
||||
|
||||
I can see the auth cookie is present. Let me check what happens during login by monitoring the network:
|
||||
|
||||
get_network_requests(filter_domain="your-api.com")
|
||||
|
||||
I notice the login request returns a 200 but no Set-Cookie header. Let me also check localStorage:
|
||||
|
||||
execute_javascript("Object.keys(localStorage)")
|
||||
```
|
||||
|
||||
### DOM Element Inspection
|
||||
- `get_document(depth?, pierce?)` - Retrieve DOM document structure
|
||||
- `query_selector(node_id, selector)` - Find single element by CSS selector
|
||||
- `query_selector_all(node_id, selector)` - Find multiple elements by CSS selector
|
||||
- `get_element_attributes(node_id)` - Get all attributes of an element
|
||||
- `get_element_outer_html(node_id)` - Get outer HTML of an element
|
||||
- `get_element_box_model(node_id)` - Get layout information
|
||||
- `describe_element(node_id, depth?)` - Get detailed element description
|
||||
- `get_element_at_position(x, y)` - Get element at screen position
|
||||
- `search_elements(query)` - Search DOM elements by text/attributes
|
||||
- `focus_element(node_id)` - Focus a DOM element
|
||||
|
||||
### CSS Style Analysis
|
||||
- `get_computed_styles(node_id)` - Get computed CSS styles
|
||||
- `get_inline_styles(node_id)` - Get inline styles
|
||||
- `get_matched_styles(node_id)` - Get all CSS rules matching an element
|
||||
- `get_stylesheet_text(stylesheet_id)` - Get stylesheet content
|
||||
- `get_background_colors(node_id)` - Get background colors and fonts
|
||||
- `get_platform_fonts(node_id)` - Get platform font information
|
||||
- `get_media_queries()` - Get all media queries
|
||||
- `collect_css_class_names(stylesheet_id)` - Collect CSS class names
|
||||
- `start_css_coverage_tracking()` - Start CSS coverage tracking
|
||||
- `stop_css_coverage_tracking()` - Stop and get CSS coverage results
|
||||
|
||||
## Common Commands
|
||||
|
||||
| Task | Command |
|
||||
|------|---------|
|
||||
| Start Chrome and connect to app | `start_chrome_and_connect("localhost:3000")` |
|
||||
| Start Chrome (manual setup) | `start_chrome()` |
|
||||
| Navigate to page | `navigate_to_url("localhost:3000")` |
|
||||
| Connect to browser | `connect_to_browser()` |
|
||||
| See all network requests | `get_network_requests()` |
|
||||
| Find failed API calls | `get_network_requests(filter_status=404)` |
|
||||
| Check for JavaScript errors | `get_console_error_summary()` |
|
||||
| Watch console in real-time | `monitor_console_live(10)` |
|
||||
| Check page load performance | `get_page_info()` |
|
||||
| Examine a variable | `inspect_console_object("window.myApp")` |
|
||||
| View cookies | `get_cookies()` |
|
||||
| Run JavaScript | `execute_javascript("document.title")` |
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
- `CHROME_DEBUG_PORT` - Chrome remote debugging port (default: 9222)
|
||||
|
||||
### MCP Compatibility
|
||||
- **MCP Protocol Version**: 2024-11-05
|
||||
- **Minimum Python Version**: 3.10+
|
||||
- **Supported MCP Clients**: Claude Desktop, any MCP-compatible client
|
||||
- **Package Manager**: uv (recommended) or pip
|
||||
|
||||
## Usage Workflow
|
||||
|
||||
### Prerequisites (Your Development Environment)
|
||||
- Have your web application running (e.g., `npm run dev`, `python -m http.server`, etc.)
|
||||
- Note the URL where your application is accessible
|
||||
|
||||
### Debugging Session
|
||||
1. **Connect to your application** via Claude Desktop:
|
||||
```
|
||||
start_chrome_and_connect("localhost:3000")
|
||||
```
|
||||
*Replace with your application's URL*
|
||||
|
||||
2. **Debug your application** using the MCP tools:
|
||||
- Monitor network requests
|
||||
- Check console errors
|
||||
- Inspect JavaScript objects
|
||||
- Analyse performance
|
||||
|
||||
3. **Make changes to your code** in your editor
|
||||
4. **Refresh or interact** with your application
|
||||
5. **Continue debugging** with real-time data
|
||||
|
||||
### Manual Connection (Alternative)
|
||||
If you prefer step-by-step control:
|
||||
1. `start_chrome()` - Launch Chrome with debugging
|
||||
2. `navigate_to_url("your-app-url")` - Navigate to your application
|
||||
3. `connect_to_browser()` - Connect the MCP server
|
||||
4. Use debugging tools as needed
|
||||
|
||||
## Security Notes
|
||||
|
||||
- Only use with development environments
|
||||
- Never connect to production Chrome instances
|
||||
- The server is designed for localhost debugging only
|
||||
- No data is stored permanently - all data is session-based
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Server Shows as "Disabled" in Claude Desktop
|
||||
|
||||
If the server appears in Claude but shows as "disabled", try these steps:
|
||||
|
||||
1. **Check Claude Desktop logs**:
|
||||
- **macOS**: `~/Library/Logs/Claude/mcp*.log`
|
||||
- **Windows**: `%APPDATA%/Claude/logs/mcp*.log`
|
||||
|
||||
2. **Common fixes**:
|
||||
```bash
|
||||
# Reinstall with verbose output
|
||||
mcp remove "Chrome DevTools MCP"
|
||||
mcp install server.py -n "Chrome DevTools MCP" --with-editable . -v CHROME_DEBUG_PORT=9222
|
||||
|
||||
# Check installation status
|
||||
mcp list
|
||||
|
||||
# Test the server manually
|
||||
python3 server.py
|
||||
```
|
||||
|
||||
3. **Check dependencies**:
|
||||
```bash
|
||||
# Ensure all dependencies are available
|
||||
pip install mcp websockets aiohttp
|
||||
|
||||
# Test imports
|
||||
python3 -c "from server import mcp; print('OK')"
|
||||
```
|
||||
|
||||
4. **Restart Claude Desktop** completely (quit and reopen)
|
||||
|
||||
### Installation Issues
|
||||
- **MCP CLI not found**: Install MCP CLI with `pip install mcp` or `npm install -g @modelcontextprotocol/cli`
|
||||
- **Server not appearing in Claude**:
|
||||
- For MCP CLI: Run `mcp list` to verify the server is installed
|
||||
- For manual setup: Check Claude Desktop configuration file path and JSON syntax
|
||||
- **Import errors**:
|
||||
- For MCP CLI: Use `--with-editable .` to install local dependencies
|
||||
- For manual setup: Run `pip install -r requirements.txt`
|
||||
- **Permission errors**: Use absolute paths in configuration
|
||||
- **Environment variables not working**: Verify `.env` file format or `-v` flag syntax
|
||||
- **Module not found**: Ensure you're using `--with-editable .` flag for local package installation
|
||||
|
||||
### Debugging Steps
|
||||
|
||||
**Step 1: Check MCP CLI Status**
|
||||
```bash
|
||||
# List all installed servers
|
||||
mcp list
|
||||
|
||||
# Check specific server status
|
||||
mcp status "Chrome DevTools MCP"
|
||||
```
|
||||
|
||||
**Step 2: Test Server Manually**
|
||||
```bash
|
||||
# Test if server starts without errors
|
||||
python3 server.py
|
||||
|
||||
# Test imports
|
||||
python3 -c "from server import mcp; print(f'Server: {mcp.name}')"
|
||||
```
|
||||
|
||||
**Step 3: Check Configuration**
|
||||
|
||||
**For Claude Desktop:**
|
||||
```bash
|
||||
# View current configuration (macOS)
|
||||
cat "~/Library/Application Support/Claude/claude_desktop_config.json"
|
||||
|
||||
# View current configuration (Windows)
|
||||
type "%APPDATA%/Claude/claude_desktop_config.json"
|
||||
```
|
||||
|
||||
**For Claude Code:**
|
||||
```bash
|
||||
# List configured MCP servers
|
||||
claude mcp list
|
||||
|
||||
# Get details about a specific server
|
||||
claude mcp get chrome-devtools
|
||||
|
||||
# Check if server is working
|
||||
claude mcp serve --help
|
||||
```
|
||||
|
||||
**Step 4: Reinstall if Needed**
|
||||
|
||||
**For MCP CLI:**
|
||||
```bash
|
||||
# Clean reinstall
|
||||
mcp remove "Chrome DevTools MCP"
|
||||
mcp install server.py -n "Chrome DevTools MCP" --with-editable .
|
||||
|
||||
# Restart Claude Desktop completely
|
||||
```
|
||||
|
||||
**For Claude Code:**
|
||||
```bash
|
||||
# Remove and re-add the server
|
||||
claude mcp remove chrome-devtools
|
||||
claude mcp add chrome-devtools python server.py -e CHROME_DEBUG_PORT=9222
|
||||
|
||||
# Or update with different scope
|
||||
claude mcp add chrome-devtools python server.py -s user -e CHROME_DEBUG_PORT=9222
|
||||
```
|
||||
|
||||
### Common Error Messages
|
||||
|
||||
| Error | Solution |
|
||||
|-------|----------|
|
||||
| "Module not found" | Use `--with-editable .` flag |
|
||||
| "No server object found" | Server should export `mcp` object (already fixed) |
|
||||
| "Import error" | Check `pip install mcp websockets aiohttp` |
|
||||
| "Permission denied" | Use absolute paths in config |
|
||||
| "Server disabled" | Check Claude Desktop logs, restart Claude |
|
||||
|
||||
### Manual Configuration Fallback
|
||||
|
||||
**For Claude Desktop:**
|
||||
If MCP CLI isn't working, add this to Claude Desktop config manually:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"chrome-devtools": {
|
||||
"command": "python3",
|
||||
"args": ["/absolute/path/to/chrome-devtools-mcp/server.py"],
|
||||
"env": {
|
||||
"CHROME_DEBUG_PORT": "9222"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**For Claude Code:**
|
||||
If the `claude mcp add` command isn't working, you can use the JSON format:
|
||||
|
||||
```bash
|
||||
# Add server using JSON configuration
|
||||
claude mcp add-json chrome-devtools '{
|
||||
"command": "python3",
|
||||
"args": ["'$(pwd)'/server.py"],
|
||||
"env": {
|
||||
"CHROME_DEBUG_PORT": "9222"
|
||||
}
|
||||
}'
|
||||
|
||||
# Or import from Claude Desktop if you have it configured there
|
||||
claude mcp add-from-claude-desktop
|
||||
```
|
||||
|
||||
### Connection Issues
|
||||
- **Chrome won't start**: The MCP server will start Chrome automatically when you use `start_chrome()`
|
||||
- **Can't connect**: Try `get_connection_status()` to check the connection
|
||||
- **Tools not working**: Ensure you've called `connect_to_browser()` or used `start_chrome_and_connect()`
|
||||
|
||||
### Common Misconceptions
|
||||
- **This is not a web server**: The MCP server runs inside Claude Desktop, not as a separate web service
|
||||
- **No separate installation needed**: Once configured in Claude Desktop, the server starts automatically
|
||||
- **Your app runs separately**: This tool connects to your existing web application, it doesn't run it
|
||||
|
||||
## Development & Testing
|
||||
|
||||
*This section is for developers who want to test or modify the MCP server itself.*
|
||||
|
||||
### Development Setup
|
||||
|
||||
**With uv (recommended):**
|
||||
```bash
|
||||
git clone https://github.com/benjaminr/chrome-devtools-mcp.git
|
||||
cd chrome-devtools-mcp
|
||||
uv sync
|
||||
```
|
||||
|
||||
**With pip:**
|
||||
```bash
|
||||
git clone https://github.com/benjaminr/chrome-devtools-mcp.git
|
||||
cd chrome-devtools-mcp
|
||||
pip install -e ".[dev]"
|
||||
```
|
||||
|
||||
### Code Quality Tools
|
||||
|
||||
```bash
|
||||
# Format code
|
||||
uv run ruff format .
|
||||
|
||||
# Lint code
|
||||
uv run ruff check .
|
||||
|
||||
# Type checking
|
||||
uv run mypy src/
|
||||
```
|
||||
|
||||
### Building the Extension
|
||||
|
||||
**Install DXT packaging tools:**
|
||||
```bash
|
||||
npm install -g @anthropic-ai/dxt
|
||||
```
|
||||
|
||||
**Build the extension:**
|
||||
```bash
|
||||
# Quick build
|
||||
make package
|
||||
|
||||
# Or manually
|
||||
npx @anthropic-ai/dxt pack
|
||||
```
|
||||
|
||||
**Using Makefile for development:**
|
||||
```bash
|
||||
make help # Show all commands
|
||||
make install # Install dependencies
|
||||
make dev # Setup development environment + pre-commit
|
||||
make check # Run all checks (lint + type + test)
|
||||
make pre-commit # Run pre-commit hooks manually
|
||||
make package # Build .dxt extension
|
||||
make release # Full release build
|
||||
```
|
||||
|
||||
### Pre-commit Hooks
|
||||
|
||||
This project uses pre-commit hooks to ensure code quality:
|
||||
|
||||
- **ruff**: Linting and formatting
|
||||
- **mypy**: Type checking
|
||||
- **pytest**: Test validation
|
||||
- **MCP validation**: Server registration check
|
||||
|
||||
Pre-commit hooks run automatically on `git commit` and can be run manually with `make pre-commit`.
|
||||
|
||||
## License
|
||||
|
||||
MIT License
|
||||
140
docs/development/commit-message-template.md
Normal file
140
docs/development/commit-message-template.md
Normal file
@@ -0,0 +1,140 @@
|
||||
# TimeSafari Commit Message Template with Time Tracking
|
||||
|
||||
## Migration Commit Template
|
||||
|
||||
```
|
||||
[Component]: Complete Enhanced Triple Migration Pattern (X minutes)
|
||||
|
||||
Database Migration: Replace databaseUtil with PlatformServiceMixin
|
||||
SQL Abstraction: Use $contacts(), $settings(), $platformService methods
|
||||
Notification Migration: Add X constants, migrate X $notify calls to helpers
|
||||
Template Optimization: Extract X computed properties, reduce complexity
|
||||
|
||||
Time: X minutes | Complexity: [Simple/Medium/Complex] | Issues: [None/List]
|
||||
Testing: [Manual/Automated/Required] | Validation: [Script passed/Manual check]
|
||||
```
|
||||
|
||||
## Real Examples from Recent Work
|
||||
|
||||
### PhotoDialog + OfferDialog (58 minutes each)
|
||||
```
|
||||
Complete Enhanced Triple Migration Pattern for PhotoDialog and OfferDialog (116 minutes)
|
||||
|
||||
Database Migration: Replace databaseUtil with PlatformServiceMixin
|
||||
SQL Abstraction: Use $accountSettings() for settings retrieval
|
||||
Notification Migration: Add 15 constants, migrate 15 $notify calls to helpers
|
||||
Template Optimization: Extract 11 computed properties, reduce template complexity
|
||||
|
||||
Time: 116 minutes | Complexity: Medium | Issues: None
|
||||
Testing: Manual | Validation: Script passed
|
||||
```
|
||||
|
||||
### ProjectsView (17 minutes)
|
||||
```
|
||||
Complete ProjectsView Triple Migration Pattern with literal extraction (17 minutes)
|
||||
|
||||
Database Migration: Replace databaseUtil with PlatformServiceMixin
|
||||
SQL Abstraction: Use $contacts(), $projects() methods
|
||||
Notification Migration: Add 1 constant, migrate 1 $notify call
|
||||
Template Optimization: Extract 3 computed properties
|
||||
|
||||
Time: 17 minutes | Complexity: Simple | Issues: None
|
||||
Testing: Automated | Validation: Script passed
|
||||
```
|
||||
|
||||
## Batch Migration Template
|
||||
|
||||
```
|
||||
Complete notification migration across X components (Y minutes)
|
||||
|
||||
Components: [List of components]
|
||||
- Add X centralized notification constants
|
||||
- Migrate X $notify calls to helper methods
|
||||
- Standardize timeout usage with TIMEOUTS constants
|
||||
|
||||
Time: Y minutes | Avg per component: Z minutes | Complexity: Batch
|
||||
Testing: Automated | Validation: Script passed
|
||||
```
|
||||
|
||||
## Time Tracking Workflow
|
||||
|
||||
### 1. Start Migration
|
||||
```bash
|
||||
./scripts/time-migration.sh ComponentName.vue start
|
||||
```
|
||||
|
||||
### 2. Complete Migration
|
||||
```bash
|
||||
./scripts/time-migration.sh ComponentName.vue end
|
||||
```
|
||||
|
||||
### 3. Daily Summary
|
||||
```bash
|
||||
./scripts/daily-migration-summary.sh
|
||||
```
|
||||
|
||||
### 4. Commit with Time Data
|
||||
```bash
|
||||
git commit -m "Complete ComponentName migration (X minutes)
|
||||
|
||||
Database Migration: Replace databaseUtil with PlatformServiceMixin
|
||||
Notification Migration: Add X constants, migrate X $notify calls
|
||||
Template Optimization: Extract X computed properties
|
||||
|
||||
Time: X minutes | Complexity: [Level] | Issues: [None/List]
|
||||
Testing: [Status] | Validation: [Status]"
|
||||
```
|
||||
|
||||
## Time Complexity Guidelines
|
||||
|
||||
### Simple Components (15-20 minutes)
|
||||
- Dialog components with minimal database operations
|
||||
- Utility components with few notifications
|
||||
- Example: UserNameDialog, TopMessage
|
||||
|
||||
### Medium Components (30-45 minutes)
|
||||
- Standard view components with moderate database usage
|
||||
- Multiple notification patterns
|
||||
- Example: ProjectsView, ContactsView
|
||||
|
||||
### Complex Components (45-60 minutes)
|
||||
- Large view components with extensive database operations
|
||||
- Many notification patterns and complex templates
|
||||
- Example: PhotoDialog, OfferDialog, ConfirmGiftView
|
||||
|
||||
## Performance Tracking
|
||||
|
||||
### Daily Targets
|
||||
- **Simple Components**: 20+ per day
|
||||
- **Medium Components**: 8-12 per day
|
||||
- **Complex Components**: 4-8 per day
|
||||
|
||||
### Weekly Targets
|
||||
- **Week 1**: 25 components (mix of simple/medium)
|
||||
- **Week 2**: 30 components (focus on complex)
|
||||
- **Week 3**: 37 components (remaining)
|
||||
|
||||
### Quality Gates
|
||||
- [ ] Start time logged
|
||||
- [ ] End time logged
|
||||
- [ ] Validation script passed
|
||||
- [ ] Linting passed
|
||||
- [ ] Commit includes time data
|
||||
- [ ] Daily summary updated
|
||||
|
||||
## Efficiency Tips
|
||||
|
||||
### Batch Processing
|
||||
- Group similar components
|
||||
- Reuse notification constants
|
||||
- Copy/paste helper patterns
|
||||
|
||||
### Templates and Automation
|
||||
- Use migration checklist
|
||||
- Standardize computed property patterns
|
||||
- Validate with scripts
|
||||
|
||||
### Time Savers
|
||||
- Keep validation script running
|
||||
- Use IDE snippets for common patterns
|
||||
- Track blockers immediately
|
||||
233
docs/development/domain-configuration.md
Normal file
233
docs/development/domain-configuration.md
Normal file
@@ -0,0 +1,233 @@
|
||||
# Domain Configuration System
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: 2025-01-27
|
||||
**Status**: ✅ **COMPLETE** - Domain configuration system implemented
|
||||
|
||||
## Overview
|
||||
|
||||
TimeSafari uses a centralized domain configuration system to ensure consistent
|
||||
URL generation across all environments. This system prevents localhost URLs from
|
||||
appearing in shared links during development and provides a single point of
|
||||
control for domain changes.
|
||||
|
||||
## Problem Solved
|
||||
|
||||
### Issue: Localhost URLs in Shared Links
|
||||
|
||||
Previously, copy link buttons and deep link generation used the environment-
|
||||
specific `APP_SERVER` constant, which resulted in:
|
||||
|
||||
- **Development**: `http://localhost:8080/deep-link/claim/123`
|
||||
- **Test**: `https://test.timesafari.app/deep-link/claim/123`
|
||||
- **Production**: `https://timesafari.app/deep-link/claim/123`
|
||||
|
||||
This caused problems when users in development mode shared links, as the
|
||||
localhost URLs wouldn't work for other users.
|
||||
|
||||
### Solution: Production Domain for Sharing
|
||||
|
||||
All sharing functionality now uses the `PROD_SHARE_DOMAIN` constant, which
|
||||
always points to the production domain regardless of the current environment.
|
||||
|
||||
## Implementation
|
||||
|
||||
### Core Configuration
|
||||
|
||||
The domain configuration is centralized in `src/constants/app.ts`:
|
||||
|
||||
```typescript
|
||||
export enum AppString {
|
||||
// ... other constants ...
|
||||
PROD_PUSH_SERVER = "https://timesafari.app",
|
||||
// ... other constants ...
|
||||
}
|
||||
|
||||
// Production domain for sharing links (always use production URL for sharing)
|
||||
export const PROD_SHARE_DOMAIN = AppString.PROD_PUSH_SERVER;
|
||||
```
|
||||
|
||||
### Usage Pattern
|
||||
|
||||
All components that generate shareable links follow this pattern:
|
||||
|
||||
```typescript
|
||||
import { PROD_SHARE_DOMAIN } from "@/constants/app";
|
||||
|
||||
// In component class
|
||||
PROD_SHARE_DOMAIN = PROD_SHARE_DOMAIN;
|
||||
|
||||
// In methods
|
||||
const deepLink = `${PROD_SHARE_DOMAIN}/deep-link/claim/${claimId}`;
|
||||
```
|
||||
|
||||
### Components Updated
|
||||
|
||||
The following components and services were updated to use `PROD_SHARE_DOMAIN`:
|
||||
|
||||
#### Views
|
||||
- `ClaimView.vue` - Claim and certificate links
|
||||
- `ProjectViewView.vue` - Project copy links
|
||||
- `ConfirmGiftView.vue` - Confirm gift deep links
|
||||
- `UserProfileView.vue` - Profile copy links
|
||||
- `InviteOneView.vue` - Invite link generation
|
||||
- `ContactsView.vue` - Contact import links
|
||||
- `OnboardMeetingSetupView.vue` - Meeting members links
|
||||
|
||||
#### Components
|
||||
- `HiddenDidDialog.vue` - Hidden DID dialog links
|
||||
|
||||
#### Services
|
||||
- `endorserServer.ts` - Contact import confirm links
|
||||
|
||||
## Configuration Management
|
||||
|
||||
### Changing the Production Domain
|
||||
|
||||
To change the production domain for all sharing functionality:
|
||||
|
||||
1. **Update the constant** in `src/constants/app.ts`:
|
||||
```typescript
|
||||
export enum AppString {
|
||||
// ... other constants ...
|
||||
PROD_PUSH_SERVER = "https://your-new-domain.com",
|
||||
// ... other constants ...
|
||||
}
|
||||
```
|
||||
|
||||
2. **Rebuild the application** for all platforms:
|
||||
```bash
|
||||
npm run build:web
|
||||
npm run build:capacitor
|
||||
npm run build:electron
|
||||
```
|
||||
|
||||
### Environment-Specific Configuration
|
||||
|
||||
The system maintains environment-specific configuration for internal operations
|
||||
while using production domains for sharing:
|
||||
|
||||
```typescript
|
||||
// Internal operations use environment-specific URLs
|
||||
export const APP_SERVER =
|
||||
import.meta.env.VITE_APP_SERVER || "https://timesafari.app";
|
||||
|
||||
// Sharing always uses production URLs
|
||||
export const PROD_SHARE_DOMAIN = AppString.PROD_PUSH_SERVER;
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
### ✅ Consistent User Experience
|
||||
|
||||
- All shared links work for all users regardless of environment
|
||||
- No more broken localhost links in development
|
||||
- Consistent behavior across all platforms
|
||||
|
||||
### ✅ Maintainability
|
||||
|
||||
- Single source of truth for production domain
|
||||
- Easy to change domain across entire application
|
||||
- Clear separation between internal and sharing URLs
|
||||
|
||||
### ✅ Developer Experience
|
||||
|
||||
- No need to remember which environment URLs work for sharing
|
||||
- Clear pattern for implementing new sharing functionality
|
||||
- Type-safe configuration with TypeScript
|
||||
|
||||
### ✅ Security
|
||||
|
||||
- No accidental exposure of internal development URLs
|
||||
- Controlled domain configuration
|
||||
- Clear audit trail for domain changes
|
||||
|
||||
## Testing
|
||||
|
||||
### Manual Testing
|
||||
|
||||
1. **Development Environment**:
|
||||
```bash
|
||||
npm run dev
|
||||
# Navigate to any page with copy link buttons
|
||||
# Verify links use production domain, not localhost
|
||||
```
|
||||
|
||||
2. **Production Build**:
|
||||
```bash
|
||||
npm run build:web
|
||||
# Deploy and test sharing functionality
|
||||
# Verify all links work correctly
|
||||
```
|
||||
|
||||
### Automated Testing
|
||||
|
||||
The implementation includes comprehensive linting to ensure:
|
||||
|
||||
- All components properly import `PROD_SHARE_DOMAIN`
|
||||
- No hardcoded URLs in sharing functionality
|
||||
- Consistent usage patterns across the codebase
|
||||
|
||||
## Migration Notes
|
||||
|
||||
### Before Implementation
|
||||
|
||||
```typescript
|
||||
// ❌ Hardcoded URLs
|
||||
const deepLink = "https://timesafari.app/deep-link/claim/123";
|
||||
|
||||
// ❌ Environment-specific URLs
|
||||
const deepLink = `${APP_SERVER}/deep-link/claim/123`;
|
||||
```
|
||||
|
||||
### After Implementation
|
||||
|
||||
```typescript
|
||||
// ✅ Configurable production URLs
|
||||
const deepLink = `${PROD_SHARE_DOMAIN}/deep-link/claim/123`;
|
||||
```
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
### Potential Improvements
|
||||
|
||||
1. **Environment-Specific Sharing Domains**:
|
||||
```typescript
|
||||
export const getShareDomain = () => {
|
||||
if (import.meta.env.PROD) {
|
||||
return AppString.PROD_PUSH_SERVER;
|
||||
}
|
||||
return AppString.TEST1_PUSH_SERVER; // Use test domain for dev sharing
|
||||
};
|
||||
```
|
||||
|
||||
2. **Dynamic Domain Detection**:
|
||||
```typescript
|
||||
export const SHARE_DOMAIN =
|
||||
import.meta.env.VITE_SHARE_DOMAIN || AppString.PROD_PUSH_SERVER;
|
||||
```
|
||||
|
||||
3. **Platform-Specific Domains**:
|
||||
```typescript
|
||||
export const getPlatformShareDomain = () => {
|
||||
const platform = process.env.VITE_PLATFORM;
|
||||
switch (platform) {
|
||||
case 'web': return AppString.PROD_PUSH_SERVER;
|
||||
case 'capacitor': return AppString.PROD_PUSH_SERVER;
|
||||
case 'electron': return AppString.PROD_PUSH_SERVER;
|
||||
default: return AppString.PROD_PUSH_SERVER;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Build Systems Overview](build-systems-overview.md) - Environment configuration
|
||||
- [Constants and Configuration](src/constants/app.ts) - Core constants
|
||||
- [Migration Guide](doc/migration-to-wa-sqlite.md) - Database migration context
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-01-27
|
||||
**Version**: 1.0
|
||||
**Maintainer**: Matthew Raymer
|
||||
794
docs/development/playwright_mcp.md
Normal file
794
docs/development/playwright_mcp.md
Normal file
@@ -0,0 +1,794 @@
|
||||
## Playwright MCP
|
||||
|
||||
A Model Context Protocol (MCP) server that provides browser automation capabilities using [Playwright](https://playwright.dev). This server enables LLMs to interact with web pages through structured accessibility snapshots, bypassing the need for screenshots or visually-tuned models.
|
||||
|
||||
### Key Features
|
||||
|
||||
- **Fast and lightweight**. Uses Playwright's accessibility tree, not pixel-based input.
|
||||
- **LLM-friendly**. No vision models needed, operates purely on structured data.
|
||||
- **Deterministic tool application**. Avoids ambiguity common with screenshot-based approaches.
|
||||
|
||||
### Requirements
|
||||
- Node.js 18 or newer
|
||||
- VS Code, Cursor, Windsurf, Claude Desktop or any other MCP client
|
||||
|
||||
<!--
|
||||
// Generate using:
|
||||
node utils/generate-links.js
|
||||
-->
|
||||
|
||||
### Getting started
|
||||
|
||||
First, install the Playwright MCP server with your client. A typical configuration looks like this:
|
||||
|
||||
```js
|
||||
{
|
||||
"mcpServers": {
|
||||
"playwright": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"@playwright/mcp@latest"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[<img src="https://img.shields.io/badge/VS_Code-VS_Code?style=flat-square&label=Install%20Server&color=0098FF" alt="Install in VS Code">](https://insiders.vscode.dev/redirect?url=vscode%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522playwright%2522%252C%2522command%2522%253A%2522npx%2522%252C%2522args%2522%253A%255B%2522%2540playwright%252Fmcp%2540latest%2522%255D%257D) [<img alt="Install in VS Code Insiders" src="https://img.shields.io/badge/VS_Code_Insiders-VS_Code_Insiders?style=flat-square&label=Install%20Server&color=24bfa5">](https://insiders.vscode.dev/redirect?url=vscode-insiders%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522playwright%2522%252C%2522command%2522%253A%2522npx%2522%252C%2522args%2522%253A%255B%2522%2540playwright%252Fmcp%2540latest%2522%255D%257D)
|
||||
|
||||
<details><summary><b>Install in VS Code</b></summary>
|
||||
|
||||
You can also install the Playwright MCP server using the VS Code CLI:
|
||||
|
||||
```bash
|
||||
# For VS Code
|
||||
code --add-mcp '{"name":"playwright","command":"npx","args":["@playwright/mcp@latest"]}'
|
||||
```
|
||||
|
||||
After installation, the Playwright MCP server will be available for use with your GitHub Copilot agent in VS Code.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Install in Cursor</b></summary>
|
||||
|
||||
#### Click the button to install:
|
||||
|
||||
[](https://cursor.com/install-mcp?name=playwright&config=eyJjb21tYW5kIjoibnB4IEBwbGF5d3JpZ2h0L21jcEBsYXRlc3QifQ%3D%3D)
|
||||
|
||||
#### Or install manually:
|
||||
|
||||
Go to `Cursor Settings` -> `MCP` -> `Add new MCP Server`. Name to your liking, use `command` type with the command `npx @playwright/mcp`. You can also verify config or add command like arguments via clicking `Edit`.
|
||||
|
||||
```js
|
||||
{
|
||||
"mcpServers": {
|
||||
"playwright": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"@playwright/mcp@latest"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Install in Windsurf</b></summary>
|
||||
|
||||
Follow Windsurf MCP [documentation](https://docs.windsurf.com/windsurf/cascade/mcp). Use following configuration:
|
||||
|
||||
```js
|
||||
{
|
||||
"mcpServers": {
|
||||
"playwright": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"@playwright/mcp@latest"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Install in Claude Desktop</b></summary>
|
||||
|
||||
Follow the MCP install [guide](https://modelcontextprotocol.io/quickstart/user), use following configuration:
|
||||
|
||||
```js
|
||||
{
|
||||
"mcpServers": {
|
||||
"playwright": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"@playwright/mcp@latest"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Install in Claude Code</b></summary>
|
||||
|
||||
Use the Claude Code CLI to add the Playwright MCP server:
|
||||
|
||||
```bash
|
||||
claude mcp add playwright npx @playwright/mcp@latest
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Install in Qodo Gen</b></summary>
|
||||
|
||||
Open [Qodo Gen](https://docs.qodo.ai/qodo-documentation/qodo-gen) chat panel in VSCode or IntelliJ → Connect more tools → + Add new MCP → Paste the following configuration:
|
||||
|
||||
```js
|
||||
{
|
||||
"mcpServers": {
|
||||
"playwright": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"@playwright/mcp@latest"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Click <code>Save</code>.
|
||||
</details>
|
||||
|
||||
### Configuration
|
||||
|
||||
Playwright MCP server supports following arguments. They can be provided in the JSON configuration above, as a part of the `"args"` list:
|
||||
|
||||
<!--- Options generated by update-readme.js -->
|
||||
|
||||
```
|
||||
> npx @playwright/mcp@latest --help
|
||||
--allowed-origins <origins> semicolon-separated list of origins to allow the
|
||||
browser to request. Default is to allow all.
|
||||
--blocked-origins <origins> semicolon-separated list of origins to block the
|
||||
browser from requesting. Blocklist is evaluated
|
||||
before allowlist. If used without the allowlist,
|
||||
requests not matching the blocklist are still
|
||||
allowed.
|
||||
--block-service-workers block service workers
|
||||
--browser <browser> browser or chrome channel to use, possible
|
||||
values: chrome, firefox, webkit, msedge.
|
||||
--browser-agent <endpoint> Use browser agent (experimental).
|
||||
--caps <caps> comma-separated list of capabilities to enable,
|
||||
possible values: tabs, pdf, history, wait, files,
|
||||
install. Default is all.
|
||||
--cdp-endpoint <endpoint> CDP endpoint to connect to.
|
||||
--config <path> path to the configuration file.
|
||||
--device <device> device to emulate, for example: "iPhone 15"
|
||||
--executable-path <path> path to the browser executable.
|
||||
--headless run browser in headless mode, headed by default
|
||||
--host <host> host to bind server to. Default is localhost. Use
|
||||
0.0.0.0 to bind to all interfaces.
|
||||
--ignore-https-errors ignore https errors
|
||||
--isolated keep the browser profile in memory, do not save
|
||||
it to disk.
|
||||
--image-responses <mode> whether to send image responses to the client.
|
||||
Can be "allow", "omit", or "auto". Defaults to
|
||||
"auto", which sends images if the client can
|
||||
display them.
|
||||
--no-sandbox disable the sandbox for all process types that
|
||||
are normally sandboxed.
|
||||
--output-dir <path> path to the directory for output files.
|
||||
--port <port> port to listen on for SSE transport.
|
||||
--proxy-bypass <bypass> comma-separated domains to bypass proxy, for
|
||||
example ".com,chromium.org,.domain.com"
|
||||
--proxy-server <proxy> specify proxy server, for example
|
||||
"http://myproxy:3128" or "socks5://myproxy:8080"
|
||||
--save-trace Whether to save the Playwright Trace of the
|
||||
session into the output directory.
|
||||
--storage-state <path> path to the storage state file for isolated
|
||||
sessions.
|
||||
--user-agent <ua string> specify user agent string
|
||||
--user-data-dir <path> path to the user data directory. If not
|
||||
specified, a temporary directory will be created.
|
||||
--viewport-size <size> specify browser viewport size in pixels, for
|
||||
example "1280, 720"
|
||||
--vision Run server that uses screenshots (Aria snapshots
|
||||
are used by default)
|
||||
```
|
||||
|
||||
<!--- End of options generated section -->
|
||||
|
||||
### User profile
|
||||
|
||||
You can run Playwright MCP with persistent profile like a regular browser (default), or in the isolated contexts for the testing sessions.
|
||||
|
||||
**Persistent profile**
|
||||
|
||||
All the logged in information will be stored in the persistent profile, you can delete it between sessions if you'd like to clear the offline state.
|
||||
Persistent profile is located at the following locations and you can override it with the `--user-data-dir` argument.
|
||||
|
||||
```bash
|
||||
# Windows
|
||||
%USERPROFILE%\AppData\Local\ms-playwright\mcp-{channel}-profile
|
||||
|
||||
# macOS
|
||||
- ~/Library/Caches/ms-playwright/mcp-{channel}-profile
|
||||
|
||||
# Linux
|
||||
- ~/.cache/ms-playwright/mcp-{channel}-profile
|
||||
```
|
||||
|
||||
**Isolated**
|
||||
|
||||
In the isolated mode, each session is started in the isolated profile. Every time you ask MCP to close the browser,
|
||||
the session is closed and all the storage state for this session is lost. You can provide initial storage state
|
||||
to the browser via the config's `contextOptions` or via the `--storage-state` argument. Learn more about the storage
|
||||
state [here](https://playwright.dev/docs/auth).
|
||||
|
||||
```js
|
||||
{
|
||||
"mcpServers": {
|
||||
"playwright": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"@playwright/mcp@latest",
|
||||
"--isolated",
|
||||
"--storage-state={path/to/storage.json}"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Configuration file
|
||||
|
||||
The Playwright MCP server can be configured using a JSON configuration file. You can specify the configuration file
|
||||
using the `--config` command line option:
|
||||
|
||||
```bash
|
||||
npx @playwright/mcp@latest --config path/to/config.json
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Configuration file schema</summary>
|
||||
|
||||
```typescript
|
||||
{
|
||||
// Browser configuration
|
||||
browser?: {
|
||||
// Browser type to use (chromium, firefox, or webkit)
|
||||
browserName?: 'chromium' | 'firefox' | 'webkit';
|
||||
|
||||
// Keep the browser profile in memory, do not save it to disk.
|
||||
isolated?: boolean;
|
||||
|
||||
// Path to user data directory for browser profile persistence
|
||||
userDataDir?: string;
|
||||
|
||||
// Browser launch options (see Playwright docs)
|
||||
// @see https://playwright.dev/docs/api/class-browsertype#browser-type-launch
|
||||
launchOptions?: {
|
||||
channel?: string; // Browser channel (e.g. 'chrome')
|
||||
headless?: boolean; // Run in headless mode
|
||||
executablePath?: string; // Path to browser executable
|
||||
// ... other Playwright launch options
|
||||
};
|
||||
|
||||
// Browser context options
|
||||
// @see https://playwright.dev/docs/api/class-browser#browser-new-context
|
||||
contextOptions?: {
|
||||
viewport?: { width: number, height: number };
|
||||
// ... other Playwright context options
|
||||
};
|
||||
|
||||
// CDP endpoint for connecting to existing browser
|
||||
cdpEndpoint?: string;
|
||||
|
||||
// Remote Playwright server endpoint
|
||||
remoteEndpoint?: string;
|
||||
},
|
||||
|
||||
// Server configuration
|
||||
server?: {
|
||||
port?: number; // Port to listen on
|
||||
host?: string; // Host to bind to (default: localhost)
|
||||
},
|
||||
|
||||
// List of enabled capabilities
|
||||
capabilities?: Array<
|
||||
'core' | // Core browser automation
|
||||
'tabs' | // Tab management
|
||||
'pdf' | // PDF generation
|
||||
'history' | // Browser history
|
||||
'wait' | // Wait utilities
|
||||
'files' | // File handling
|
||||
'install' | // Browser installation
|
||||
'testing' // Testing
|
||||
>;
|
||||
|
||||
// Enable vision mode (screenshots instead of accessibility snapshots)
|
||||
vision?: boolean;
|
||||
|
||||
// Directory for output files
|
||||
outputDir?: string;
|
||||
|
||||
// Network configuration
|
||||
network?: {
|
||||
// List of origins to allow the browser to request. Default is to allow all. Origins matching both `allowedOrigins` and `blockedOrigins` will be blocked.
|
||||
allowedOrigins?: string[];
|
||||
|
||||
// List of origins to block the browser to request. Origins matching both `allowedOrigins` and `blockedOrigins` will be blocked.
|
||||
blockedOrigins?: string[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Do not send image responses to the client.
|
||||
*/
|
||||
noImageResponses?: boolean;
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
### Standalone MCP server
|
||||
|
||||
When running headed browser on system w/o display or from worker processes of the IDEs,
|
||||
run the MCP server from environment with the DISPLAY and pass the `--port` flag to enable SSE transport.
|
||||
|
||||
```bash
|
||||
npx @playwright/mcp@latest --port 8931
|
||||
```
|
||||
|
||||
And then in MCP client config, set the `url` to the SSE endpoint:
|
||||
|
||||
```js
|
||||
{
|
||||
"mcpServers": {
|
||||
"playwright": {
|
||||
"url": "http://localhost:8931/sse"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary><b>Docker</b></summary>
|
||||
|
||||
**NOTE:** The Docker implementation only supports headless chromium at the moment.
|
||||
|
||||
```js
|
||||
{
|
||||
"mcpServers": {
|
||||
"playwright": {
|
||||
"command": "docker",
|
||||
"args": ["run", "-i", "--rm", "--init", "--pull=always", "mcr.microsoft.com/playwright/mcp"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can build the Docker image yourself.
|
||||
|
||||
```
|
||||
docker build -t mcr.microsoft.com/playwright/mcp .
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Programmatic usage</b></summary>
|
||||
|
||||
```js
|
||||
import http from 'http';
|
||||
|
||||
import { createConnection } from '@playwright/mcp';
|
||||
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
|
||||
|
||||
http.createServer(async (req, res) => {
|
||||
// ...
|
||||
|
||||
// Creates a headless Playwright MCP server with SSE transport
|
||||
const connection = await createConnection({ browser: { launchOptions: { headless: true } } });
|
||||
const transport = new SSEServerTransport('/messages', res);
|
||||
await connection.sever.connect(transport);
|
||||
|
||||
// ...
|
||||
});
|
||||
```
|
||||
</details>
|
||||
|
||||
### Tools
|
||||
|
||||
The tools are available in two modes:
|
||||
|
||||
1. **Snapshot Mode** (default): Uses accessibility snapshots for better performance and reliability
|
||||
2. **Vision Mode**: Uses screenshots for visual-based interactions
|
||||
|
||||
To use Vision Mode, add the `--vision` flag when starting the server:
|
||||
|
||||
```js
|
||||
{
|
||||
"mcpServers": {
|
||||
"playwright": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"@playwright/mcp@latest",
|
||||
"--vision"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Vision Mode works best with the computer use models that are able to interact with elements using
|
||||
X Y coordinate space, based on the provided screenshot.
|
||||
|
||||
<!--- Tools generated by update-readme.js -->
|
||||
|
||||
<details>
|
||||
<summary><b>Interactions</b></summary>
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_snapshot**
|
||||
- Title: Page snapshot
|
||||
- Description: Capture accessibility snapshot of the current page, this is better than screenshot
|
||||
- Parameters: None
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_click**
|
||||
- Title: Click
|
||||
- Description: Perform click on a web page
|
||||
- Parameters:
|
||||
- `element` (string): Human-readable element description used to obtain permission to interact with the element
|
||||
- `ref` (string): Exact target element reference from the page snapshot
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_drag**
|
||||
- Title: Drag mouse
|
||||
- Description: Perform drag and drop between two elements
|
||||
- Parameters:
|
||||
- `startElement` (string): Human-readable source element description used to obtain the permission to interact with the element
|
||||
- `startRef` (string): Exact source element reference from the page snapshot
|
||||
- `endElement` (string): Human-readable target element description used to obtain the permission to interact with the element
|
||||
- `endRef` (string): Exact target element reference from the page snapshot
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_hover**
|
||||
- Title: Hover mouse
|
||||
- Description: Hover over element on page
|
||||
- Parameters:
|
||||
- `element` (string): Human-readable element description used to obtain permission to interact with the element
|
||||
- `ref` (string): Exact target element reference from the page snapshot
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_type**
|
||||
- Title: Type text
|
||||
- Description: Type text into editable element
|
||||
- Parameters:
|
||||
- `element` (string): Human-readable element description used to obtain permission to interact with the element
|
||||
- `ref` (string): Exact target element reference from the page snapshot
|
||||
- `text` (string): Text to type into the element
|
||||
- `submit` (boolean, optional): Whether to submit entered text (press Enter after)
|
||||
- `slowly` (boolean, optional): 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.
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_select_option**
|
||||
- Title: Select option
|
||||
- Description: Select an option in a dropdown
|
||||
- Parameters:
|
||||
- `element` (string): Human-readable element description used to obtain permission to interact with the element
|
||||
- `ref` (string): Exact target element reference from the page snapshot
|
||||
- `values` (array): Array of values to select in the dropdown. This can be a single value or multiple values.
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_press_key**
|
||||
- Title: Press a key
|
||||
- Description: Press a key on the keyboard
|
||||
- Parameters:
|
||||
- `key` (string): Name of the key to press or a character to generate, such as `ArrowLeft` or `a`
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_wait_for**
|
||||
- Title: Wait for
|
||||
- Description: Wait for text to appear or disappear or a specified time to pass
|
||||
- Parameters:
|
||||
- `time` (number, optional): The time to wait in seconds
|
||||
- `text` (string, optional): The text to wait for
|
||||
- `textGone` (string, optional): The text to wait for to disappear
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_file_upload**
|
||||
- Title: Upload files
|
||||
- Description: Upload one or multiple files
|
||||
- Parameters:
|
||||
- `paths` (array): The absolute paths to the files to upload. Can be a single file or multiple files.
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_handle_dialog**
|
||||
- Title: Handle a dialog
|
||||
- Description: Handle a dialog
|
||||
- Parameters:
|
||||
- `accept` (boolean): Whether to accept the dialog.
|
||||
- `promptText` (string, optional): The text of the prompt in case of a prompt dialog.
|
||||
- Read-only: **false**
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Navigation</b></summary>
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_navigate**
|
||||
- Title: Navigate to a URL
|
||||
- Description: Navigate to a URL
|
||||
- Parameters:
|
||||
- `url` (string): The URL to navigate to
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_navigate_back**
|
||||
- Title: Go back
|
||||
- Description: Go back to the previous page
|
||||
- Parameters: None
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_navigate_forward**
|
||||
- Title: Go forward
|
||||
- Description: Go forward to the next page
|
||||
- Parameters: None
|
||||
- Read-only: **true**
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Resources</b></summary>
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_take_screenshot**
|
||||
- Title: Take a screenshot
|
||||
- Description: Take a screenshot of the current page. You can't perform actions based on the screenshot, use browser_snapshot for actions.
|
||||
- Parameters:
|
||||
- `raw` (boolean, optional): Whether to return without compression (in PNG format). Default is false, which returns a JPEG image.
|
||||
- `filename` (string, optional): File name to save the screenshot to. Defaults to `page-{timestamp}.{png|jpeg}` if not specified.
|
||||
- `element` (string, optional): 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.
|
||||
- `ref` (string, optional): 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.
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_pdf_save**
|
||||
- Title: Save as PDF
|
||||
- Description: Save page as PDF
|
||||
- Parameters:
|
||||
- `filename` (string, optional): File name to save the pdf to. Defaults to `page-{timestamp}.pdf` if not specified.
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_network_requests**
|
||||
- Title: List network requests
|
||||
- Description: Returns all network requests since loading the page
|
||||
- Parameters: None
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_console_messages**
|
||||
- Title: Get console messages
|
||||
- Description: Returns all console messages
|
||||
- Parameters: None
|
||||
- Read-only: **true**
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Utilities</b></summary>
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_install**
|
||||
- Title: Install the browser specified in the config
|
||||
- Description: Install the browser specified in the config. Call this if you get an error about the browser not being installed.
|
||||
- Parameters: None
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_close**
|
||||
- Title: Close browser
|
||||
- Description: Close the page
|
||||
- Parameters: None
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_resize**
|
||||
- Title: Resize browser window
|
||||
- Description: Resize the browser window
|
||||
- Parameters:
|
||||
- `width` (number): Width of the browser window
|
||||
- `height` (number): Height of the browser window
|
||||
- Read-only: **true**
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Tabs</b></summary>
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_tab_list**
|
||||
- Title: List tabs
|
||||
- Description: List browser tabs
|
||||
- Parameters: None
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_tab_new**
|
||||
- Title: Open a new tab
|
||||
- Description: Open a new tab
|
||||
- Parameters:
|
||||
- `url` (string, optional): The URL to navigate to in the new tab. If not provided, the new tab will be blank.
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_tab_select**
|
||||
- Title: Select a tab
|
||||
- Description: Select a tab by index
|
||||
- Parameters:
|
||||
- `index` (number): The index of the tab to select
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_tab_close**
|
||||
- Title: Close a tab
|
||||
- Description: Close a tab
|
||||
- Parameters:
|
||||
- `index` (number, optional): The index of the tab to close. Closes current tab if not provided.
|
||||
- Read-only: **false**
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Testing</b></summary>
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_generate_playwright_test**
|
||||
- Title: Generate a Playwright test
|
||||
- Description: Generate a Playwright test for given scenario
|
||||
- Parameters:
|
||||
- `name` (string): The name of the test
|
||||
- `description` (string): The description of the test
|
||||
- `steps` (array): The steps of the test
|
||||
- Read-only: **true**
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Vision mode</b></summary>
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_screen_capture**
|
||||
- Title: Take a screenshot
|
||||
- Description: Take a screenshot of the current page
|
||||
- Parameters: None
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_screen_move_mouse**
|
||||
- Title: Move mouse
|
||||
- Description: Move mouse to a given position
|
||||
- Parameters:
|
||||
- `element` (string): Human-readable element description used to obtain permission to interact with the element
|
||||
- `x` (number): X coordinate
|
||||
- `y` (number): Y coordinate
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_screen_click**
|
||||
- Title: Click
|
||||
- Description: Click left mouse button
|
||||
- Parameters:
|
||||
- `element` (string): Human-readable element description used to obtain permission to interact with the element
|
||||
- `x` (number): X coordinate
|
||||
- `y` (number): Y coordinate
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_screen_drag**
|
||||
- Title: Drag mouse
|
||||
- Description: Drag left mouse button
|
||||
- Parameters:
|
||||
- `element` (string): Human-readable element description used to obtain permission to interact with the element
|
||||
- `startX` (number): Start X coordinate
|
||||
- `startY` (number): Start Y coordinate
|
||||
- `endX` (number): End X coordinate
|
||||
- `endY` (number): End Y coordinate
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_screen_type**
|
||||
- Title: Type text
|
||||
- Description: Type text
|
||||
- Parameters:
|
||||
- `text` (string): Text to type into the element
|
||||
- `submit` (boolean, optional): Whether to submit entered text (press Enter after)
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_press_key**
|
||||
- Title: Press a key
|
||||
- Description: Press a key on the keyboard
|
||||
- Parameters:
|
||||
- `key` (string): Name of the key to press or a character to generate, such as `ArrowLeft` or `a`
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_wait_for**
|
||||
- Title: Wait for
|
||||
- Description: Wait for text to appear or disappear or a specified time to pass
|
||||
- Parameters:
|
||||
- `time` (number, optional): The time to wait in seconds
|
||||
- `text` (string, optional): The text to wait for
|
||||
- `textGone` (string, optional): The text to wait for to disappear
|
||||
- Read-only: **true**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_file_upload**
|
||||
- Title: Upload files
|
||||
- Description: Upload one or multiple files
|
||||
- Parameters:
|
||||
- `paths` (array): The absolute paths to the files to upload. Can be a single file or multiple files.
|
||||
- Read-only: **false**
|
||||
|
||||
<!-- NOTE: This has been generated via update-readme.js -->
|
||||
|
||||
- **browser_handle_dialog**
|
||||
- Title: Handle a dialog
|
||||
- Description: Handle a dialog
|
||||
- Parameters:
|
||||
- `accept` (boolean): Whether to accept the dialog.
|
||||
- `promptText` (string, optional): The text of the prompt in case of a prompt dialog.
|
||||
- Read-only: **false**
|
||||
|
||||
</details>
|
||||
|
||||
<!--- End of tools generated section -->
|
||||
|
||||
Reference in New Issue
Block a user