# set_secret

Source: https://modulify.ai/docs/mcp/secrets/set-secret

Creates or replaces one environment variable on a site.

- Title: Set an environment variable
- Scope: `config:write`
- Access: Makes changes

By default the value is stored encrypted and is server-only, and reading it back needs `get_secret` and the separate `credentials:reveal` scope. Set `isPublic` to store it unencrypted instead, so it can be read back in the product without a reveal. Leave it off for anything secret.

That flag controls storage only. Every variable reaches the build the same way, and browser visibility comes from the `NEXT_PUBLIC_` prefix on the name, not from the flag. Replacing an existing variable applies the flag again, so leaving `isPublic` out stores the new value encrypted even if the old one was public.

The new value reaches the running preview straight away, but the published site keeps the old one until the site is published again. A site holds up to 200 of your own variables on top of the managed ones, and a new one past that is refused.

`DATABASE_URL`, `DATABASE_TOKEN`, `CDN_URL`, `CDN_PRIVATE_KEY`, `EMAIL_URL` and `EMAIL_PRIVATE_KEY` are refused as locked, and a further list Modulify reserves for itself, among them `GITHUB_TOKEN`, `PROJECT_ID` and `WS_TOKEN`, is refused as reserved. See [Secrets](https://modulify.ai/docs/data/secrets#reserved-names).

## Inputs

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | Yes | The site id. |
| `key` | string | Yes | The variable name, for example `STRIPE_SECRET_KEY`. Use letters, digits and underscores only, starting with a letter or an underscore. A name the platform reserves is refused. |
| `value` | string | Yes | The value to store. Anything past 10,000 characters is cut off. |
| `isPublic` | boolean | No | True to store the value unencrypted, so it can be read back without a reveal. Defaults to false. This is about storage, not browser exposure, so never set it for a credential. |