Launch browser with HAR recording, capture traffic manually, then generate Python API client
Launch a browser with HAR recording to manually capture API traffic, then automatically generate a production-ready Python client from the recorded requests. Use this when you need to reverse engineer web APIs by interacting with a site naturally.
/plugin marketplace add kalil0321/reverse-api-engineer/plugin install kalil0321-reverse-api-engineer-plugins-reverse-api-engineer@kalil0321/reverse-api-engineer[task] [url]Launch a browser with HAR recording enabled. The user will navigate manually to trigger the desired API calls. When the browser closes, analyze the captured HAR file and generate a production-ready Python API client.
Ensure the reverse-engineering-api skill is loaded for guidance on HAR analysis and code generation.
task (optional): Description of what to reverse engineer (e.g., "fetch Apple jobs", "scrape product data")url (optional): Starting URL for the browserIf arguments are not provided, prompt the user interactively.
If task argument is not provided:
Ask: "What would you like to reverse engineer? (e.g., 'fetch job listings from Company X')"
If url argument is not provided:
Ask: "What URL should I open? (optional, press Enter to skip)"
Generate a unique run ID using UUID format:
run_id = uuid4() (e.g., "abc-123-def-456")
Setup paths:
har_dir = ~/.reverse-api/runs/har/{run_id}/
har_path = {har_dir}/recording.har
Ensure directory exists:
mkdir -p ~/.reverse-api/runs/har/{run_id}/
Use the Playwright MCP rae-playwright-mcp to launch a browser with HAR recording:
Call MCP tool: playwright_navigate
Parameters:
- url: {url} or "about:blank" if no URL provided
- options:
- record_har: true
- har_path: ~/.reverse-api/runs/har/{run_id}/recording.har
Inform the user:
Browser launched with HAR recording enabled.
Navigate to the website and interact with it to trigger API calls.
Close the browser when you're done to proceed with analysis.
HAR will be saved to: ~/.reverse-api/runs/har/{run_id}/recording.har
Monitor the browser session. When it closes, the HAR file will be saved automatically.
Verify HAR file exists:
ls -lh ~/.reverse-api/runs/har/{run_id}/recording.har
If file doesn't exist or is empty:
Error: "HAR file not found or empty. Please ensure you interacted with the website before closing the browser."
Exit with error
Read and parse the HAR file:
import json
with open("~/.reverse-api/runs/har/{run_id}/recording.har", "r") as f:
har_data = json.load(f)
Use the reverse-engineering-api skill guidance to:
/api/, /v1/, /graphql, XHR/Fetch requestsSummarize findings:
Found {count} relevant API endpoints:
- {method} {endpoint} ({description})
- {method} {endpoint} ({description})
...
Authentication detected: {auth_type} (Bearer token / API key / None)
Base URL: {base_url}
Generate a descriptive name for the script based on the task:
task_name = sanitize(task) # e.g., "apple_jobs_api"
output_dir = ./scripts/{task_name}/
Create output directory:
mkdir -p ./scripts/{task_name}/
Generate api_client.py with the following structure:
"""
Auto-generated API client for {domain}
Generated from HAR capture on {date}
Run ID: {run_id}
HAR file: ~/.reverse-api/runs/har/{run_id}/recording.har
"""
import requests
from typing import Optional, Dict, Any, List
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class {ClassName}Client:
"""API client for {domain}."""
def __init__(
self,
base_url: str = "{base_url}",
session: Optional[requests.Session] = None,
):
self.base_url = base_url.rstrip("/")
self.session = session or requests.Session()
self._setup_session()
def _setup_session(self):
"""Configure session with default headers."""
self.session.headers.update({
"User-Agent": "Mozilla/5.0 (compatible)",
"Accept": "application/json",
# Add detected required headers
})
def _request(
self,
method: str,
endpoint: str,
**kwargs,
) -> requests.Response:
"""Make an HTTP request with error handling."""
url = f"{self.base_url}{endpoint}"
try:
response = self.session.request(method, url, **kwargs)
response.raise_for_status()
return response
except requests.exceptions.RequestException as e:
logger.error(f"Request failed: {e}")
raise
# Generated endpoint methods
# For each detected endpoint, create a method like:
def get_example(self, param: str) -> Dict[str, Any]:
"""
{Method description based on endpoint}.
Args:
param: {Parameter description}
Returns:
JSON response data
Raises:
requests.exceptions.RequestException: If request fails
"""
response = self._request("GET", f"/api/example/{param}")
return response.json()
# Example usage
if __name__ == "__main__":
client = {ClassName}Client()
# Add example calls based on captured endpoints
Generate README.md:
# {Task Name} API Client
Auto-generated Python API client from browser traffic capture.
## Generated From
- **Run ID**: {run_id}
- **HAR File**: ~/.reverse-api/runs/har/{run_id}/recording.har
- **Date**: {date}
- **Base URL**: {base_url}
## Installation
```bash
pip install requests
from api_client import {ClassName}Client
client = {ClassName}Client()
# Example: {endpoint_1}
result = client.{method_1}({params})
print(result)
{List all generated methods with descriptions}
{Describe detected authentication mechanism and how to configure}
### Step 7: Save Run History
Update `~/.reverse-api/history.json` with run metadata:
```json
{
"run_id": "{run_id}",
"mode": "manual",
"task": "{task}",
"url": "{url}",
"timestamp": "{ISO timestamp}",
"har_path": "~/.reverse-api/runs/har/{run_id}/recording.har",
"output_dir": "./scripts/{task_name}/",
"status": "completed"
}
Present final summary to user:
API client generated successfully!
Run ID: {run_id}
HAR file: ~/.reverse-api/runs/har/{run_id}/recording.har
Generated files:
- ./scripts/{task_name}/api_client.py
- ./scripts/{task_name}/README.md
Detected endpoints: {count}
Authentication: {auth_type}
Next steps:
1. Review the generated code
2. Test with: python ./scripts/{task_name}/api_client.py
3. Integrate into your project
/reverse-api-engineer:engineer {run_id} to retry with different approach/reverse-api-engineer:engineer {run_id} to regenerate from same capture/reverse-api-engineer:manual "fetch Apple jobs" https://jobs.apple.com
/reverse-api-engineer:manual "scrape product data"
/reverse-api-engineer:manual