# Claude Context for Playwright MCP Proxy
This document provides context and guidelines for Claude when working with this MCP proxy server project.
## Project Overview
This is a proxy server for Microsoft's playwright-mcp built with Python and FastMCP. It provides efficient handling of large binary data (screenshots, PDFs) through blob storage while maintaining full access to all playwright browser automation capabilities.
## Technology Stack
- **Language**: Python 3.10+
- **Framework**: FastMCP
- **HTTP Client**: requests
- **Package Manager**: uv
- **Testing**: pytest, pytest-asyncio
- **Linting**: ruff
- **Containerization**: Docker
## Project Structure
```
src/playwright_proxy_mcp/
├── server.py # Main MCP proxy server
├── types.py # TypedDict definitions for blob/playwright types
├── playwright/ # Playwright proxy components
│ ├── __init__.py # Package initialization
│ ├── config.py # Configuration loading (env vars)
│ ├── process_manager.py # Subprocess lifecycle management
│ ├── blob_manager.py # Blob storage wrapper (mcp-mapped-resource-lib)
│ ├── middleware.py # Binary interception logic
│ └── proxy_client.py # Proxy client integration
├── api/ # MCP tools
│ ├── __init__.py
│ └── blob_tools.py # Blob retrieval tools
└── utils/ # Utility functions
```
## Key Patterns
### Tool Registration
Tools are registered in `server.py` using the `@mcp.tool()` decorator:
```python
@mcp.tool()
async def my_tool(param: str) -> dict:
"""Tool description shown to clients."""
return {"result": "value"}
```
Or by importing from API modules:
```python
from .api import my_module
mcp.tool()(my_module.my_function)
```
### API Module Structure
Each API module in `src/playwright_proxy_mcp/api/` should:
1. Define async functions that perform specific operations
2. Include comprehensive docstrings (these become tool descriptions)
3. Use type hints for all parameters and return values
4. Handle errors gracefully with informative messages
Example:
```python
async def get_resource(resource_id: str) -> dict:
"""
Get a resource by its ID.
Args:
resource_id: The unique identifier of the resource
Returns:
The resource data
Raises:
ValueError: If the resource is not found
"""
# Implementation here
```
### Type Definitions
Use TypedDict classes in `types.py` for structured data:
```python
class ResourceData(TypedDict):
id: str
name: str
description: str | None
```
### Error Handling
- Raise `ValueError` for invalid input or not found errors
- Raise `RuntimeError` for server/API errors
- Include descriptive error messages
## Development Workflow
### Running the Server
```bash
uv run playwright-proxy-mcp
```
### Running Tests
```bash
uv run pytest -v
```
### Linting
```bash
uv run ruff check src/ tests/
uv run ruff format src/ tests/
```
### Building
```bash
uv build
```
## Coding Standards
1. **Async by default**: All tool functions should be async
2. **Type everything**: Use type hints for parameters, returns, and variables
3. **Document thoroughly**: Docstrings are exposed to MCP clients
4. **Test comprehensively**: Each API function should have tests
5. **Handle errors gracefully**: Provide informative error messages
## Adding New Features
When adding new functionality:
1. Create a new module in `src/playwright_proxy_mcp/api/`
2. Define async functions with proper docstrings
3. Add TypedDict definitions in `types.py` if needed
4. Register tools in `server.py`
5. Write tests in `tests/`
6. Update this documentation if patterns change
## Handling Large Files and Binary Data
### Using mcp-mapped-resource-lib
For MCP servers that need to handle large file uploads/downloads or binary blob storage, use the **mcp-mapped-resource-lib** library instead of implementing custom blob storage:
**Installation:**
```bash
pip install mcp-mapped-resource-lib
```
**Key Features:**
- Blob management with unique identifiers (`blob://TIMESTAMP-HASH.EXT`)
- Metadata storage alongside blobs
- Automatic TTL-based expiration and cleanup
- Content deduplication via SHA256
- Security features (path traversal prevention, MIME validation, size limits)
- Docker volume integration for shared storage across containers
**Basic Usage:**
```python
from mcp_mapped_resource_lib import BlobStorage
# Initialize storage
storage = BlobStorage(
storage_root="/mnt/blob-storage",
max_size_mb=100
)
# Upload a blob
result = storage.upload_blob(
data=b"file content",
filename="document.pdf"
)
# Retrieve metadata
metadata = storage.get_metadata(result['blob_id'])
# Delete when done
storage.delete_blob(result['blob_id'])
```
**Docker Setup:**
When using with Docker, mount a shared volume for blob storage:
```yaml
volumes:
- blob-storage:/mnt/blob-storage
```
**Important:** This library requires `libmagic` for MIME detection:
- Ubuntu/Debian: `apt-get install libmagic1`
- macOS: Install via Homebrew
For more details, see: https://github.com/nickweedon/mcp_mapped_resource_lib
## Common Tasks
### Add a new API endpoint/tool
1. Create function in appropriate `api/` module
2. Add types in `types.py`
3. Register in `server.py`: `mcp.tool()(module.function)`
4. Write tests
### Add a new resource
Resources provide read-only data access:
```python
@mcp.resource("myserver://resource-name")
async def get_resource() -> str:
"""Resource description."""
return "resource content"
```
### Add a new prompt
Prompts are templates for common operations:
```python
@mcp.prompt()
def my_prompt() -> str:
"""Prompt description."""
return "Prompt template text..."
```
## Environment Variables
Configure in `.env`:
- `API_KEY`: Authentication key for backend API
- `API_BASE_URL`: Base URL for API requests
- `API_TIMEOUT`: Request timeout in seconds
- `DEBUG`: Enable debug logging
## Troubleshooting
### Checking Claude Desktop Logs
When working in the devcontainer, Claude Desktop MCP server logs are mounted at:
- **Path**: `/workspace/logs/`
- **Source**: `C:\Users\nickw\AppData\Roaming\Claude\logs\`
These logs contain output from the MCP server as it's being used by the Claude Desktop application. When asked to check logs or diagnose issues, refer to the ```mcp-server-playwright-proxy-mcp-docker.log``` file.
**Common log commands**:
```bash
# View last 50 lines
tail -n 50 /workspace/logs/claude-desktop-mcp.log
# Follow logs in real-time
tail -f /workspace/logs/claude-desktop-mcp.log
# Search for errors
grep -i error /workspace/logs/claude-desktop-mcp.log
# View full log
cat /workspace/logs/claude-desktop-mcp.log
```
### Server won't start
1. Check that all dependencies are installed: `uv sync`
2. Verify `.env` file exists and has required variables
3. Check for syntax errors: `uv run python -m py_compile src/playwright_proxy_mcp/server.py`
4. Check Claude Desktop logs: `tail -f /workspace/logs/claude-desktop-mcp.log`
### Tests failing
1. Ensure test dependencies are installed: `uv sync`
2. Run with verbose output: `uv run pytest -v --tb=long`
### Docker issues
1. Rebuild image: `docker compose build --no-cache`
2. Check logs: `docker compose logs -f`
3. Check Claude Desktop MCP logs: `tail -f /workspace/logs/claude-desktop-mcp.log`