Skip to content

Scripts

A script in Reminix is code your team can run safely, from the app, the API or an AI agent. It has a name, an owner, and the JSON Schema of its inputs, which becomes the form people fill in and the input agents send. Its code lives in versions: every change is a new version, and runs use the one that’s published.

The folder: reminix.json and an entry file

Section titled “The folder: reminix.json and an entry file”
{
"slug": "refund-customer",
"name": "Refund a customer",
"description": "Refunds an order and notifies the customer.",
"entry": "index.ts",
"inputSchema": {
"type": "object",
"required": ["orderId"],
"properties": { "orderId": { "type": "string" } }
}
}
// index.ts: the entry. It may import other files and npm packages.
import { refund } from "./payments.ts";
export default async function run(inputs: { orderId: string }, ctx) {
ctx.log(`refunding ${inputs.orderId}`);
return { refunded: inputs.orderId };
}

The entry default-exports run(inputs, ctx) and returns JSON. JavaScript and TypeScript both work. When you publish, Reminix bundles the entry and everything it imports into one module of at most 5 MB: your other files, and npm packages from the folder’s node_modules (run npm install first). Node built-ins such as node:crypto and node:buffer can be imported.

Add "tags": ["finance", "refunds"] to reminix.json (up to 10, lowercase) and a README.md beside it. The script’s page shows the README, and both help your team find it.

By default a script has no network. To call an API, list its hosts, and the secrets to attach to requests to them:

{
"hosts": ["api.stripe.com"],
"secrets": {
"STRIPE_KEY": {
"host": "api.stripe.com",
"header": "Authorization",
"value": "Bearer {secret}"
}
}
}
export default async function run(inputs, ctx) {
// No key in the code: Reminix adds the Authorization header on the way out.
const res = await fetch("https://api.stripe.com/v1/refunds", {
method: "POST",
body: new URLSearchParams({ payment_intent: inputs.paymentId }),
});
return await res.json();
}
  • Requests go out only to hosts, over HTTPS. Anything else fails with “Host not allowed”, and every request is in the run’s log.
  • Reminix attaches each secret only to its host, and only if the secret itself allows that host (Secrets). The code never holds the value. One caution: an API that echoes your credentials back in its response would reveal them to the code, so don’t send secrets to one.
  • value defaults to {secret}. Use it to add a scheme, as in "Bearer {secret}".
  • To read a secret as a plain value (ctx.env.NAME), list it in "env": ["NAME"]. That’s allowed only for a secret whose owner turned on “Let scripts read the value itself”.

The script’s page shows each version’s hosts and secrets, so whoever publishes can see what it can reach.

Terminal window
reminix scripts publish ./refund-customer # uploads a draft version
reminix scripts publish ./refund-customer --publish # and publishes it

The first publish creates the script. A draft changes nothing until a version is published, by the script’s owner or a workspace owner or admin. An agent’s publish becomes a request that a person approves. Publishing an older version again rolls back. See Governance for who can use a script, runs that need approval, and a second person for publishing.

Through the API, with a key or token that has scripts:write: POST /v1/scripts creates one, POST /v1/scripts/{slug}/versions uploads a version ({ entry, inputSchema, code }), and POST /v1/scripts/{slug}/versions/{number}/publish publishes it.

Once a version is published, anyone in the workspace who may use the script can run it:

  • In the app: open it under Scripts. Its input schema is a form, and Run shows the output and the log.
  • From the command line: reminix scripts run refund-customer --input '{"orderId":"o_123"}' prints the output. Add --log to print the log too.
  • From an agent: through the MCP server, every published script is a tool with the script’s own name (refund_customer) that takes its inputs.
  • From the API: POST /v1/scripts/{slug}/runs. See Runs.