New: MCP server, saved tests and a CI runner

ASTRAL — The agentic browser for the agentic era

AI agents and you work in the same real browser tabs. Connect Claude Code, Cursor or any MCP client, watch every click as it happens, and keep the tests your agent writes — with your credentials locked in the OS keychain.

Curious about UADP? Read how it works

macOS · Windows · Linux — developer tools macOS first free download →
MCP server · macOS first

Built for agentic development

Astral is an MCP server for testing the pages you build. Your coding agent drives the tab in front of you, and you see exactly what it does.

Your agent, your tabs

Connect Claude Code, Cursor, VS Code or any MCP client in one click. Agents read compact page snapshots and click, type and navigate in the real tabs you see — on macOS, as trusted native input.

Test runs with evidence

astral.test, step and expect produce a report per step: screenshots with the click drawn on them, network and console evidence, page performance and an optional video of the run.

Saved, reproducible tests

Tests live in .astral/tests in your repo, linked to the ticket they verify. The agent opens one in Astral; you press ▶ Play and watch it in slow motion, pause or go step by step.

Credentials stay in the keychain

Scripts refer to a credential by name. Astral types the secret itself, only on the project's own origins, and masks it in every result, report and log. The agent never sees it.

DevTools shared with your agent

Network, console, an Error Inbox that groups failures and links them to the click that caused them, and page performance with web vitals. It persists across reloads, and agents read the same data.

You stay in control

Choose which panels an agent may see, switch tool groups on and off, and follow every call in a live activity feed and an audit log.

Connect in one line

Turn on Developer mode, then use the one-click setup in Settings → Developer, or paste the command it shows into your terminal.

claude mcp add --scope user astral -- "/Applications/Astral.app/Contents/MacOS/astral-mcp"
Command that adds Astral as an MCP server to Claude Code on macOS

The path is where macOS installs Astral; Settings shows the exact command for your install. Cursor, VS Code, Claude Desktop and Windsurf get the same one-click setup.

A test your agent can write — and you can replay

// .astral/tests/checkout.astral.js — linked to a ticket, replayable with ▶ Play
return await astral.test('Sign in and pay', async () => {
  await astral.step('Sign in', async () => {
    await astral.navigate({url: astral.url('/login')});
    await astral.fill({locator: {role: 'textbox', name: 'Email'}, credential: 'shop.demo', field: 'username'});
    await astral.fill({locator: {role: 'textbox', name: 'Password'}, credential: 'shop.demo', field: 'password'});
    await astral.click({locator: {role: 'button', name: 'Sign in'}});
    await astral.expect.url('/account');
  });
  await astral.step('Pay', async () => {
    await astral.click({locator: {role: 'button', name: 'Pay'}});
    await astral.expect.request({urlContains: '/api/checkout', method: 'POST', status: '2xx'});
    await astral.expect.noErrors();
  });
}, {record: 'video'});
credential: 'shop.demo' is a name from .astral/config.json; the password itself comes from the OS keychain and shows as ••••••.
Saved tests · macOS first

Tests your agents can prove

When an agent says a flow works, it hands you the run: what it did at every step, what the page answered, and a test you can replay yourself.

A report, not a claim

Every run writes report.html and report.json: a screenshot per step with the click drawn on it, the network requests, console errors and Error Inbox groups of that step, performance per navigation, and an optional video.

▶ Play replays without tokens

A saved test is a script in .astral/tests, versioned with your repo and linked to its ticket. ▶ Play, test_run and the CI runner execute that script, not the model, so a replay spends no tokens and runs the same steps every time.

Collections and environments

Group tests into ordered collections and run them against local, staging or prod from .astral/config.json. Collections run in order, in one visible tab, and write a summary report with a link to each test.

Production stays protected

Mark an environment protected and only tests saved as readOnly may run there. Agents get a clear refusal, collections skip the rest with the reason, and the app asks before it runs anything on it.

History at a glance

Each replay is added to a local run history, kept on this machine and never in the repo. The Tests panel shows the latest runs per environment as green and red dots; agents read the same history with test_history.

Watch it, or let the agent press Play

By default the agent opens the test paused and you press ▶ Play: slow motion, pause, step by step. For demos it can start Play itself and open DevTools on the view it wants to show you. The run is labelled with the agent's name and you keep Pause, Step and Stop.

