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
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" 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 ••••••.
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" }
}
}
} 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 } 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} 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.
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 soonVisual 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 soonThe 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.
Docs
From the first install to a test running in CI: how to connect your agent, what it can call, and how to keep what it tests.
- Getting started Install Astral, turn on Developer mode and make your first call from an agent.
- Connect your agent One command for Claude Code, Codex, VS Code, Cursor, Windsurf and more, or a manual config.
- Tool reference Every MCP tool, by permission group, with each parameter's type. Generated from the server itself.
- Saved tests Keep a tested flow in your repository, with environments and credentials in the system keychain.
- Run in CI Replay saved tests with astral-test, with exit codes, JUnit and NDJSON output.
- Read the docs
The same tab, not a hidden one
How Astral compares with classic headless 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.
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.
| 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.
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.
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.
"Show me my bank balance and latest tweets"
Matched 2 services: orbit, nova
/.well-known/uadp.json → manifests
Token valid for 3600s
2 panels: BankAccountCard + SocialFeed
"Show me my bank balance and latest tweets"
Matched 2 services: orbit, nova
/.well-known/uadp.json → manifests
Token valid for 3600s
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.
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:
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.
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@astralComing 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.
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.
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_typefield, so rendering is uniform.
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.