WendyOS Docs
AdvancedApps

wendy.json

wendy.json is the configuration file for a Wendy app. It lives at the root of your project and describes the app's identity, target platform, required capabilities, and runtime beh

wendy.json

wendy.json is the configuration file for a Wendy app. It lives at the root of your project and describes the app's identity, target platform, required capabilities, and runtime behaviour.

Example

{
  "$schema": "https://wendy.sh/schemas/wendy.json",
  "appId": "my-app",
  "version": "1.0.0",
  "language": "swift",
  "entitlements": [
    { "type": "network" },
    { "type": "gpu" }
  ]
}

Fields

appId (required)

Unique identifier for the app.

{ "appId": "my-app" }

version

Version string for the app, e.g. "1.0.0".

platform

Target platform. One of:

ValueDescription
wendyosLinux edge device running WendyOS
wendy-liteESP32 WASM target
darwinNative macOS app running through Wendy for Mac
linux/arm64, linux/amd64, etc.Explicit Linux architecture target

Omit to target the default platform.

Use "darwin" for native macOS targets managed by Wendy for Mac. The CLI builds the app on a Mac development machine, syncs the build output to the Mac agent, and launches it as a native macOS process. Darwin apps run natively and non-containerized; they do not use the WendyOS Linux container runtime.

Wendy for Mac: If the selected target is Wendy for Mac, wendy run rejects any platform value that does not resolve to darwin (for example, linux/arm64 or wendyos). Set platform: "darwin" and use a native SwiftPM or Xcode project.

Minimal SwiftPM/macOS configuration:

{
  "$schema": "https://wendy.sh/schemas/wendy.json",
  "appId": "com.example.hello-mac",
  "version": "1.0.0",
  "language": "swift",
  "platform": "darwin"
}

language

Project language, e.g. "swift" or "python". Used by the CLI to select the appropriate build toolchain.

debug

Set to true to enable debug mode (default false). Injects debug tooling into the container via the WENDY_DEBUG build arg.

entitlements

Array of capabilities the app requires. See Entitlements below.

readiness

Configures how the CLI determines when the app is ready after starting.

{
  "readiness": {
    "tcpSocket": { "port": 8080 },
    "timeoutSeconds": 30
  }
}
FieldTypeDefaultDescription
tcpSocket.portinteger (1–65535)—TCP port to probe
timeoutSecondsinteger30How long to wait before giving up

hooks

Lifecycle commands to run at specific points during the app lifecycle.

{
  "hooks": {
    "postStart": {
      "cli": "open http://localhost:8080",
      "agent": "/app/post-start.sh"
    }
  }
}
FieldDescription
hooks.postStart.cliCommand run on the developer's machine after the app starts
hooks.postStart.agentCommand run on the device after the app starts

python

Python-specific settings.

FieldDescription
python.sourceRootPath to the Python source root directory
python.container.sourceRootPath to the Python source root inside the container image

$schema

Optional URI pointing to the JSON Schema for editor autocompletion and validation. Set to "https://wendy.sh/schemas/wendy.json".


Entitlements

Entitlements grant the app access to hardware and system capabilities. Any capability not listed is unavailable to the app. They are code signed, preventing privilege escalation.

Use wendy project entitlements add / remove to manage them, or edit wendy.json directly.

network

IP networking access.

{ "type": "network" }
{ "type": "network", "mode": "host" }
modeDescription
(omitted)Default isolated network
"host"Shares the host network stack
"none"Networking fully disabled

gpu

Hardware-dependent GPU or board-telemetry access.

{ "type": "gpu" }
Host hardwareGrant
NVIDIA JetsonNVIDIA CDI specs, CUDA env vars, /dev/nvidia*
Raspberry Pi/dev/vcio (VideoCore mailbox) for board telemetry — power, voltage/current, temperature, throttling, Pi 5 PMIC ADC
OtherNo hardware-specific grant

On Raspberry Pi, /dev/vcio is bind-mounted only when present on the host; access is rw (no mknod).

camera

Camera / V4L2 device access.

{ "type": "camera" }
{ "type": "camera", "allowlist": ["/dev/video0"] }
FieldDescription
allowlistRestrict access to specific device paths. Omit to allow all cameras.

audio

Microphone and speaker access.

{ "type": "audio" }

bluetooth

Bluetooth access.

{ "type": "bluetooth" }

persist

Persistent storage that survives container restarts.

{
  "type": "persist",
  "name": "my-app",
  "path": "/data"
}
FieldDescription
nameShared namespace (app ID). Apps with the same name can share storage.
pathMount path inside the container, e.g. "/data".

usb

USB device access.

{ "type": "usb" }

i2c

I2C bus access.

{ "type": "i2c", "device": "/dev/i2c-1" }
FieldDescription
deviceI2C device path (required).

serial

Serial tty device access — e.g. a USB-serial adapter or servo bus (pyserial/termios).

{ "type": "serial", "device": "ttyACM0" }
FieldDescription
deviceBare USB tty node name, matching ttyACM0 / ttyUSB0 (required). USB-only; on-board UARTs (ttyAMA, ttyS) are not supported. Not a path.

gpio

GPIO pin access.

{ "type": "gpio" }
{ "type": "gpio", "pins": [17, 27] }
FieldDescription
pinsPin numbers to expose. Omit to grant access to all GPIO chips.

spi

SPI device access.

{ "type": "spi" }

input

HID input device access (barcode scanners, keyboards, etc.).

{ "type": "input" }

mcp

Registers the container as a Model Context Protocol (MCP) server. When this entitlement is present the wendy agent:

  1. Stores the port in the container's sh.wendy/mcp.port label.
  2. Exposes the container's tools through wendy mcp serve so that AI assistants (Claude Desktop, etc.) can call them automatically.
  3. Makes the port available via the StreamMCP gRPC API for secure proxying.
{ "type": "mcp", "port": 3000 }
FieldTypeDescription
portintegerTCP port on which the container's MCP server listens (required).

The container must serve the MCP Streamable HTTP transport on 0.0.0.0:<port>. See the MCPExample for a complete Python reference implementation.

Note: The mcp entitlement is typically combined with { "type": "network", "mode": "host" } so that the agent can reach the container's MCP port over loopback.


Compose-based projects

If your project uses a docker-compose.yml instead of a single container, you don't need a wendy.json. wendy run detects the compose file automatically and each service gets a generated app config derived from its ports, network_mode, and volumes declarations.

See Multi-Service Apps with Docker Compose for details.


Deprecated: { "type": "video" } — use camera instead.

On this page