Skip to content

Keep local values in env files

On your machine, a pack's settings and secrets live in env files at the pack's root. kindgi dev reads .env, then .env.local; a name in both takes its value from .env.local.

.env
ORDERS_APP_URL=http://localhost:3000

kindgi dev says which files it read when it starts:

✓ env files: .env, .env.local — 4 name(s) for the pack

Under kindgi dev, the env files are two things at once.

The pack service's environment. Your tools' code runs in the pack service, and every name in the env files is in its environment:

tools/order-link/index.ts
import { defineTool } from '@kindgi/sdk/define';
import type { ToolId } from '@kindgi/sdk/types';
import { z } from 'zod';
const defined = defineTool({
id: 'my-pack.order-link' as ToolId,
description: 'Returns the link to an order in the back office.',
version: '0.1.0',
input: z.object({ orderId: z.string() }),
output: z.object({ url: z.string() }),
effects: [],
mutating: false,
handler: async ({ orderId }) => {
const base = process.env.ORDERS_APP_URL;
if (base === undefined) throw new Error('ORDERS_APP_URL is not set');
return { url: `${base}/orders/${orderId}` };
},
});
if (defined.kind === 'err') throw new Error(defined.error.message);
export default defined.value;

Call it from my-pack.link, a one-step flow:

Terminal window
kindgi runs start --flow=my-pack.link --input='{"orderId":"ord_1001"}'
"flowId": "my-pack.link",
"flowVersion": "0.1.0",
"status": "completed",
…
"output": {
"url": "http://localhost:3000/orders/ord_1001"
},

Nothing else reaches it: a variable exported in the shell you start kindgi dev from isn't in the pack service's environment, and neither is a KINDGI_* name, from anywhere. Save an env file and the pack service restarts with the new values.

The local secrets store. Tools' declared secrets, HTTP tools' credentials, model providers' keys and MCP endpoints' credentials resolve in an environment; under kindgi dev it's local, and local is these files. kindgi secrets set … --env=local writes to .env.local (Store a secret).

Terminal window
kindgi env list --env=local
Environment: local
Env file: .env
Env file: .env.local
Reveal: NO (redacted; --reveal to show)
4 key(s):
HTTPBIN_TOKEN de**********23 [.env.local]
INVENTORY_TOKEN in**************56 [.env.local]
ORDERS_APP_URL ht*****************00 [.env]
RECEIPT_SIGNING_KEY a6************************************************************83 [.env.local]

Values are redacted; --reveal prints them to a terminal, never to a pipe or a file.

To read more files, list them in the pack's config, lowest precedence first:

// in kindgi.config.ts
dev: { envFiles: ['.env', '.env.development', '.env.local'] },

kindgi dev reads the list when it starts: restart it after a change.

✓ env files: .env, .env.development, .env.local — 6 name(s) for the pack

The files hold secrets. Make sure your .gitignore covers them:

.env
.env.*
!.env.example

The Python template's .gitignore has these lines. A TypeScript pack made with kindgi init 0.1.0 has no .gitignore (its lines landed in .npmignore): add one.