Overview
Scripting SDK Overview
// Query recent observations, check for contradictions, trigger a sequence if needed
const signals = mentu.cir.query({ type: 'observation', since: '24h', limit: 50 });
const contradictions = mentu.cir.contradictions();
const apiKey = mentu.vault.get('EXTERNAL_API_KEY');
if (contradictions.length > 5 && apiKey) {
console.log(`Found ${contradictions.length} contradictions — triggering audit`);
mentu.sequence.run('cir-audit', { vars: { THRESHOLD: '5' } });
mentu.notify.send('CIR Alert', `${contradictions.length} contradictions detected`);
} else {
console.log(`System healthy: ${signals.length} signals, ${contradictions.length} contradictions`);
}
return { signals: signals.length, contradictions: contradictions.length };What is the Scripting SDK?
The Scripting SDK lets you write TypeScript scripts that compose all mentu primitives — CIR, vault, sequences, temporals, notifications, and health checks — in imperative code. Scripts run inside a locked-down V8 sandbox with a mentu global object providing access to 7 namespaces plus runtime variables and workspace info.
Get started in 3 steps
- Install mentu + Node.js 20+ — see Installation
- Set your API key —
mentu auth login you@example.com— see API Keys - Create and run a script:
cat > ~/.mentu/scripts/hello.ts << 'EOF' console.log('Hello from mentu!'); return mentu.cir.stats(); EOF mentu script run hello
Capabilities
| Namespace | What it does |
|---|---|
mentu.cir |
Query, capture, and search signals in the CIR substrate |
mentu.vault |
Read and write secrets from macOS Keychain |
mentu.sequence |
Trigger and list recipe sequences |
mentu.temporal |
Manage scheduled temporal definitions |
mentu.ledger |
Verify ledger integrity |
mentu.notify |
Send macOS desktop notifications |
mentu.health |
Run system health checks |
mentu.vars |
Read-only runtime variables from --var flags |
mentu.workspace |
Workspace path ({ path: string }) |
Scripts can also access MCP servers via the servers proxy:
const result = await servers.crawlio.call('search_api', { query: 'test' });Script vs recipe vs sequence
| Script | Recipe | Sequence | |
|---|---|---|---|
| Language | TypeScript | JSON template | JSON manifest |
| Logic | Imperative — conditionals, loops, composition | Declarative — single prompt | Declarative — ordered step list |
| Best for | Complex workflows, conditional branching, API composition | Single-shot LLM tasks | Multi-step LLM pipelines |
| Runtime | V8 sandbox (Node.js) | mentu CLI | mentu CLI |
| Access | All SDK namespaces + MCP servers | LLM context only | LLM context + step variables |
Use scripts when you need imperative logic: if/else branching, loops, composing multiple CIR queries, reading vault secrets to decide what to do next, or calling external services through MCP.
Use recipes for single LLM prompts with template variables.
Use sequences to chain multiple recipes into a pipeline where each step's output feeds the next.
Security model
Scripts execute in a V8 sandbox with deny-all defaults:
- No filesystem access —
require,fs,process,__dirnameare not available - No network access —
fetch,http,netare not available - No code generation —
eval()andnew Function()throwEvalError - Frozen prototypes —
Object.prototypeandArray.prototypeare sealed,Function.prototypeis frozen - Output limits — 50KB code size, 10MB output cap
- Timeout enforcement — configurable per-script (default 300s), 30s cap per
sleep()call
The only way scripts reach external systems is through the mentu SDK (which shells out to the CLI binary) or the servers proxy (which routes through the MCP child manager). Both are injected as frozen globals — scripts cannot modify them.
See Script Runner for full internals.