One file describes where tests may run

Environments, collections and credentials live in .astral/config.json. A secret is never written there: it is a reference to the OS keychain, an ASTRAL_TEST_* variable or a git-ignored local file, and Astral refuses a password in plain text.

{
  "project": "shop",
  "envs": {
    "local":   { "baseUrl": "http://127.0.0.1:4555" },
    "staging": { "baseUrl": "https://staging.shop.test" },
    "prod":    { "baseUrl": "https://shop.test", "protected": true }
  },
  "defaultEnv": "local",
  "collections": {
    "smoke": { "name": "Smoke", "tests": ["login-demo", "home-loads"] }
  },
  "credentials": {
    "shop.demo": {
      "username": "[email protected]",
      "password": { "keychain": "shop.demo.password" }
    }
  }
}
Example project configuration with a protected prod environment and a smoke collection
astral-test · headless runner

Run them in CI

astral-test runs the same saved tests without opening Astral: in GitHub Actions, in GitLab, or inside your agent's loop. Same collections, same protected-environment rules.

one binary, no browser bundled
~13 MB
engine start
0.4–0.7 s
per test
1–3 s
runner memory, plus the browser
15–28 MB

Measured on macOS with Chrome against a demo app. The browser's own memory is not included.

Drop it into a workflow

name: e2e
on: [push, pull_request]
jobs:
  astral-test:
    runs-on: ubuntu-latest          # ships with Google Chrome
    steps:
      - uses: actions/checkout@v4
      # Put astral-test on the PATH (binaries: see Downloads)
      - name: Start the app under test
        run: npm start &            # your app
      - name: Run saved tests
        run: |
          astral-test run . --collection smoke --engine cdp \
            --reporter pretty --reporter junit --out astral-test-results
        env:
          ASTRAL_TEST_SHOP_DEMO_PASSWORD: ${{ secrets.SHOP_DEMO_PASSWORD }}
      - if: always()
        uses: actions/upload-artifact@v4
        with: { name: astral-test-results, path: astral-test-results }
      - if: always()
        uses: mikepenz/action-junit-report@v4
        with: { report_paths: astral-test-results/junit.xml }
JUnit for your CI's test view, and a report.html per test as an artifact. In CI, credentials come from ASTRAL_TEST_* secrets; the keychain stays in the app, and every resolved secret is masked in the output.

Output an agent can act on

With --reporter json, one JSON event per line: which step failed, what was expected, what the page showed, the URL, an excerpt of the page tree around the target, failing requests and console errors.

{"schemaVersion":1,"type":"step_end","testId":"wrong-greeting","step":2,"name":"Greeting","status":"failed","durationMs":5134,"error":"expect.text heading nth 0 contains \"Hi, Nobody\" — got \"Hi, Demo User\", \"Preferences\", \"Session\""}{"schemaVersion":1,"type":"test_end","testId":"wrong-greeting","status":"failed","durationMs":6964,"failure":{"kind":"assertion","step":2,"stepName":"Greeting","expected":"Hi, Nobody","actual":"\"Hi, Demo User\", \"Preferences\", \"Session\"","url":"http://127.0.0.1:4555/account","domExcerpt":"…"},"reportHtml":"/out/wrong-greeting/report.html"}{"schemaVersion":1,"type":"run_end","status":"failed","exitCode":1,"totals":{"tests":6,"passed":4,"failed":2,"skipped":0,"errors":0},"durationMs":18896}
Trimmed from a real run (fields elided). Every line carries type and schemaVersion; run_end is always last.
  • 0 every selected test passed
  • 1 a test failed: the app did not do what the test expects
  • 2 usage or config: unknown test, env or credential
  • 3 engine: no browser found, or it did not start

--engine cdp

Google Chrome, Chromium or Microsoft Edge already on the machine, or any browser you started with DevTools (--cdp-url). Full rendering, screenshots and video. Nothing is downloaded.

--engine lite experimental

Lightpanda (opens in a new tab), if you installed it: DOM and JavaScript without rendering, page trees instead of screenshots. Not verified or measured yet. Lightpanda is AGPL-3.0; astral-test only starts it as a separate process.

