Skip to navigation

TypeScript SDK Reference

Package: @mima-ai/governance · Version: 0.1.x · Node.js: 18+


Building a TypeScript AI agent? You don’t need this SDK. Configure the MCP server in 4 lines and your agent has full governance evidence — no code changes, any language.

Use this SDK when your TypeScript app code calls AI APIs directly — LangChain chains, batch pipelines, CI scripts, or any workflow where you control the call site.


npm install @mima-ai/governance

Requires Node.js 18+ for native fetch and crypto. No runtime dependencies.


Client setup

import { MimaGovernance } from '@mima-ai/governance';
const mima = new MimaGovernance({
apiKey: process.env.MIMA_API_KEY!, // required
systemName: 'my-ai-pipeline', // required
workspaceId: undefined, // resolved from API key automatically
baseUrl: 'https://api.mima.works', // override for self-hosted
agentName: undefined, // defaults to systemName
signingKey: undefined, // 32-byte hex key for GRC signing
authorisedBy: {
identity: 'alice@example.com',
role: 'ml-engineer',
},
onError: 'warn', // 'warn' | 'raise' | 'silent'
batchFlushInterval: 30_000, // ms
batchMaxSize: 100,
});

Environment variables

VariablePurpose
MIMA_API_KEYAlternative to passing apiKey
MIMA_WORKSPACE_IDAlternative to passing workspaceId

Attestation

mima.wrap() — function wrapper

TypeScript’s equivalent of Python’s @mima.attest() decorator. Takes a function and returns a wrapped version that attests every call.

const classify = mima.wrap('classify_document', async (doc: string) => {
const resp = await anthropic.messages.create({
model: 'claude-opus-4-6',
messages: [{ role: 'user', content: `Classify: ${doc}` }],
});
return resp.content[0].type === 'text' ? resp.content[0].text : '';
});
const label = await classify(document); // attests automatically

Parameters

ParameterTypeDefaultDescription
toolNamestringrequiredName of the tool / action
fnFunctionrequiredFunction to wrap
options.modelIdstring—LLM model identifier
options.authorisedByAuthorisedByclient defaultOverride for this call
options.mode'sync' | 'batch''sync'Push immediately or buffer

The wrapped function always returns Promise<TReturn>. If the original function was sync, the return type becomes Promise<OriginalReturnType>.


mima.push() — explicit attestation

Use when you have pre-computed hashes (e.g. from a pipeline step with its own hashing).

import { createHash } from 'node:crypto';
const inputHash = createHash('sha256').update(JSON.stringify(input)).digest('hex');
const outputHash = createHash('sha256').update(JSON.stringify(output)).digest('hex');
await mima.push('generate_report', inputHash, outputHash, {
modelId: 'claude-opus-4-6',
executedAt: new Date().toISOString(),
});

mima.trace() — manual hash capture

Pass a callback. Call ctx.setInput() / ctx.setOutput() to capture hashes at the right moment.

const result = await mima.trace('run_pipeline', async (ctx) => {
ctx.setInput(inputDocs);
const output = await pipeline.run(inputDocs);
ctx.setOutput(output);
ctx.setModelId('claude-opus-4-6');
return output;
});

mima.batch() — buffered bulk push

await mima.batch(async (b) => {
for (const item of workQueue) {
const result = await processItem(item);
b.add('process_item', { input: item, output: result });
}
});
// All records flushed in a single batch request on exit.

GRC evidence methods

All GRC methods are async and return Promise<GrcResult>:

interface GrcResult {
recordId: string; // '' on failure
recordType: RecordType;
mappedControls: string[]; // e.g. ['EUAIA_ART9', 'ISO42001_6_1']
detail: string; // 'ok' on success
}

mima.worksRiskAssessment()

await mima.worksRiskAssessment(
'loan-scorer',
'high',
'Automated credit scoring for consumer loans',
{
intendedPurpose: 'Score loan applications for human review',
impactDomains: ['credit', 'consumer_finance'],
art5SelfAssessment: true, // certifies no Art.5 prohibited practices
assessor: 'alice@example.com',
annexIiiCategory: 'essential_services', // required for high-risk
environment: 'production',
systemVersion: 'v2.1.0',
technicalDocUrl: 'https://docs.internal/loan-scorer/annex-iv',
},
);

art5SelfAssessment: true certifies no Art. 5 prohibited practices. Never set without explicit human confirmation.


