🐉 Automate Browser-based workflows using LLMs and Computer Vision 🐉
Skyvern automates browser-based workflows using LLMs and computer vision. It provides a Playwright-compatible SDK that adds AI functionality on top of playwright, as well as a no-code workflow builder to help both technical and non-technical users automate manual workflows on any website, replacing brittle or unreliable automation solutions.

Traditional approaches to browser automations required writing custom scripts for websites, often relying on DOM parsing and XPath-based interactions which would break whenever the website layouts changed.
Instead of only relying on code-defined XPath interactions, Skyvern relies on Vision LLMs to learn and interact with the websites.
Skyvern was inspired by the Task-Driven autonomous agent design popularized by BabyAGI and AutoGPT -- with one major bonus: we give Skyvern the ability to interact with websites using browser automation libraries like Playwright.
Skyvern uses a swarm of agents to comprehend a website, and plan and execute its actions:

This approach has a few advantages:
https://github.com/user-attachments/assets/5cab4668-e8e2-4982-8551-aab05ff73a7f
Skyvern Cloud is a managed cloud version of Skyvern that allows you to run Skyvern without worrying about the infrastructure. It allows you to run multiple Skyvern instances in parallel and comes bundled with anti-bot detection mechanisms, proxy network, and CAPTCHA solvers.
If you'd like to try it out, navigate to app.skyvern.com and create an account.
Choose your preferred setup method:
Database default:
skyvern quickstartandskyvern run serverdefault to a SQLite database at~/.skyvern/data.dbso the pip path works without Postgres or Docker. To use Postgres instead, pass--postgresfor a local container or--database-stringfor an existing database. Docker Compose always uses the bundled Postgres service.
Dependencies needed: - Python 3.11, 3.12, or 3.13
Additionally, for Windows: - Rust - VS Code with C++ dev tools and Windows SDK
pip install "skyvern[all]"
skyvern quickstart
The pip quickstart uses SQLite by default. For a local Postgres container, run skyvern quickstart --postgres.
Use this option if you want everything containerized (Postgres, API, UI) and don't want to install Python/Node locally.
bash
git clone https://github.com/skyvern-ai/skyvern.git && cd skyvern.env (the quickstart --docker-compose command below will create it from .env.example if missing):
bash
cp .env.example .env # if not already created
# edit .env to add your LLM API keybash
docker compose up -d(sqlite3.OperationalError) table organizations already exists — You hit a known bug in pip install skyvern==1.0.31. Fix:
rm ~/.skyvern/data.db # remove the leftover SQLite file
pip install --upgrade skyvern # 1.0.32+ contains the fix
skyvern quickstart
If you are still on 1.0.31 and cannot upgrade, install via uv instead:
uv pip install skyvern
pip install skyvern fails with ResolutionImpossible (litellm / fastmcp) — You hit a dependency-resolution conflict in 1.0.31. Either upgrade to 1.0.32+ or use uv: uv pip install skyvern.
Skyvern is a Playwright extension that adds AI-powered browser automation. It gives you the full power of Playwright with additional AI capabilities—use natural language prompts to interact with elements, extract data, and automate complex multi-step workflows.
Installation:
- Python SDK / cloud API: pip install skyvern
- Local server + packaged UI: pip install "skyvern[all]" then run skyvern quickstart
- Local server + packaged UI with Postgres: pip install "skyvern[all]" then run skyvern quickstart --postgres
- Packaged UI for an existing API: pip install "skyvern[ui]" then run
skyvern run ui --api-url <api-url> --api-key <api-key>
- TypeScript: npm install @skyvern/client
Skyvern adds four core AI commands directly on the page object:
| Command | Description |
|---|---|
page.act(prompt) |
Perform actions using natural language (e.g., "Click the login button") |
page.extract(prompt, schema) |
Extract structured data from the page with optional JSON schema |
page.validate(prompt) |
Validate page state, returns bool (e.g., "Check if user is logged in") |
page.prompt(prompt, schema) |
Send arbitrary prompts to the LLM with optional response schema |
Additionally, page.agent provides higher-level workflow commands:
| Command | Description |
|---|---|
page.agent.run_task(prompt) |
Execute complex multi-step tasks |
page.agent.login(credential_type, credential_id) |
Authenticate with stored credentials (Skyvern, Bitwarden, 1Password) |
page.agent.download_files(prompt) |
Navigate and download files |
page.agent.run_workflow(workflow_id) |
Execute pre-built workflows |
All standard Playwright actions support an optional prompt parameter for AI-powered element location:
| Action | Playwright | AI-Augmented |
|---|---|---|
| Click | page.click("#btn") |
page.click(prompt="Click login button") |
| Fill | page.fill("#email", "a@b.com") |
page.fill(prompt="Email field", value="a@b.com") |
| Select | page.select_option("#country", "US") |
page.select_option(prompt="Country dropdown", value="US") |
| Upload | page.upload_file("#file", "doc.pdf") |
page.upload_file(prompt="Upload area", files="doc.pdf") |
Three interaction modes:
# 1. Traditional Playwright - CSS/XPath selectors
await page.click("#submit-button")
# 2. AI-powered - natural language
await page.click(prompt="Click the green Submit button")
# 3. AI fallback - tries selector first, falls back to AI if it fails
await page.click("#submit-btn", prompt="Click the Submit button")
# act - Perform actions using natural language
await page.act("Click the login button and wait for the dashboard to load")
# extract - Extract structured data with optional JSON schema
result = await page.extract("Get the product name and price")
result = await page.extract(
prompt="Extract order details",
schema={"order_id": "string", "total": "number", "items": "array"}
)
# validate - Check page state (returns bool)
is_logged_in = await page.validate("Check if the user is logged in")
# prompt - Send arbitrary prompts to the LLM
summary = await page.prompt("Summarize what's on this page")
Run via UI:
skyvern run all
Navigate to http://localhost:8080 to run tasks through the web interface. If the packaged UI is missing, skyvern run ui will offer to install the matching UI package. For non-interactive setup, use skyvern run ui --install-ui or skyvern run all --install-ui.
To run only the packaged UI against an existing Skyvern API, install skyvern[ui] and pass
--api-url; the CLI infers --wss-url from the API URL unless you override it. You can also set
VITE_API_BASE_URL, VITE_WSS_BASE_URL, VITE_ARTIFACT_API_BASE_URL, VITE_SKYVERN_API_KEY,
and VITE_BROWSER_STREAMING_MODE before running skyvern run ui.
Python SDK:
from skyvern import Skyvern
# Local mode
skyvern = Skyvern.local()
# Or connect to Skyvern Cloud
skyvern = Skyvern(api_key="your-api-key")
# Launch browser and get page
browser = await skyvern.launch_cloud_browser()
page = await browser.get_working_page()
# Mix Playwright with AI-powered actions
await page.goto("https://example.com")
await page.click("#login-button") # Traditional Playwright
await page.agent.login(credential_type="skyvern", credential_id="cred_123") # AI login
await page.click(prompt="Add first item to cart") # AI-augmented click
await page.agent.run_task("Complete checkout with: John Snow, 12345") # AI task
TypeScript SDK:
import { Skyvern } from "@skyvern/client";
const skyvern = new Skyvern({ apiKey: "your-api-key" });
const browser = await skyvern.launchCloudBrowser();
const page = await browser.getWorkingPage();
// Mix Playwright with AI-powered actions
await page.goto("https://example.com");
await page.click("#login-button"); // Traditional Playwright
await page.agent.login("skyvern", { credentialId: "cred_123" }); // AI login
await page.click({ prompt: "Add first item to cart" }); // AI-augmented click
await page.agent.runTask("Complete checkout with: John Snow, 12345"); // AI task
await browser.close();
Simple task execution:
from skyvern import Skyvern
skyvern = Skyvern()
task = await skyvern.run_task(prompt="Find the top post on hackernews today")
print(task)
Let Skyvern control your existing Chrome browser — with all your cookies, logins, and extensions.
chrome://inspect/#remote-debugging[!TIP] The
skyvern init browsercommand can do this automatically — it openschrome://inspect/#remote-debugging, waits for you to enable it, and saves the config.
Option A — Python Code:
from skyvern import Skyvern
skyvern = Skyvern(
base_url="http://localhost:8000",
api_key="YOUR_API_KEY",
browser_address="http://127.0.0.1:9222",
)
task = await skyvern.run_task(
prompt="Find the top post on hackernews today",
)
Option B — Skyvern Service:
Add two variables to your .env file:
BROWSER_TYPE=cdp-connect
BROWSER_REMOTE_DEBUGGING_URL=http://127.0.0.1:9222
Restart Skyvern service skyvern run all and run the task through UI or code
Let Skyvern Cloud control a Chrome browser running on your machine — with all your existing cookies, logins, and extensions. Useful for automating sites where you're already logged in or behind a VPN.
# One command to start Chrome + create a tunnel to Skyvern Cloud
skyvern browser serve --tunnel
Then use the tunnel URL in your task:
from skyvern import Skyvern
skyvern = Skyvern(api_key="your-api-key")
task = await skyvern.run_task(
prompt="Download the latest invoice from my account",
browser_address="https://abc123.ngrok-free.dev",
)
[!WARNING] Always use
--api-keywhen exposing your browser via a tunnel. Without it, anyone with the URL has full control of your browser. See the security docs.
See the full documentation for all options, manual tunnel setup, and
$ claude mcp add skyvern \
-- python -m otcore.mcp_server <graph>