Corezoid Variable Manager
How to call these tools
Every operation in this skill is an action of the single cz-variables MCP tool —
the individual names below are action strings, not tools of their own:
cz-variables {"action": "list-variables"}
Arguments always go inside args; the shorthand used in the examples below — create-variable(name="payment-api-url", …) — means exactly that call. When unsure about an action's
arguments, call cz-variables {"action": "<action>", "help": true} — it returns the
full schema and runs nothing.
What variables are
Environment variables store constants (URLs, tokens, API keys, IDs, configuration values)
that must not be hardcoded in process logic. The reference syntax {{env_var[@name]}} is
resolved at runtime — changing a variable value takes effect immediately without
redeploying any process.
Variables are stage-scoped: shared across all processes within a stage.
Variable types
By data type
data_type | When to use | Value format |
|---|---|---|
raw | Plain string (URL, token, ID, any scalar) | "https://api.example.com" |
json | Structured config, multi-field config, feature flags | {"key":"value","nested":{...}} |
By visibility
env_var_type | UI display | Accessible from | Scopes |
|---|---|---|---|
visible | Value shown in plain text | All node types | [{"type":"*","fields":"*"}] |
secret | Value masked, shows only fingerprint | API Call nodes only | [{"type":"api_call","fields":"*"}] |
⚠️ Secret variables are designed for tokens, passwords, and API keys. They are never returned in plain text by the API after creation — only an MD5/SHA256 fingerprint is available. Use
visiblefor non-sensitive configuration.
Actions of cz-variables
| Action | Purpose |
|---|---|
create-variable | Create a raw + visible variable in one step |
list-variables | List a stage's variables with obj_id, types, values (secrets masked) |
modify-variable | Change value/title/data_type or rename — dry-run + confirm-gated |
delete-variable | PERMANENTLY delete (no recycle bin) — dry-run + confirm-gated |
Note: creating
secretorjsonvariables is not yet exposed as an action — use the direct API calls documented below for creation; manage them afterwards with the actions above.
Double-confirmation etiquette (modify / delete)
modify-variable and delete-variable are consequential: a deleted variable is gone
FOREVER (env vars have NO recycle bin), a renamed one breaks every
{{env_var[@old-name]}} reference, and a changed value takes effect immediately in
running processes. The actions enforce a two-step gate, and you must drive it honestly:
- Call the action WITHOUT
apply— you get a dry-run: a current → new diff (modify) or a red🔴 PERMANENT DELETIONblock (delete), including a local reference scan. - Show that dry-run output to the user verbatim — do not summarize away the warnings, especially the red block and the list of files that still reference the variable.
- Ask the user explicitly whether to proceed, and wait for their clear agreement in the conversation.
- Only then re-run with
apply=trueand the exactconfirm="<short_name>#<obj_id>"from the dry-run output. Never fabricate the confirm string without steps 1–3, and never treat an earlier, unrelated "yes" as agreement for this action.
Server facts the tools rely on (verified live): modify is PARTIAL — omitted fields
keep their value, so modifying a secret's title does not require (or touch) its value;
env_var_type (visible/secret) can NOT be changed after creation — the server
silently ignores such attempts; delete requires project_id + stage_id and is
irreversible.
Using variables in process JSON
Once a variable exists, reference it with {{env_var[@short-name]}} anywhere a value
is expected.
API Call node — URL field
json{ "type": "api", "url": "{{env_var[@payment-api-url]}}/charge", "method": "POST", "extra_headers": {}, "max_threads": 5, "err_node_id": "<error_node_id>" }
API Call node — header field
json{ "type": "api", "url": "{{env_var[@payment-api-url]}}/charge", "method": "POST", "extra_headers": {}, "max_threads": 5, "extra": { "Authorization": "Bearer {{env_var[@payment-api-token]}}" }, "extra_type": { "Authorization": "string" }, "err_node_id": "<error_node_id>" }
Set Parameters node
json{ "type": "set_param", "extra": { "baseUrl": "{{env_var[@service-url]}}", "token": "{{env_var[@service-token]}}" }, "extra_type": { "baseUrl": "string", "token": "string" }, "err_node_id": "<error_node_id>" }
Call a Process node — passing variable as parameter
json{ "type": "api_rpc", "conv_id": "@target-process", "extra": { "endpoint": "{{env_var[@service-endpoint]}}" }, "extra_type": { "endpoint": "string" }, "err_node_id": "<error_node_id>" }
Condition node (go_if_const)
Variable references work in condition expressions as both the left-hand value and the comparison value:
json{ "type": "go_if_const", "conditions": [ { "fun": "equal", "arg": "{{env_var[@feature-flag]}}", "val": "enabled" } ], "to_node_id": "<next_node_id>" }
Code node — variables must be pre-loaded via set_param
Variables are not directly accessible inside api_code JavaScript. First assign them
to task fields using a set_param node upstream, then read via data.* in code:
javascript// In set_param upstream: "apiUrl": "{{env_var[@my-api-url]}}" var url = data.apiUrl + "/endpoint";
Naming rules
- Only lowercase letters
[a-z], digits[0-9], and hyphens- - Name and description must be at least 3 characters
- Must be unique within the stage
- Good:
stripe-secret-key,payment-api-url,db-host-prod - Bad:
URL,TOKEN,x,My_Var
Local cache files
Two files store variable information locally. Check both before creating a new variable:
| File | Created by | Contains |
|---|---|---|
_ENV_VARS_.json | pull-folder (ZIP export from Corezoid) | All variables in the stage |
.processes/variables.json | the create-variable action | Only variables created in this session |
If neither file exists, run pull-folder or call the list API (see below) to get the
current state.
Workflow: Create a visible raw variable (MCP tool)
Step 1 — Check if variable already exists
Read _ENV_VARS_.json (or .processes/variables.json) and search for the short_name.
If found, reuse it — do not create a duplicate.
Step 2 — Create the variable
Call cz-variables with action: "create-variable" and these args:
name: theshort_name(kebab-case, e.g.stripe-api-key)description: human-readable label (min 3 chars), used astitlein the APIvalue: the actual value
cz-variables {"action": "create-variable", "args": { "name": "payment-api-url", "description": "Payment Service Base URL", "value": "https://api.payments.example.com" }}
The action creates the variable in Corezoid and appends it to .processes/variables.json.
Step 3 — Reference in process JSON
Use {{env_var[@payment-api-url]}} wherever this value is needed.
Workflow: Create a secret variable (direct API)
Use when storing tokens, passwords, API keys — values that must be masked in the UI.
POST {corezoid_url}/api/2/json Authorization: Simulator {access_token} Content-Type: application/json { "ops": [{ "type": "create", "obj": "env_var", "obj_type": 0, "status": "active", "data_type": "raw", "env_var_type": "secret", "title": "Stripe Secret Key", "short_name": "stripe-secret-key", "description": "", "value": "sk_live_...", "company_id": "<WORKSPACE_ID>", "project_id": <PROJECT_ID>, "stage_id": <STAGE_ID>, "scopes": [{"type": "api_call", "fields": "*"}] }] }
Response: { "obj_id": 2192, "proc": "ok", "fingerprints": [...] }
The value is never returned after creation. Store it securely before calling this API.
Workflow: Create a JSON variable (direct API)
Use when a variable holds a structured config object or array.
POST {corezoid_url}/api/2/json Authorization: Simulator {access_token} Content-Type: application/json { "ops": [{ "type": "create", "obj": "env_var", "obj_type": 0, "status": "active", "data_type": "json", "env_var_type": "visible", "title": "Service Config", "short_name": "service-config", "description": "", "value": "{\"host\":\"db.example.com\",\"port\":5432,\"name\":\"prod\"}", "company_id": "<WORKSPACE_ID>", "project_id": <PROJECT_ID>, "stage_id": <STAGE_ID>, "scopes": [{"type": "*", "fields": "*"}] }] }
The
valuefield must be a JSON string (the JSON content encoded as a string). A secret JSON variable uses"env_var_type": "secret"and"scopes": [{"type": "api_call", "fields": "*"}].
Workflow: List variables (direct API)
POST {corezoid_url}/api/2/json Authorization: Simulator {access_token} Content-Type: application/json { "ops": [{ "type": "list", "obj": "env_var", "sort": "date", "order": "asc", "id": "<WORKSPACE_ID>", "company_id": "<WORKSPACE_ID>", "project_id": <PROJECT_ID>, "stage_id": <STAGE_ID> }] }
Response fields per variable:
| Field | Description |
|---|---|
obj_id | Numeric ID (needed for modify/delete) |
short_name | The @name used in {{env_var[@name]}} |
title | Human-readable display label |
data_type | raw or json |
env_var_type | visible or secret |
value | Actual value (empty for secret after creation) |
fingerprints | MD5 + SHA256 hashes — use to detect value changes |
scopes | Access scope rules |
create_time / change_time | Unix timestamps |
uuid | Variable UUID |
Workflow: Modify a variable (direct API)
Modify updates all mutable fields in one call. Always send the full payload — partial updates are not supported.
POST {corezoid_url}/api/2/json Authorization: Simulator {access_token} Content-Type: application/json { "ops": [{ "type": "modify", "obj": "env_var", "obj_id": <VAR_OBJ_ID>, "data_type": "raw", "env_var_type": "visible", "title": "Updated Display Title", "short_name": "new-short-name", "description": "", "value": "new-value", "company_id": "<WORKSPACE_ID>", "project_id": <PROJECT_ID>, "stage_id": <STAGE_ID>, "scopes": [{"type": "*", "fields": "*"}] }] }
⚠️ Changing
short_nameinvalidates all{{env_var[@old-name]}}references across every process in the stage. After renaming, grep all.conv.jsonfiles for the old name and update them, thenpush-processeach affected file.
Workflow: Delete a variable (direct API)
⚠️ Before deleting, verify no process references
{{env_var[@short-name]}}.push-processvalidates env_var references and will fail if the variable is missing.
bash# Check which processes reference this variable grep -r "env_var\[@variable-name\]" . --include="*.conv.json"
POST {corezoid_url}/api/2/json Authorization: Simulator {access_token} Content-Type: application/json { "ops": [{ "type": "delete", "obj": "env_var", "obj_id": <VAR_OBJ_ID>, "company_id": "<WORKSPACE_ID>", "project_id": <PROJECT_ID>, "stage_id": <STAGE_ID> }] }
Resolving environment values
When calling the create-variable / modify-variable / delete-variable / list-variables actions you do not need to look up stage_id or project_id — MCP resolves both from the <id>_<name>.stage.json marker at the workspace root.
For direct /api/2/json calls (the raw workflows below) you need the values explicitly:
| Value | Where to find it |
|---|---|
company_id | workspace_id field in current Folder in ~/.corezoid/config.json |
stage_id | obj_id in <id>_<name>.stage.json at the workspace root |
project_id | parent_id in the same <id>_<name>.stage.json |
| API URL | corezoid_url field in current Folder |
| Access token | access_token field in current Folder |
obj_id of variable | List API response, or _ENV_VARS_.json |
If the marker file is missing, run the corezoid-init skill.
Runtime behaviour
- Variables are resolved before the node executes — the
{{env_var[@name]}}token is replaced with the live value at the moment the task reaches that node - Updating a variable value takes effect immediately — no process redeploy needed
push-processvalidates all{{env_var[@name]}}references: if the variable does not exist in the stage, deployment fails with an error
Common pitfalls
| Mistake | Correct approach |
|---|---|
{{env_var[payment-url]}} — missing @ | {{env_var[@payment-url]}} — @ is required |
{{env_var[@Payment-URL]}} — uppercase | {{env_var[@payment-url]}} — always lowercase |
Storing secrets as visible variables | Use env_var_type: "secret" for tokens and passwords |
Trying to read a secret variable in a Code node | Secret variables are only accessible from api (API Call) nodes |
| Duplicate variable creation | Always read _ENV_VARS_.json or call the list API first |
Renaming short_name without updating process files | Grep all .conv.json, update references, push each changed process |
| Deleting a variable used by active processes | push-process will fail; remove all references first |
| Passing large JSON config as raw string | Use data_type: json for structured values |
Reference Documents
| Path | When to read |
|---|---|
${CLAUDE_PLUGIN_ROOT}/docs/variables-guide.md | Naming rules and usage examples (quick reference) |
${CLAUDE_PLUGIN_ROOT}/docs/nodes/set-parameters-node.md | How set_param feeds variables into task data for Code nodes |
${CLAUDE_PLUGIN_ROOT}/docs/nodes/api-call-node.md | How variables are used in URL, headers, and body fields |
${CLAUDE_PLUGIN_ROOT}/docs/process/process-json-validation.md | How push-process validates {{env_var[@name]}} references |


