Administer
Resources
On this page
What a resource is
A resource is a backing service that Valet provisions for your organization and attaches to an app. Only apps hold resources. Artifacts and agents can't; for data they need, use a connector.
Attaching writes the resource's connection details onto the app as
secret env vars, and the app reads them like any other env var. Valet
stores the connection details encrypted. list_env_vars, or
valet env --app <name>, lists them with their values masked.
A resource belongs to the organization, not to an app. Its name is unique in the organization. Several apps can attach the same resource, and it outlives the apps that use it. Every organization member can create, attach, detach and destroy resources.
list_catalog_resources, or valet resources catalog, lists the kinds
your installation offers. For each kind it shows the
plans, the env vars an attachment sets, and a guide that tells a coding
agent how to use it. Valet's built-in skills tell coding agents to
follow that guide.
Kinds of resources
PostgreSQL
Provider valet-postgresql, plan dev. It gives an app an empty
PostgreSQL database, for records people enter or data that must outlast
a restart. The app creates its own tables when it starts.
DATABASE_URL
- Holds
- Connection URL, with the TLS settings the server needs
DATABASE_POOLED_URL
- Holds
- Connection URL through a connection pooler
DATABASE_HOST, DATABASE_PORT, DATABASE_NAME
- Holds
- Parts of the URL, for a library that can't take one
DATABASE_USER, DATABASE_PASSWORD
- Holds
- The database's login
Every app attached to one database gets the same login.
Inference
Provider valet-inference. It gives an app access to one AI model, for
server code that calls a model. Each plan is one exact model ID, such as
claude-sonnet-5; list_catalog_resources lists them.
| Env var | Holds |
|---|---|
LLM_BASE_URL | Base URL to pass to the vendor's SDK |
LLM_API_KEY | Key for this app's attachment |
LLM_MODEL | The exact model ID; requests for any other are refused |
LLM_PROVIDER | anthropic, openai or zai, which names the SDK to use |
The app calls Valet's inference endpoint, not the vendor. Valet records every request and response, and passes each request to the model's vendor. Two endpoints work: Anthropic Messages and OpenAI Chat Completions. Valet refuses others, such as embeddings and the OpenAI Responses API.
Each attachment gets its own key, so two apps that share one inference resource hold different keys. The key has no expiry. Detaching the resource stops the key from working.
Lifecycle
Create
A resource is created for the app that first needs it:
attach_resource
{ "name": "shop", "resource": "orders-db", "provider": "valet-postgresql", "plan": "dev" }Valet records the resource and starts provisioning it at once, in the
background, usually finishing within a minute. The first
attach_resource call returns while it provisions, and your agent
repeats the call until the resource is attached. With --app,
valet resources create waits for provisioning and then attaches.
list_resources, or valet resources info <name>, shows whether it's ready.
Name a resource for what it holds, such as orders-db, not for the
app.
Attach
Another app attaches an existing resource by name:
attach_resource
{ "name": "reports", "resource": "orders-db" }Attaching writes the resource's env vars onto the app and restarts it.
Only a provisioned resource attaches. Valet records the attachment
before it changes anything, so one interrupted partway, by a failed
restart or a deploy, finishes on its own. get_service shows its
status.
Attach refuses when any env var it would set already exists on the app,
including one set for the whole organization. A conflict that appears
later, such as an organization value that now shadows one of the
resource's, leaves the attachment waiting until you change the name or
detach. To give an app two resources that set the same names, attach the
second with a prefix, "env_prefix": "EVENTS" or --prefix EVENTS,
which sets EVENTS_DATABASE_URL and the rest.
The resource's env vars are ordinary secrets on the app, and Valet doesn't guard them: if someone unsets or overwrites one, the app sees that change. Valet never overwrites a value someone else set.
Detach
detach_resource
{ "name": "reports", "resource": "orders-db" }Detaching removes the env vars the attachment wrote and restarts the app. A variable someone changed after the attach stays, and Valet names it. The resource and its data stay. Other apps that hold the resource keep it.
Destroy
destroy_resource
{ "resource": "orders-db" }Destroying deletes the resource and its data, and can't be undone. It
refuses while any app holds the resource; detach it from each app
first, or pass --force to the CLI to detach every app at once. The
provider removes the database in the background.
Destroying an app detaches its resources and keeps them. Destroy them separately when nothing needs their data.
Limits
An organization can hold 100 resources, and an app can attach 10, by default. Unattached resources count toward the organization limit. Valet can change both limits for an organization.
Valet has no command to back up or restore a resource.
Commands and MCP tools
List kinds and plans
- MCP tool
list_catalog_resources- CLI
valet resources catalog
List the organization's resources
- MCP tool
list_resources- CLI
valet resources
Show one resource
- MCP tool
list_resources- CLI
valet resources info
Create
- MCP tool
attach_resourcewithprovider- CLI
valet resources create
Attach
- MCP tool
attach_resource- CLI
valet resources attach
Detach
- MCP tool
detach_resource- CLI
valet resources detach
Destroy
- MCP tool
destroy_resource- CLI
valet resources destroy
The dashboard shows an app's resources and their state on the app's page. Create, attach, detach and destroy them with MCP tools or the CLI. For an example of asking a coding agent, see Data access.