SDK Reference
SDK Reference
Every method in the mentu global object is documented below with its TypeScript signature, parameters, return type, and a code example.
All SDK methods are synchronous (they shell out to the mentu CLI via execFileSync). The only async APIs are the servers.* proxy and sleep().
mentu.cir
Query, capture, and search signals in the CIR substrate.
cir.query(options?)
Query CIR signals with optional filters.
cir.query(options?: CIRQueryOptions): CIRSignal[]Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
options.type |
string |
— | Filter by signal type (e.g., 'observation', 'classification') |
options.domain |
string |
— | Filter by domain |
options.limit |
number |
— | Maximum number of signals to return |
options.since |
string |
— | Time filter (e.g., '24h', '7d') |
Returns: CIRSignal[]
interface CIRSignal {
id: string;
type: string;
body: string;
domain?: string;
confidence?: number;
source?: string;
created_at?: string;
tags?: string[];
}Example:
// Get the 10 most recent observation signals
const signals = mentu.cir.query({ type: 'observation', limit: 10 });
for (const s of signals) {
console.log(`[${s.type}] ${s.body} (confidence: ${s.confidence})`);
}cir.capture(body, options?)
Capture a new signal into CIR.
cir.capture(body: string, options?: CIRCaptureOptions): { id: string }Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
body |
string |
required | The signal content |
options.type |
string |
— | Signal type |
options.domain |
string |
— | Signal domain |
options.confidence |
number |
— | Confidence score (0.0–1.0) |
options.source |
string |
— | Source identifier |
options.tags |
string[] |
— | Tags for categorization |
Returns: { id: string } — the ID of the newly created signal.
Example:
const result = mentu.cir.capture('API latency exceeded 500ms threshold', {
type: 'observation',
domain: 'infrastructure',
confidence: 0.95,
source: 'health-script',
tags: ['latency', 'alert'],
});
console.log(`Captured signal: ${result.id}`);cir.search(text, options?)
Search CIR signals by body text content.
cir.search(text: string, options?: CIRQueryOptions): CIRSignal[]Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
text |
string |
required | Search text to match against signal bodies |
options.type |
string |
— | Filter by signal type |
options.domain |
string |
— | Filter by domain |
options.limit |
number |
— | Maximum results |
Returns: CIRSignal[]
Example:
const matches = mentu.cir.search('authentication failure', { limit: 5 });
console.log(`Found ${matches.length} matching signals`);cir.contradictions()
Return all contradiction signals detected in CIR.
cir.contradictions(): CIRSignal[]Returns: CIRSignal[] — signals where two or more entries conflict.
Example:
const contradictions = mentu.cir.contradictions();
if (contradictions.length > 0) {
console.log(`${contradictions.length} contradictions detected:`);
for (const c of contradictions) {
console.log(` - ${c.body}`);
}
}cir.stats()
Return aggregate statistics about the CIR substrate.
cir.stats(): CIRStatsReturns:
interface CIRStats {
signals: number;
relations: number;
embeddings: number;
patterns: number;
contradictions: number;
database_size_bytes: number;
}Example:
const stats = mentu.cir.stats();
console.log(`CIR: ${stats.signals} signals, ${stats.contradictions} contradictions`);
console.log(`Database: ${(stats.database_size_bytes / 1024 / 1024).toFixed(1)} MB`);mentu.vault
Read and write secrets from macOS Keychain. All methods accept an optional scope to namespace secrets.
vault.get(key, options?)
Read a secret from the vault.
vault.get(key: string, options?: { scope?: string }): string | nullParameters:
| Name | Type | Default | Description |
|---|---|---|---|
key |
string |
required | The secret key name |
options.scope |
string |
— | Vault scope (uses mentu-vault/{scope} Keychain service) |
Returns: The secret value as a string, or null if the key does not exist.
Example:
const apiKey = mentu.vault.get('OPENAI_KEY');
if (apiKey) {
console.log(`Key found: ${apiKey.slice(0, 8)}...`);
} else {
console.log('No API key stored');
}vault.set(key, value, options?)
Store a secret in the vault.
vault.set(key: string, value: string, options?: { scope?: string }): voidParameters:
| Name | Type | Default | Description |
|---|---|---|---|
key |
string |
required | The secret key name |
value |
string |
required | The secret value |
options.scope |
string |
— | Vault scope |
Example:
mentu.vault.set('DEPLOY_TOKEN', 'ghp_abc123', { scope: 'ci' });vault.delete(key, options?)
Remove a secret from the vault.
vault.delete(key: string, options?: { scope?: string }): voidParameters:
| Name | Type | Default | Description |
|---|---|---|---|
key |
string |
required | The secret key name |
options.scope |
string |
— | Vault scope |
Example:
mentu.vault.delete('OLD_TOKEN');vault.list(options?)
List all secret key names in the vault.
vault.list(options?: { scope?: string }): string[]Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
options.scope |
string |
— | Vault scope — only list keys in this scope |
Returns: An array of key names (not values).
Example:
const keys = mentu.vault.list();
console.log(`Vault contains ${keys.length} keys: ${keys.join(', ')}`);
// List keys in a specific scope
const ciKeys = mentu.vault.list({ scope: 'ci' });mentu.sequence
Trigger and list recipe sequences.
sequence.run(name, options?)
Execute a named sequence. Blocks until the sequence completes or times out.
sequence.run(name: string, options?: SequenceRunOptions): stringParameters:
| Name | Type | Default | Description |
|---|---|---|---|
name |
string |
required | Sequence name |
options.vars |
Record<string, string> |
— | Variables passed to the sequence |
options.model |
string |
— | LLM model override |
options.backend |
string |
— | Backend override |
options.startFrom |
number |
— | Step number to resume from |
Returns: The sequence output as a string.
Timeout: 10 minutes (600,000ms). If the sequence takes longer, the call throws.
Example:
const output = mentu.sequence.run('cir-audit', {
vars: { THRESHOLD: '3', DOMAIN: 'infrastructure' },
});
console.log('Sequence output:', output);sequence.list()
List all available recipes.
sequence.list(): Array<{ name: string; type: string }>Returns: An array of objects with name and type fields.
Example:
const recipes = mentu.sequence.list();
for (const r of recipes) {
console.log(`${r.name} (${r.type})`);
}mentu.temporal
Manage scheduled temporal definitions. Temporals are cron-based scheduled tasks with circuit breaker support.
temporal.list()
List all temporal definitions.
temporal.list(): TemporalEntry[]Returns:
interface TemporalEntry {
name: string;
schedule: string; // cron expression
target: string; // sequence or script target
enabled: boolean;
last_run?: string; // ISO 8601 timestamp
next_run?: string; // ISO 8601 timestamp
consecutive_failures: number;
circuit_broken: boolean; // true if circuit breaker has tripped
}Example:
const temporals = mentu.temporal.list();
for (const t of temporals) {
const status = t.circuit_broken ? 'BROKEN' : t.enabled ? 'active' : 'disabled';
console.log(`${t.name}: ${t.schedule} [${status}]`);
}temporal.enable(name)
Enable a temporal definition.
temporal.enable(name: string): voidExample:
mentu.temporal.enable('daily-health');temporal.disable(name)
Disable a temporal definition.
temporal.disable(name: string): voidExample:
mentu.temporal.disable('daily-health');temporal.status(name)
Get detailed status for a specific temporal.
temporal.status(name: string): Record<string, unknown>Returns: A status object with temporal details including schedule, last run, failure counts, and circuit breaker state.
Example:
const status = mentu.temporal.status('daily-health');
console.log(JSON.stringify(status, null, 2));temporal.fire(name)
Manually fire a temporal, executing its target immediately regardless of schedule.
temporal.fire(name: string): stringReturns: The execution output as a string.
Timeout: 10 minutes (600,000ms), same as sequence.run.
Example:
const output = mentu.temporal.fire('daily-health');
console.log('Fired temporal:', output);mentu.ledger
Verify the integrity of the CIR ledger.
ledger.verify()
Run a ledger integrity check.
ledger.verify(): { valid: boolean; entries: number }Returns:
| Field | Type | Description |
|---|---|---|
valid |
boolean |
true if the ledger is intact |
entries |
number |
Total number of ledger entries |
Example:
const result = mentu.ledger.verify();
if (result.valid) {
console.log(`Ledger valid: ${result.entries} entries`);
} else {
console.log('Ledger integrity check FAILED');
mentu.notify.send('Ledger Alert', 'Integrity check failed');
}mentu.notify
Send macOS desktop notifications via osascript.
notify.send(title, message)
Display a macOS notification.
notify.send(title: string, message: string): voidParameters:
| Name | Type | Description |
|---|---|---|
title |
string |
Notification title |
message |
string |
Notification body text |
Behavior: Notification failures are non-fatal — if osascript fails (e.g., permissions denied, headless environment), the error is silently caught and execution continues.
Example:
mentu.notify.send('Build Complete', 'All 42 tests passed');mentu.health
System health checks.
health.check()
Run a system health check.
health.check(): Record<string, unknown>Returns: A health status object with component-level details.
Example:
const health = mentu.health.check();
console.log(JSON.stringify(health, null, 2));mentu.vars
Read-only runtime variables passed via --var flags.
vars: Readonly<Record<string, string>>Variables are passed when running a script:
mentu script run my-script --var ENV=production --var THRESHOLD=5Example:
const env = mentu.vars.ENV ?? 'development';
const threshold = parseInt(mentu.vars.THRESHOLD ?? '10', 10);
console.log(`Running in ${env} with threshold ${threshold}`);mentu.vars is a frozen object — you cannot add, modify, or delete properties.
mentu.workspace
The current workspace path.
workspace: { path: string }Example:
console.log(`Workspace: ${mentu.workspace.path}`);The workspace is determined by --workspace flag or defaults to the current working directory when the script was invoked.
servers.* (MCP Proxy)
Scripts can access any MCP server configured in the workspace's .mcp.json file through the servers proxy.
await servers.<server-id>.call(tool: string, args?: Record<string, unknown>): Promise<unknown>The servers object is a JavaScript Proxy. Accessing any property returns an object with a single call() method. Servers are lazily connected — no child process is spawned until the first call().
Parameters:
| Name | Type | Description |
|---|---|---|
tool |
string |
The MCP tool name to invoke |
args |
Record<string, unknown> |
Tool arguments (optional) |
Returns: Promise<unknown> — the tool's response. This is the only async API in the SDK (along with sleep()).
Example:
// Call a tool on the 'crawlio' MCP server
const result = await servers.crawlio.call('search_api', {
query: 'authentication',
limit: 10,
});
console.log(JSON.stringify(result, null, 2));Configuration: MCP servers are defined in {workspace}/.mcp.json using the standard MCP configuration format. The script runner reads this file at startup and makes all configured servers available through the proxy.
sleep()
Pause execution for a specified duration.
sleep(ms: number): Promise<void>Parameters:
| Name | Type | Description |
|---|---|---|
ms |
number |
Milliseconds to sleep (capped at 30,000ms per call) |
Example:
console.log('Waiting 5 seconds...');
await sleep(5000);
console.log('Done');If ms exceeds 30,000 (30 seconds), it is silently capped to 30,000.