From website-to-api
Reverse-engineer a website's internal API using Chrome browser automation. Use when asked to discover, wrap, or build a programmatic interface for a website that doesn't have a public API. Guides the process of finding endpoints, extracting auth, and building scripts.
How this skill is triggered — by the user, by Claude, or both
Slash command
/website-to-api:website-to-apiThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
A systematic approach to discovering and wrapping any website's internal API using Chrome browser automation (Claude in Chrome extension).
A systematic approach to discovering and wrapping any website's internal API using Chrome browser automation (Claude in Chrome extension).
substack) has broken and needs re-discoveryEvery modern web application fetches data from internal API endpoints. This skill teaches a repeatable 4-step process to discover and wrap those endpoints.
Navigate to the target website using the Chrome extension and observe what API calls the page makes.
Tools needed:
ToolSearch("select:mcp__claude-in-chrome__tabs_context_mcp,mcp__claude-in-chrome__navigate,mcp__claude-in-chrome__javascript_tool,mcp__claude-in-chrome__read_network_requests,mcp__claude-in-chrome__get_page_text,mcp__claude-in-chrome__read_page")
Procedure:
Get tab context and navigate:
mcp__claude-in-chrome__tabs_context_mcp(createIfEmpty=true)
mcp__claude-in-chrome__navigate(url="https://target-site.com", tabId=TAB_ID)
Enable network tracking, then trigger actions:
mcp__claude-in-chrome__read_network_requests(tabId=TAB_ID) // starts tracking
Navigate or interact with the page to trigger API calls, then read:
mcp__claude-in-chrome__read_network_requests(tabId=TAB_ID, urlPattern="api")
Inspect page globals for config:
// Run via javascript_tool — look for app config, API base URLs, user info
JSON.stringify(Object.keys(window).filter(k =>
k.includes('config') || k.includes('api') || k.includes('app') || k.startsWith('__')
));
Check for framework data (Next.js, etc.):
// Next.js apps embed data in __NEXT_DATA__
const nd = document.getElementById('__NEXT_DATA__');
nd ? JSON.stringify(Object.keys(JSON.parse(nd.textContent))) : 'not Next.js';
Try common API patterns:
// Most sites use /api/v1/ or similar
fetch('/api/v1/...', { credentials: 'include' })
.then(r => r.json())
.then(data => { document.title = JSON.stringify(Object.keys(data)); });
Document what you find — endpoints, parameters, response shapes.
Most sites use httpOnly session cookies that JavaScript cannot read. The browser sends them automatically with fetch() using credentials: 'include'.
Verify auth works:
// Run via javascript_tool on the target site
fetch('/api/v1/some-endpoint', { credentials: 'include' })
.then(r => r.json())
.then(data => { document.title = JSON.stringify({ authenticated: true }); })
.catch(e => { document.title = 'ERROR: ' + e.message; });
Compare auth vs no-auth:
# Unauthenticated (from terminal)
curl -s 'https://target-site.com/api/v1/endpoint' | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(str(d)))"
Compare the response size/content with the browser-based fetch to identify what auth adds.
Find the cookie name:
window._analyticsConfig or similar globals for site metadataconnect.sid, {site}.sid, session, _session_idFor script usage, the user must extract the cookie value once:
export SITE_AUTH_COOKIE="<value>"Create a Python CLI script using PEP 723 inline metadata (runs via uv run, no install needed).
Script template: See templates/site-skill-template/scripts/client.py.template
Key principles:
httpx for HTTP, typer for CLI, rich for display, markdownify for HTML→MD--sid/--cookie flagget-text command that fetches content and saves as MarkdownCreate a SKILL.md that documents:
Every site-specific skill MUST include this section:
## If This Breaks
This skill uses an internal, undocumented API. If commands fail:
1. Read the error — 401/403 likely means expired cookie or renamed cookie
2. Re-discover using the `website-to-api` meta-skill
3. Update this skill's SKILL.md and scripts with the new API shape
document.title (which truncates and corrupts data)get_page_text for extracting rendered page content — it's simpler than transferring HTML through JavaScriptdocument.title for data larger than ~500 chars — it truncates silently and causes data corruptionnpx claudepluginhub hamelsmu/website-to-apiCaptures HTTP traffic from web apps using Playwright CLI with site fingerprinting for frameworks, protections, iframes, auth, APIs, plus tracing and HAR export. For API discovery and site analysis.
Explores websites with Playwright to reverse-engineer APIs, document network flows, and generate crawler code. Useful for scraping, API analysis, and anti-bot bypass planning.
Integrates Firecrawl web data capabilities into application code: web search, scraping, structured extraction, and browser interaction. Activates when building features that need live web data.