MCP · extensions · plugins

Works with your editor and agent

One command registers Astral's MCP server with the client you already use, and your agent gets a short guide on how to test with it.

astral-mcp setup --client <x>

astral-mcp setup --client claude-code --project .

Writes .mcp.json in the project. Without --project it prints the official claude mcp add --scope user command instead of editing Claude Code's own state file.

astral-mcp setup --list shows every client and whether it is installed; --client all-detected sets up all of them.

  • Merges into the existing file and keeps every other server and key
  • Backs the file up before changing it; running it twice changes nothing
  • Writes only the binary path: no tokens, no secrets
  • --dry-run shows the diff, --instructions adds Astral's section to AGENTS.md

VS Code extension

Coming soon

Visual Studio Marketplace and Open VSX: Cursor, Windsurf, Antigravity, VSCodium

  • Saved tests and collections in the Test Explorer, run through astral-test
  • Failures land on the line of the step that failed, with expected and actual as a diff
  • ▶ Run and ▶ Open in Astral above every test file
  • Never sends a non-readOnly test to a protected environment

In VS Code 1.101 and later it also registers the Astral MCP server for you.

Claude Code plugin

Coming soon

The astral-testing skill

When to reach for Astral, how to save, run and read tests, and the credential rules: never ask for or print a secret.

Not published yet. Once it is, two commands install it:

/plugin marketplace add Perseusoft/astral
/plugin install astral@astral

The plugin brings the skill; astral-mcp setup --client claude-code connects the server.

Any agent that reads AGENTS.md

Codex, Cursor, Antigravity · GEMINI.md for Gemini CLI

--instructions adds the same guide, shorter, between astral:begin and astral:end markers. Running it again replaces the block instead of duplicating it.

JetBrains plugin coming

Today: --client jetbrains --print gives you the JSON for AI Assistant's MCP settings.

The same tab, not a hidden one

How Astral compares with classic headless automation.

Astral compared with classic headless browser automation
Aspect Astral Classic headless automation
Where it runs In the tab you are looking at, with a separate profile per project In a separate browser, usually headless, started for each run
Seeing what happened Watch it live, or press ▶ Play to replay in slow motion, step by step Traces, logs and videos you open after the run
Credentials OS keychain; Astral types them and the agent never sees them Often environment variables or .env files the test process can read
Debugging context Network, console, Error Inbox and performance, shared with the agent Whatever the test collects, read after the fact
Best at The daily loop: you and your agent building and checking a flow together Large suites in CI, run in parallel across several browser engines

Astral doesn't replace your CI suite. Use it where you build and review flows with your agent; the same saved tests can then run headless in CI with astral-test, next to the suites you already have.

How is Astral different from Playwright MCP or a browser extension?

Both are good tools, and you can use them alongside Astral. Here is what each is built around.

Playwright MCP

A mature way to let an agent drive Chromium, Firefox or WebKit through Playwright. It can save traces and video and generate Playwright code, and Playwright scales to large parallel suites.

A browser extension

Puts an agent inside the browser you already use, with your everyday profile and the sites you are signed in to. Nothing new to install beyond the extension.

What Astral adds

Evidence reports
Each run's report has a screenshot per step with the click marked, plus that step's requests, console errors and performance.
Token-free replay
Saved tests replay from the script in your repo, with ▶ Play in the app or astral-test in CI. No model call per run.
Protected environments
Production can be marked protected, and then only tests saved as readOnly may run there.
The same DevTools
For the tabs you let it reach, the agent reads the same network, console, Error Inbox and performance data you see in the DevTools drawer.
Keychain credentials
Tests name a credential; Astral types it on the project's origins. The agent never receives the secret.
DevTools · performance

Web Vitals you and your agent both read

The Performance tab of the DevTools drawer rates every load green, amber or red, explains the slow part in a sentence, and draws the load timeline.

Rating thresholds for each metric
Metric Good Poor
TTFB ≤ 0.8 s > 1.8 s
FCP ≤ 1.8 s > 3 s
LCP ≤ 2.5 s > 4 s
INP ≤ 200 ms > 500 ms
CLS ≤ 0.1 > 0.25

