You pick the shape by including a
foreground, background, or both sections in your truffile.yaml.
The supported development loop is intentionally CLI-first: scaffold locally,
validate locally, dry-run the deploy plan, then deploy to a connected device.
The bundled examples live under truffile/app-store/ in the truffile repo. Treat them as reference implementations:
The SDK import surface
App code imports everything it needs fromtruffile.app_runtime. This is the module that ships with the truffile package when you pip install truffile.
truffile/app_runtime/ in the repo and ships with the installed package. Once you pip install truffile, the same runtime is importable from app code running on your device.
There are two other entry points that import the same names:
from truffile.sdk import ...— a curated re-export module with nice grouping. Use this if you prefer one obvious “public API” import.from truffile import ForegroundApp, BackgroundWorkerApp, ToolSpec, ok, err, OAuth, AppHarness— the most common names are also re-exported at the top level.
truffile.app_runtime because it is the clearest app-authoring import surface.
Scaffold a new app
The fastest way to start:truffile create <name>— set the name, prompt for base pathtruffile create <name> --path <dir>— set name and base pathtruffile create— fully interactive
my_app_foreground.py and my_app_background.py are stubs using the real SDK classes. Delete whichever you don’t need — the app type is inferred from which foreground / background sections you keep in truffile.yaml.
Let an agent build the app for you
If you’re working in the truffile repo with a coding agent — Claude Code, Codex, or any other agent that can read skill files — there’s a built-in skill it can follow to build a Truffle app end-to-end:truffle-app-creator (at truffile/skills/truffle-app-creator/SKILL.md).
It’s the fastest path for things like:
- “Create a Truffle app that talks to <service>”
- “Port this MCP server to Truffle”
- “Build an integration with <API> and run it in the background”
truffile create to scaffold, implements the client/auth/tools, writes tests, and runs truffile validate + truffile deploy for you. Just describe the service you want to connect and it takes over from there.
truffile.yaml structure
Every app needs a truffile.yaml. Minimum viable config:
Supported step types
Steps run during installation on the device, in order. The manifest supports:
See the Install steps reference for every option on each type — field shapes, validators, exit code semantics, and multi-field examples.
vnc / browser setup steps are not supported through truffile. truffile validate rejects them with an explanation and tells users to install those apps through Symphony Settings.Auth patterns
Pick the smallest auth surface that matches the upstream service:
For
text auth, add a validator that calls python ./foreground.py --verify or python ./background.py --verify. For OAuth, write a tiny auth helper around OAuth or RemoteMcpOAuth, store the token file path in an env var, and verify it in a follow-up bash step.
If an update reaches an auth step that cannot be refreshed non-interactively, fail clearly and tell the user to reauthenticate from Settings.
Build and deploy flow
validatechecks thetruffile.yamlstructure, confirms referenced files exist, and parses all Python files for syntax errors.deploy --dry-runbuilds the deploy plan without changing anything on the device, so you can see what files will be uploaded, what bash steps will run, and how the process config will look.deployopens a build session on the device, uploads files, runs your steps in order, and registers the app.
--interactive to deploy to open a shell inside the app’s container when the build steps finish — useful for installing extra packages or debugging before finalizing.
After deployment, use an agent-safe one-shot request as a routing smoke test:
tool_calls in the JSON result. This tests normal agent discovery and
tool routing only. Convo has no per-thread app allowlist, so the CLI cannot
attach the newly deployed app or guarantee that this request uses it. Use
truffile infer --mcp <url> before deployment when you need deterministic
local selection of the app’s MCP server.
Runtime stability pattern
Whatever network clients your app opens — HTTP sessions, database connections, MCP subprocesses — close them on shutdown:Next steps
Build a Foreground App
Use
ForegroundApp to expose MCP tools the agent can call on demand.Build a Background App
Use
BackgroundWorkerApp to run on a schedule and submit context to the proactive agent.