mima.modelEvaluation()

await mima.modelEvaluation(
'loan-scorer-v2.1',
'holdout-q2-2026',
0.94,
{
evaluatedBy: 'alice@example.com',
evaluationType: 'quarterly',
biasMetrics: { demographic_parity: 0.02, equal_opportunity: 0.01 },
robustnessScore: 0.91,
passedThreshold: true,
},
);

mima.humanOversight()

await mima.humanOversight(
'loan-app-48291',
'approve',
'reject',
{
reviewer: 'bob@example.com',
rationale: 'Flagged for fraud indicators not in model training data',
modelId: 'loan-scorer-v2.1',
},
);
// override: true is inferred (approve !== reject)

mima.trainingDataGovernance()

await mima.trainingDataGovernance(
'loan-scorer-v2.1',
'training-set-2026-q1',
2_400_000,
{
biasChecksPerformed: true,
approvedBy: 'data-governance@example.com',
dataSources: ['internal_originations', 'credit_bureau_x'],
dataCategories: ['financial_history', 'demographics'],
knownLimitations: 'Underrepresented: self-employed applicants pre-2020',
},
);

mima.incidentReport()

await mima.incidentReport(
'Model output hallucination on edge case inputs',
'high',
{
description: 'Model returned invalid IBANs for 3 users on 2026-06-01',
affectedSystems: ['payment-processor-ai'],
detectedAt: '2026-06-01T14:22:00Z',
authorityNotifiedAt: '2026-06-01T18:00:00Z',
},
);

mima.accessReview()

await mima.accessReview(
'contractor@external.com',
'model-training-pipeline',
false,
{
reviewedBy: 'alice@example.com',
reviewType: 'periodic',
reason: 'Contractor engagement ended 2026-05-31',
},
);

mima.changeEvent()

await mima.changeEvent(
'prompt_update',
'alice@example.com',
'Updated system prompt to add output format constraints',
{
environment: 'production',
system: 'customer-support-ai',
changeId: 'CHG-4821',
},
);

mima.vendorRisk()

await mima.vendorRisk('OpenAI', 'high', {
lastReviewed: '2026-06-01',
findings: 2,
contacts: ['security@openai.com'],
});

mima.policyAcknowledged()

await mima.policyAcknowledged(
'AI Use Policy',
'alice@example.com',
{
version: 'v3.1.0',
acknowledgmentType: 'initial',
policyUrl: 'https://internal.example.com/policies/ai-use/v3.1.0',
channel: 'in-app',
},
);

mima.modelDriftEvent()

await mima.modelDriftEvent(
'loan-scorer-v2.1',
'f1_score',
0.94,
0.88,
0.90,
{
driftType: 'performance',
detectedBy: 'monitoring-agent',
actionTaken: 'Model retraining scheduled for 2026-07-01',
},
);

mima.governanceReview()

await mima.governanceReview(
'ciso@example.com',
'quarterly',
{
frameworksReviewed: ['EU_AI_ACT', 'ISO_42001', 'SOC2'],
overallReadiness: 78,
actionItems: 4,
notes: 'Three open gaps in Art.9 documentation.',
},
);

Lifecycle

Always call mima.close() at the end of a long-running process or serverless function. It flushes any buffered batch records.

// Express / Next.js — on shutdown
process.on('SIGTERM', async () => {
await mima.close();
process.exit(0);
});
// Lambda / serverless — at the end of each handler
export const handler = async (event: APIGatewayEvent) => {
try {
return await handleRequest(event);
} finally {
await mima.close();
}
};

The client also registers process.once('beforeExit', ...) as a safety net.


Signing GRC records

Pass a 32-byte hex key to enable HMAC-SHA256 signing. Every GRC push includes client_sig and client_sig_algo: "hmac-sha256".

import { randomBytes } from 'node:crypto';
// Generate once and store in a secrets manager:
const signingKey = randomBytes(32).toString('hex');
const mima = new MimaGovernance({
apiKey: '...',
systemName: '...',
signingKey,
});

The canonical message is cross-compatible with the Python SDK — signatures generated by either SDK verify against each other.


ESM setup

The package is ESM-only. In a CommonJS project, use dynamic import:

// CommonJS
const { MimaGovernance } = await import('@mima-ai/governance');

For mixed projects, add "type": "module" to your package.json and rename .js files to .mjs as needed.


