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:
Matthew Raymer
2025-07-22 09:18:30 +00:00
parent 2f38eba4ff
commit db5da0cdfc
127 changed files with 956 additions and 0 deletions

View 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

View 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

View 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

View 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:
[![Install MCP Server](https://cursor.com/deeplink/mcp-install-dark.svg)](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 -->