Skip to main content
An app has three layers of configuration. Each is declared in code and typed end to end.

Environment variables and secrets

Declare every variable the app reads on createReintersectApp. Plain values use a schema; secrets use secret():
Environment values always arrive as strings. A schema whose input isn’t a string, such as a plain number, is a type error: env.MAX_DEPLOYMENTS arrives as a string: use a string schema such as z.coerce.number() or type("string.numeric.parse"). A variable is required unless its schema accepts undefined; secrets are always required. A deploy fails with env-missing when a required variable has no value in the target environment. Each piece declares the keys it reads, and only those keys are available in its handlers:
Adding that piece to an app checks the declaration against the app’s env. A missing key or a different type is a compile error at the add… call.

Setting values

Set values per environment with the CLI, in Settings → Developer → Apps → your app → Environment, or from CI with a deploy token:
env set stores a secret in production unless you pass --plain or --preview, and reads the value from a prompt or from stdin. Values are write-only: nobody can read a stored value back, in the dashboard or anywhere else. Each environment holds up to 128 variables of at most 5 KB each. Hosted apps redeploy when production variables change. The variables REINTERSECT_APP_CLIENT_ID, REINTERSECT_APP_CLIENT_SECRET, REINTERSECT_APP_SIGNING_SECRET and REINTERSECT_BASE_URL are read by the SDK itself; see Self-hosted apps and Reintersect-hosted apps.

Secret values

A secret arrives as a Secret, not a string. Call .reveal() at the point where you need the value, such as an authorization header. Until then, it prints as <redacted> in console.log, string templates and JSON.stringify, and the SDK’s log helper doesn’t accept it as a field:
reveal() returns a plain string, and the types can’t follow it after that. Reveal as late as possible. On the Effect entry, secret() produces a Redacted<string> instead. See the Effect guide.

Install config

Install config is for settings that differ per workspace, such as which project a workspace maps to. Declare a schema on the app; Reintersect generates a form from its JSON Schema (titles, descriptions, enums and formats) and shows it on the consent screen:
Pieces declare the config they read with config, and handlers receive it typed:
Reading config in a piece that doesn’t declare it is a type error. Admins can change install config later from the app’s page in Settings → Workspace → Integrations. Reintersect sends the current config with every delivery, so your app stores nothing. Top-level config fields marked writeOnly or format: "password" in the JSON Schema are stored encrypted, never shown again, and only decrypted to send them to your app. Prefer member connections for credentials that belong to a person.

Member connections

Some tools act as a specific person on another service. Reintersect stores those connections per member. The first time the agent needs one, it shows the member a Connect card inline in the chat, and the member signs in with that service. Admins only make the service available; they never hand their own account to everyone else. See MCP authentication.