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 varHolds
LLM_BASE_URLBase URL to pass to the vendor's SDK
LLM_API_KEYKey for this app's attachment
LLM_MODELThe exact model ID; requests for any other are refused
LLM_PROVIDERanthropic, 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_resource with provider
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.