Skip to content
Development
Skill

/portal

Build and sideload Android apps for Meta Portal devices (Portal, Portal+, Portal Mini, Portal Go, Portal TV) using metavr. Use when targeting Portal hardware — covers ADB enablement, the no-GMS constraint, manifest/launcher intent-filter requirements, icon density quirks

From plugin
meta-vr
17629 skills1 hook1 MCP
Install
$ npx -y skills add meta-quest/agentic-tools --skill portal --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/portal

Context preview

The summary Claude sees to decide when to auto-load this skill.

Build and sideload Android apps for Meta Portal devices (Portal, Portal+, Portal Mini, Portal Go, Portal TV) using metavr. Use when targeting Portal hardware — covers ADB enablement, the no-GMS constraint, manifest/launcher intent-filter requirements, icon density quirks

SKILL.md

portal.SKILL.md
name: portal
license: Apache-2.0
description: Build and sideload Android apps for Meta Portal devices (Portal, Portal+, Portal Mini, Portal Go, Portal TV) using metavr. Use when targeting Portal hardware — covers ADB enablement, the no-GMS constraint, manifest/launcher intent-filter requirements, icon density quirks (PNG-only, mipmap-xxxhdpi), the Smart Camera SDK, and the gradle + `metavr adb` build/deploy/debug loop. Auto-load when the user mentions "Portal" device, targets `minSdkVersion` 28-29 for a tabletop/TV form factor, or works with the `com.facebook.portal` package.
allowed-tools: Read Bash(metavr:*) Bash(hzdb:*) Bash(npx:*) Bash(android:*) Bash(./gradlew:*)

Portal

This skill is for building Android apps that target Meta's Portal device family. Portal devices are discontinued (sales stopped end of 2022), but ADB is now enabled, so owners can sideload their own apps.

The hardware: Snapdragon-based Android tablets and TV sticks running a modified AOSP **without** Google Mobile Services. Several models, all touch or TV. `minSdkVersion` 28 (Android 9) or 29 (Android 10) depending on device.

This skill pairs with **metavr** (Meta VR CLI) — install it first. Use `metavr adb` in place of raw `adb` everywhere. See `resources/hzdb.md` for the one-line install (via `npx`), the MCP-into-your-editor setup, and the Portal-relevant command surface. The full `metavr-cli` skill ships in the same repo and can also be loaded for deeper reference.

Hard constraints — read before writing any code

If you only remember a few things, remember these. Each is a class of bug Portal apps hit constantly.

1. **No Google Mobile Services.** No Play Services, no Firebase, no FCM, no Play Billing, no Google Sign-In, no Google Maps SDK, no AdMob, no ML Kit. Apps with hard GMS deps will crash on launch. Pick non-GMS alternatives — see `resources/app-requirements.md`. 2. **`minSdkVersion ≤ 28` is required** (Portal hardware tops out at API 29). For **new apps**, `targetSdkVersion 29` is the safest default. For **porting existing apps**, `targetSdkVersion` higher than 29 usually works fine — verified empirically with `targetSdk = 36`. Don't waste time downgrading the target SDK of an existing app unless you observe a concrete runtime issue. 3. **Launcher intent-filter is required.** Touch devices need `MAIN + LAUNCHER`; Portal TV needs `MAIN + LEANBACK_LAUNCHER`. The `DEFAULT` category is **not** required (verified empirically on Portal — apps with only `MAIN + LAUNCHER` appear on the home tile grid). Without one of these, the app installs but never appears on the home screen. 4. **App icon must include a PNG in `mipmap-xxxhdpi/`** as a fallback. Declare `android:icon` (touch) or `android:banner` (TV) on the launcher activity. You can also ship adaptive icons (`mipmap-anydpi-v26/`) and other density PNGs alongside — Portal's launcher correctly falls back to the `mipmap-xxxhdpi` PNG when the adaptive XML can't be rendered. Apps with **only** adaptive icons (no PNG fallback) will not have a visible icon on Portal. 5. **No contacts API. No account/credentials API.** `READ_CONTACTS` is denied. The account provider returns nothing. 5a. **Basic mic capture works; the far-field / beamformed mic array does not.** Standard `RECORD_AUDIO` opens an `AudioRecord` stream and delivers real audio from `handset-mic` (the single-channel mic). The far-field beamformed array used by "Hey Portal" wake-word is gated by a Meta-signed native permission (`com.facebook.alohasdk.permission.RECORD_AUDIO_PRIVILEGED`) and is not available to sideloaded apps. So basic voice features work; sideloaded wake-word detection and high-quality room-distance pickup do not. See `resources/app-requirements.md` § Microphone capture for details. 6. **Touch UI for tabletop, not phone form factor.** Portal sits on a counter or stand. Users interact from 50–100 cm. Hit targets ≥ 64 dp (96 dp for primary actions), body text ≥ 16 sp (18 sp on Portal+), landscape-first. Full Portal design system (typography, spacing, palette, WCAG ratios, TalkBack rules) is in `resources/design-guidelines.md`; for Jetpack Compose apps, `resources/compose-theme.md` is a copy-paste theme starter that bakes these rules into `Color.kt` / `Theme.kt` / `Type.kt`. 7. **Reserve the top ~64 dp** (only if your top content sits within 64 dp of the canvas edge). Portal has a persistent system overlay strip at the top: **back / home buttons (top-left)** and **Wi-Fi / status (top-right)**. It floats *above* app content with no automatic safe-area inset. Apps whose top UI hugs the edge (edge-to-edge toolbars, sticky headers, full-bleed modals) will tuck under it. Apps whose top content naturally sits ≥80 dp below the canvas edge don't need any change. The overlay pills are **white**, so apps with a **light background** in the top region need an additional dark scrim even after inset — see `resources/app-requirements.md` § Top system overlay.

Device matrix

| Device | `minSdkVersion` | Connection | |---|---|---| | Portal (1st and 2nd gen) | 28 / 29 | USB-C (back) | | Portal Mini | 29 | USB-C (back) | | Portal+ (1st and 2nd gen) | 28 / 29 | USB-C (back) | | Portal Go | 29 | USB-C (under rubber cover on back) | | Portal TV | 29 | USB-C |

Set `minSdkVersion 28` if you want to cover everything. If you don't need to support 1st-gen Portal / Portal+, you can target 29.

Quickstart

**Toolchain first — don't hand-hunt for it.** Building needs two host-machine pieces: a **JDK** (Gradle/AGP run on it) and the **Android SDK**. Install the SDK with Google's [`android` CLI](https://developer.android.com/tools) — don't go scavenging the filesystem for an SDK. For the JDK, point `JAVA_HOME` at **Android Studio's bundled JBR** if Android Studio is installed, otherwise install **Temurin 17**. The `android` CLI installs the **SDK only — it does not provide a JDK.** Full walkthrough: `resources/android-sdk-setup.md`.

# 1) Get a JDK 17 (one-time, host machine — Gradle / AGP run
Read more
Ships withmeta-vr

Agentic skills and tools for Meta Quest and Horizon OS development.

Get the whole plugin