Error handling

Error modes

onErrorBehaviour
'warn' (default)console.warn and return an empty result (recordId: '')
'raise'Throw MimaAttestationError
'silent'Swallow errors entirely, return empty result

Catching errors

import { MimaGovernance, MimaAttestationError } from '@mima-ai/governance';
const mima = new MimaGovernance({ ..., onError: 'raise' });
try {
await mima.push('tool', inputHash, outputHash);
} catch (err) {
if (err instanceof MimaAttestationError) {
logger.error('Governance record failed:', err.message);
}
}

Detecting failure without raising

const result = await mima.push('tool', inputHash, outputHash);
if (!result.recordId) {
logger.warn('Push failed:', result.detail);
}

The pattern is the same for all GRC methods — result.recordId === '' means failure.

Network and rate limits

ScenarioBehaviour
Network timeout15 s hardcoded; triggers error mode
HTTP 429 (rate limit)Retries after Retry-After header; limit is 2000 req/min
HTTP 401/403Invalid or expired API key; triggers error mode
HTTP 5xxServer error; triggers error mode (no automatic retry)

Workspace ID resolution

If you omit workspaceId, the SDK resolves it from your API key on first call. If resolution fails (invalid key, network error), you get:

MimaAttestationError: workspaceId not set and could not be resolved automatically

Fix: pass workspaceId explicitly or set MIMA_WORKSPACE_ID.

Batch flush on shutdown

Call await mima.shutdown() before process exit. Unflushed batch records are lost if the process terminates without shutdown. shutdown() flushes remaining records and throws MimaAttestationError (in 'raise' mode) if the final flush fails.


Type reference

All types are exported from @mima-ai/governance and available in your editor’s autocomplete.

Result types

interface AttestationResult {
attestationId: string; // unique ID, empty string on failure
externalVerified: boolean;
trustTier: string; // 'verified' | 'attested' | 'observed'
detail: string;
}
interface GrcResult {
recordId: string; // unique ID, empty string on failure
recordType: RecordType;
mappedControls: string[]; // e.g. ['EUAIA_ART9', 'ISO42001_6_1']
detail: string;
}

Configuration

interface MimaGovernanceOptions {
apiKey: string;
systemName: string;
workspaceId?: string; // auto-resolved from API key
baseUrl?: string; // default: 'https://api.mima.works'
agentName?: string; // defaults to systemName
signingKey?: string; // 32-byte hex, enables HMAC-SHA256 record signing
authorisedBy?: AuthorisedBy;
onError?: 'warn' | 'raise' | 'silent';
batchFlushInterval?: number; // ms, default: 30000
batchMaxSize?: number; // default: 100
}
interface AuthorisedBy {
identity: string; // email or principal ID
role?: string;
sessionId?: string;
}

Method options

interface WrapOptions {
modelId?: string;
authorisedBy?: AuthorisedBy;
mode?: 'sync' | 'batch'; // default: 'sync'
}
interface PushOptions {
modelId?: string;
authorisedBy?: AuthorisedBy;
executedAt?: string; // ISO timestamp, defaults to now
}

GRC method options

Each GRC method accepts a typed options object:

MethodOptions typeRequired fields
accessReview()AccessReviewOptionsreviewedBy
changeEvent()ChangeEventOptionsenvironment, system
vendorRisk()VendorRiskOptionslastReviewed
policyAcknowledged()PolicyAcknowledgedOptionsversion
incidentReport()IncidentReportOptionsdescription, affectedSystems
aiRiskAssessment()AiRiskAssessmentOptionsintendedPurpose, impactDomains, art5SelfAssessment, assessor
trainingDataGovernance()TrainingDataGovernanceOptionsbiasChecksPerformed, approvedBy, dataSources, dataCategories
modelEvaluation()ModelEvaluationOptionsevaluatedBy
humanOversight()HumanOversightOptionsreviewer
modelDriftEvent()ModelDriftEventOptionsdetectedBy
governanceReview()GovernanceReviewOptionsframeworksReviewed, overallReadiness

RecordType union

type RecordType =
| 'ai_risk_assessment'
| 'governance_review'
| 'model_evaluation'
| 'training_data_governance'
| 'human_oversight'
| 'incident_report'
| 'change_event'
| 'access_review'
| 'vendor_risk'
| 'model_drift_event'
| 'policy_acknowledged';