The web-vitals thresholds. On macOS the WebKit engine does not report CLS, long tasks or JavaScript memory, so those read "not available".

  • Measured where the page cannot touch it

    The collector runs in an isolated world, so the page cannot see or fake it. Load phases, FCP, LCP and its element, INP, and resources by type and weight, for every document a tab shows.

  • Honest gaps

    What the engine cannot measure says not available, and what has not happened yet says waiting. Never a 0.

  • Did it get slower?

    The last loads of each page are kept while Astral is open, with every metric compared against their median: better, same or worse.

  • Same numbers for the agent and the report

    Agents call page_performance; test reports include a performance table for every navigation of the run.

  • The agent can show you

    With devtools_show, an agent opens the DevTools drawer on Issues, Network, Console or Performance, or on one request's timings, while it explains what it found.

Preview · bring your own key

A chat that can use the browser

No coding agent needed. Ask Astral's chat to look something up or try a flow on a site, and it works in a real tab while you watch.

  • Turn on Browse in the chat composer and the chat can open, read and click through a tab.
  • Every step shows live in the conversation, and Stop is always one click away.
  • It asks before it submits, pays or deletes anything. Saved passwords never reach the model.
  • Runs with your own model key: page content goes only to the provider you choose.
Local · no account

Bookmarks that stay on your device

Bring your bookmarks with you in one click. They are stored in a local database on your machine: no account, no server, nothing leaves the device.

  • Chrome
  • Edge
  • Brave
  • Arc
  • Firefox
  • Safari
  • HTML file

Complete on macOS, where some browsers' data needs Full Disk Access (or an HTML export); best effort on Windows and Linux.

  • ☆ in the address bar, or ⌘D / Ctrl+D, saves the page; ★ lets you rename it or move it to a folder.
  • A Bookmarks section in the Workspace sidebar, with folders and search that ignores case and accents.
  • Imports keep the folder structure, skip what you already have, and never write to the other browser's files.
  • Export everything as a standard bookmarks HTML file whenever you want.

Your local apps, inside Astral

Plugins let the apps already running on your computer — a music player, a task list, your notes — show up in Astral while they're open.

  • music
  • video
  • tasks
  • notes
  • messaging
  • generic

Pick a type, get the UI

A plugin declares what it is. A music player gets a now-playing pill and a player panel with its queue and library; other types work today through generic action panels.

Control it without switching apps

Play, pause, skip or pick from the queue in Astral while the audio keeps playing in your app. Each plugin only gets the scopes you approved when pairing.

Paired, local, scoped

Plugins talk to Astral on 127.0.0.1 only. You pair each app with a 6-digit code, its token lives in the OS keychain, and every action lands in an audit log.

No SDK to install

The contract is HTTP, JSON and server-sent events. The Plugin SDK guide walks through it, with a mock plugin and a conformance suite to test against.

How Astral works

One sentence goes in. Structured, rendered data comes out. Everything in between is the agent.

Ask — User

"Show me my bank balance and latest tweets"

Mind — Intent

Matched 2 services: orbit, nova

UADP — Discover

/.well-known/uadp.json → manifests

Auth — Passkey

Token valid for 3600s

Render — UI

2 panels: BankAccountCard + SocialFeed

A new paradigm for browsing

Astral isn't a traditional browser. It's an AI-native platform where agents interact with services on your behalf through the UADP protocol.

Agent-Driven

No tabs, no URLs. Tell your AI agent what you need and it fetches, filters, and presents your data across all connected services.

UADP Protocol

Universal Agentic Data Protocol — structured JSON instead of HTML scraping. Services expose data via standardized manifests that agents discover automatically.

View on GitHub →

Passkey Security

Your private keys never leave your device. WebAuthn passkeys backed by Secure Enclave, TPM, or StrongBox provide zero-password authentication.

14 UADP Services

Social feeds, banking, commerce, streaming, news, messaging, music, maps, food delivery, email — all accessible through a single conversational interface.

Customizable UI

ComponentConfig is serializable JSON. Customize your entire layout by voice, sync across devices, and let the agent arrange your panels.

Cross-Platform

Built with Tauri 2 — runs natively on macOS, Windows, and Linux. Android and iOS apps are on the roadmap, from the same codebase.

