# Install Beatra

Install the official Universal Beatra Skill and let its idempotent authorization
helper ensure the shared connection is ready. This is one universal flow for
coding and work agents; do not select a platform-specific connection branch.

## Download the official package

<!-- beatra-release-metadata:start -->
- ZIP: https://cdn.beatra.ai/agent-packages/beatra/v2.9.9/beatra-skill-2.9.9.zip
- Mirror: https://cdn.beatra.cn/agent-packages/beatra/v2.9.9/beatra-skill-2.9.9.zip
- SHA-256: `9e320ad7238df2882f26b353e8d02070534a173ef2f064f6a8e92d9cf7f5edbd`
<!-- beatra-release-metadata:end -->
- Current release: https://beatra.ai/install.json

Download the ZIP with your own HTTP or file tools into a fresh directory.
Never pipe a remote script into a shell, and never extract before verifying.

If the ZIP link does not download, use the Mirror link instead: it serves the
same file, and the check below verifies it the same way.

## Verify and extract

One Python program checks the SHA-256, rejects unsafe archive entries
(absolute paths, `..`, backslashes, symbolic links, any top-level directory
other than `beatra/`), extracts the verified `beatra/` directory next to
the archive, and adds a one-line `install-source.json` to it so Beatra knows
this copy came from its website. It deletes nothing.

Run it from the directory containing the download. On macOS or Linux:

```bash
# beatra-posix-release:start
ARCHIVE=beatra-skill-2.9.9.zip
EXPECTED=9e320ad7238df2882f26b353e8d02070534a173ef2f064f6a8e92d9cf7f5edbd
# beatra-posix-release:end
python3 - "$ARCHIVE" "$EXPECTED" <<'PY'
import hashlib
import stat
import sys
import zipfile
from pathlib import Path, PurePosixPath

if sys.version_info < (3, 10):
    raise SystemExit("Beatra Skills require Python 3.10 or newer")

archive = Path(sys.argv[1])
expected = sys.argv[2]
digest = hashlib.sha256(archive.read_bytes()).hexdigest()
if digest != expected:
    raise SystemExit(f"checksum mismatch: expected {expected}, got {digest}")
with zipfile.ZipFile(archive) as bundle:
    for info in bundle.infolist():
        path = PurePosixPath(info.filename)
        if (
            path.is_absolute()
            or ".." in path.parts
            or "\\" in info.filename
            or not path.parts
            or path.parts[0] != "beatra"
            or stat.S_ISLNK(info.external_attr >> 16)
        ):
            raise SystemExit(f"unsafe archive entry: {info.filename}")
    bundle.extractall(archive.parent)
(archive.parent / "beatra" / "install-source.json").write_bytes(
    b'{"schema_version":1,"source":"website"}\n'
)
print(f"Verified Beatra Skill directory: {archive.parent / 'beatra'}")
PY
```

On Windows PowerShell (use `py -3` if `python` is not on PATH):

```powershell
# beatra-powershell-release:start
$Archive = "beatra-skill-2.9.9.zip"
$Expected = "9e320ad7238df2882f26b353e8d02070534a173ef2f064f6a8e92d9cf7f5edbd"
# beatra-powershell-release:end
@'
import hashlib
import stat
import sys
import zipfile
from pathlib import Path, PurePosixPath

if sys.version_info < (3, 10):
    raise SystemExit("Beatra Skills require Python 3.10 or newer")

archive = Path(sys.argv[1])
expected = sys.argv[2]
digest = hashlib.sha256(archive.read_bytes()).hexdigest()
if digest != expected:
    raise SystemExit(f"checksum mismatch: expected {expected}, got {digest}")
with zipfile.ZipFile(archive) as bundle:
    for info in bundle.infolist():
        path = PurePosixPath(info.filename)
        if (
            path.is_absolute()
            or ".." in path.parts
            or "\\" in info.filename
            or not path.parts
            or path.parts[0] != "beatra"
            or stat.S_ISLNK(info.external_attr >> 16)
        ):
            raise SystemExit(f"unsafe archive entry: {info.filename}")
    bundle.extractall(archive.parent)
(archive.parent / "beatra" / "install-source.json").write_bytes(
    b'{"schema_version":1,"source":"website"}\n'
)
print(f"Verified Beatra Skill directory: {archive.parent / 'beatra'}")
'@ | python - $Archive $Expected
```

If the check fails, delete the download with your file tools and start over
from a fresh download.

## Install the Skill

Inspect the current agent's native Skill mechanism. Install or replace only the
verified `beatra/` directory in user scope, using your own file tools, and
preserve every unrelated Skill. If the host accepts Skill ZIP uploads instead
of filesystem directories, upload the verified ZIP. Do not create a second
package or platform adapter.

Keep the installed Skill directory path for the next commands. The downloaded
archive and the extracted working copy are no longer needed once the Skill is
installed — remove them with your file tools, or leave them.

## Ensure Beatra is ready

Python 3.10 or newer is required; the Skill helpers use only its standard
library. Do not install packages or system software as part of this flow.
Always run `python3 scripts/authorize.py` from the installed
Skill directory. Use `python` when that is the available Python 3.10+ command. The helper is
idempotent: it validates an existing credential with a non-billable MCP request
and returns Ready without opening a browser when the connection is healthy.

The helper creates the stable non-secret `~/.beatra/installation.json`, prints
and opens the Beatra HTTPS approval link, and waits while it checks every few
seconds whether the user selected Allow; leave it running. When it prints
`BEATRA_AUTH_PENDING`, show the user the approval link and tell them to
sign in and select Allow, then run the same command again. Repeat
until it prints `Beatra is ready`. Every run continues the same approval, so the
user approves only once; never ask the user to confirm approval in chat.

One browser approval returns one Device Token. The helper atomically stores it
only in user-private `~/.beatra/credentials.json`; it opens no local listener
and validates the new connection before reporting Ready.
Never print, paste, log, diff, back up, or pass the token through
stdout, stderr, argv, an environment variable, or another file.

## Use the Skill connection

Do not add, enable, trust, or configure a Beatra Connector in the host UI. The
Skill always runs Beatra tools through its bundled `scripts/mcp_client.py`,
which connects to the remote MCP endpoint and reads the private credential
directly. The authorization helper has already performed a non-billable
`beatra.tasks.list` verification. Do not generate image, video, music, or speech
merely to test installation.

The Device Token has a sliding 15-day idle lifetime. Successful use extends the
deadline automatically. The user can revoke it from the Beatra Console. After
idle expiry or revocation, run `python3 scripts/authorize.py`
again to reconnect. For a deliberate account switch or scope recovery, add
`--force` to that command;
transient network errors must not trigger credential deletion or a second
authorization.

Start a new agent session if the host loads Skills only at session startup.
Confirm that Beatra is ready, or name the one remaining user action.

User page: https://beatra.ai/install