Pre-alpha · v0.2

Download Astral

Native desktop builds for macOS, Windows, and Linux. Free download, runs locally — your private keys and data never leave your device.

Astral desktop

Pick your platform:

First open on every platform

Pre-alpha builds ship unsigned: macOS Gatekeeper and Windows SmartScreen will warn you the first time you open Astral. Pick a platform below and this note shows the exact command for it.

Why it is unsigned, and the notes for every platform ↓
  • Windows: Agent and test tools are coming to Windows: WebView2 support is in progress.
  • Linux: Agent and test tools are not available on Linux yet.
v0.2.1manifest not live yet

Unsigned build · install at your own decision

Astral is in pre-alpha and ships without code-signing certificates from Apple or Microsoft. macOS Gatekeeper and Windows SmartScreen will warn you when you try to open the installer. By downloading, you accept that you are installing software that has not been notarized by an OS vendor. We will introduce signing once the project exits pre-alpha.

How to bypass the OS warning

macOS

macOS attaches a com.apple.quarantine flag to every file your browser downloads. Gatekeeper blocks the app until the flag is removed — even if you allowed apps from anywhere in System Settings.

If you already moved Astral to Applications and it refuses to open ("damaged" / "cannot be verified"), run:

sudo xattr -cr /Applications/Astral.app

Then double-click Astral. Alternative: clean the .dmg before mounting it:

xattr -d com.apple.quarantine ~/Downloads/Astral_*.dmg

Windows

When SmartScreen says "Windows protected your PC", click More info → Run anyway.

Linux

Make the AppImage executable and run it:

chmod +x Astral_*.AppImage
./Astral_*.AppImage

Or install the .deb on Debian/Ubuntu:

sudo dpkg -i Astral_*.deb

Developer tools

The CI runner, the MCP bridge, the editor extension and the Claude Code plugin are not published yet. They are listed so you know what is coming; nothing below is a dead link.

  • astral-test · CI runner

    astral-test · macOS Apple Silicon

    Single binary. Uses a Chrome, Chromium or Edge you already have.

    Coming soon
  • astral-test · CI runner

    astral-test · macOS Intel

    Single binary. Uses a Chrome, Chromium or Edge you already have.

    Coming soon
  • astral-test · CI runner

    astral-test · Linux x64

    For CI runners such as GitHub Actions ubuntu-latest, which ship Chrome.

    Coming soon
  • astral-test · CI runner

    astral-test · Windows x64

    Single binary. Uses a Chrome, Chromium or Edge you already have.

    Coming soon
  • MCP bridge

    astral-mcp

    No separate download: it ships inside the Astral desktop installer, starting with the release that brings the MCP server.

    Coming soon
  • Editor extension

    VS Code extension · Visual Studio Marketplace

    Astral Tests (perseusoft.astral-tests) for VS Code.

    Coming soon
  • Editor extension

    VS Code extension · Open VSX

    The same extension for Cursor, Windsurf, Antigravity and VSCodium.

    Coming soon
  • Agent plugin

    Claude Code plugin

    The astral-testing skill: when to use Astral and how to save, run and read tests.

    Once it is published

    /plugin marketplace add Perseusoft/astral
    /plugin install astral@astral
    Coming soon
  • Optional engine

    Lightpanda (optional engine)

    Experimental lite engine for astral-test: DOM and JavaScript without rendering. AGPL-3.0, installed by you; Astral never bundles or downloads it.

Open protocol

What is UADP?

A lightweight open protocol that lets AI agents talk to any service through the same interface — no custom SDKs, no per-service integrations.

The protocol

UADP in three lines

  • ◆ Every service publishes a manifest at /.well-known/uadp.json.
  • ◆ The manifest lists endpoints, types and AI hints — agents read it and know what to do.
  • ◆ All responses use UADP+JSON with a uadp_type field, so rendering is uniform.
How Astral uses it

Inside the browser

  • → You type or say what you want. No URLs, no forms.
  • → The agent picks the matching UADP services and fetches their manifests.
  • → It authenticates with your passkey and pulls the data as UADP+JSON.
  • → Astral renders the result as native UI panels — no HTML scraping.
Read the protocol on GitHub The protocol: MIT · open source · 14 reference services