TypeScript SDK
AegisClient for TypeScript and Node.js — execution, approvals, SEAL, stimulus, admin, and more.
TypeScript SDK
Configure the GitHub Packages registry, then install:
npm config set @100monkeys-ai:registry https://npm.pkg.github.com
npm install @100monkeys-ai/aegis-sdkAegisClient
import { AegisClient } from '@100monkeys-ai/aegis-sdk';
const client = new AegisClient(
'https://your-aegis-node',
process.env.AEGIS_API_KEY, // Optional; Keycloak Bearer JWT
);Constructor
new AegisClient(baseUrl: string, apiKey?: string)| Parameter | Type | Description |
|---|---|---|
baseUrl | string | Base URL of the AEGIS orchestrator (no trailing slash) |
apiKey | string | Optional Keycloak Bearer JWT. When omitted, requests are unauthenticated. |
Execution
startExecution(agentId, input, contextOverrides?)
Start a new agent execution. Returns the execution ID immediately; use streamExecution to follow progress.
const { execution_id } = await client.startExecution(
'agent-uuid',
'Write a primality check in TypeScript',
);
console.log(execution_id); // "exec-uuid"| Parameter | Type | Description |
|---|---|---|
agentId | string | UUID of the agent to execute |
input | string | The task prompt / instruction |
contextOverrides | any | Optional context overrides for the execution |
Returns: Promise<StartExecutionResponse>
interface StartExecutionResponse {
execution_id: string;
}streamExecution(executionId, token?)
Stream SSE events for a running execution.
const stream = await client.streamExecution(execution_id);| Parameter | Type | Description |
|---|---|---|
executionId | string | UUID of the execution to stream |
token | string | Optional resumption token |
Returns: Promise<ReadableStream> — an SSE event stream (see Streaming Executions below).
Human Approvals
listPendingApprovals()
List all pending human approval requests.
const { pending_requests, count } = await client.listPendingApprovals();
console.log(`${count} pending approvals`);Returns: Promise<{ pending_requests: PendingApproval[]; count: number }>
getPendingApproval(id)
Get a specific pending approval by ID.
Returns: Promise<{ request: PendingApproval }>
approveRequest(id, request?)
Approve a pending request.
await client.approveRequest('approval-uuid', {
feedback: 'Looks good',
approved_by: 'jeshua',
});| Parameter | Type | Description |
|---|---|---|
id | string | UUID of the approval request |
request | ApprovalRequest | Optional feedback and approver identity |
Returns: Promise<ApprovalResponse>
rejectRequest(id, request)
Reject a pending request with a reason.
await client.rejectRequest('approval-uuid', {
reason: 'Scope too broad',
rejected_by: 'jeshua',
});| Parameter | Type | Description |
|---|---|---|
id | string | UUID of the approval request |
request | RejectionRequest | Reason and optional rejector identity |
Returns: Promise<ApprovalResponse>
SEAL
attestSeal(payload)
Request an SEAL security token via attestation.
Returns: Promise<SealAttestationResponse>
interface SealAttestationResponse {
security_token: string;
}invokeSeal(payload)
Invoke an SEAL tool with a signed payload.
Returns: Promise<any>
listSealTools(securityContext?)
List available SEAL tools, optionally filtered by security context.
Returns: Promise<SealToolsResponse>
interface SealToolsResponse {
protocol: string;
attestation_endpoint: string;
invoke_endpoint: string;
security_context?: string;
tools: any[];
}SEAL Protocol
The @100monkeys-ai/aegis-sdk package exports a low-level SEAL module for workloads that need to self-attest and call SEAL tools directly — without going through AegisClient. Useful for custom bootstrap scripts and server-side envelope verification.
Import
import { SEALClient, Ed25519Key, createSealEnvelope, verifySealEnvelope } from '@100monkeys-ai/aegis-sdk';SEALClient
High-level client: generates a keypair, attests, and calls tools.
import { SEALClient } from '@100monkeys-ai/aegis-sdk';
const seal = new SEALClient(
'https://your-aegis-node',
'my-workload',
'default',
);
try {
const result = await seal.attest();
console.log(result.security_token);
const output = await seal.callTool('read_file', { path: '/workspace/main.ts' });
console.log(output);
} finally {
seal.dispose(); // zeroes the in-memory private key
}Constructor:
new SEALClient(gatewayUrl: string, workloadId: string, securityScope: string)| Parameter | Type | Description |
|---|---|---|
gatewayUrl | string | Base URL of the SEAL gateway |
workloadId | string | Identifier for this workload |
securityScope | string | Security context / scope label |
Methods:
| Method | Returns | Description |
|---|---|---|
attest() | Promise<AttestationResult> | Generates a keypair, attests, returns a security token |
callTool(toolName, argumentsObj) | Promise<unknown> | Calls a SEAL tool after attestation |
dispose() | void | Zeroes the private key from memory |
AttestationResult:
type AttestationResult = {
security_token: string;
expires_at: string;
session_id?: string;
}Ed25519Key
Low-level Ed25519 keypair for manual envelope construction.
import { Ed25519Key } from '@100monkeys-ai/aegis-sdk';
const key = Ed25519Key.generate();
const signatureB64 = key.signBase64(new TextEncoder().encode('my message'));
const pubKeyB64 = key.getPublicKeyBase64();
key.erase(); // zeroes the private key when done| Method | Returns | Description |
|---|---|---|
Ed25519Key.generate() | Ed25519Key | Generate a new random keypair |
sign(message: Uint8Array) | Uint8Array | Sign bytes, return raw signature |
signBase64(message: Uint8Array) | string | Sign bytes, return base64-encoded signature |
getPublicKeyBytes() | Uint8Array | Raw 32-byte public key |
getPublicKeyBase64() | string | Base64-encoded public key |
erase() | void | Zeroes the private key from memory |
Envelope utilities
createSealEnvelope(securityToken, mcpPayload, privateKey)
Construct a signed SEAL envelope.
import { createSealEnvelope, Ed25519Key } from '@100monkeys-ai/aegis-sdk';
const key = Ed25519Key.generate();
const envelope = createSealEnvelope(
'<security-token>',
{ jsonrpc: '2.0', id: 1, method: 'tools/call', params: { name: 'read_file', arguments: {} } },
key,
);
// Pass envelope to AegisClient.invokeSeal() or the raw SEAL endpointverifySealEnvelope(envelope, publicKeyBytes, maxAgeSeconds?)
Server-side verification. Throws on invalid signature or expired timestamp; returns the inner MCP payload on success.
import { verifySealEnvelope } from '@100monkeys-ai/aegis-sdk';
const payload = verifySealEnvelope(
envelopeObject,
registeredPublicKeyBytes,
30, // max age in seconds (default: 30)
);createCanonicalMessage(securityToken, payload, timestampUnix)
Low-level helper that produces the canonical Uint8Array that is signed.
import { createCanonicalMessage } from '@100monkeys-ai/aegis-sdk';
const msgBytes = createCanonicalMessage('<token>', mcpPayload, Math.floor(Date.now() / 1000));SEAL types
interface McpPayload {
jsonrpc: string;
id: string | number;
method: string;
params?: Record<string, unknown>;
}
interface SealEnvelope {
protocol: string;
security_token: string;
signature: string;
payload: McpPayload;
timestamp: string;
}
class SEALError extends Error {}Dispatch Gateway
dispatchGateway(payload)
Dispatch a message to the inner loop gateway.
Returns: Promise<any>
Stimulus
ingestStimulus(payload)
Ingest an external stimulus event.
Returns: Promise<any>
sendWebhook(source, payload)
Send a webhook event from a named source.
| Parameter | Type | Description |
|---|---|---|
source | string | Webhook source identifier |
payload | any | Webhook event body |
Returns: Promise<any>
Workflow Logs
getWorkflowExecutionLogs(executionId, limit?, offset?)
Retrieve paginated workflow execution logs.
Returns: Promise<WorkflowExecutionLogs>
interface WorkflowExecutionLogs {
execution_id: string;
events: any[];
count: number;
limit: number;
offset: number;
}streamWorkflowExecutionLogs(executionId)
Stream workflow execution logs via SSE.
Returns: Promise<ReadableStream>
Admin: Tenant Management
createTenant(slug, displayName, tier?)
Create a new tenant. The tier parameter defaults to 'enterprise'.
Returns: Promise<Tenant>
interface Tenant {
slug: string;
display_name: string;
status: string;
tier: string;
keycloak_realm: string;
openbao_namespace: string;
quotas: TenantQuotas;
created_at: string;
updated_at: string;
deleted_at?: string;
}
interface TenantQuotas {
max_concurrent_executions: number;
max_agents: number;
max_storage_gb: number;
}listTenants()
List all tenants.
Returns: Promise<{ tenants: Tenant[]; count: number }>
suspendTenant(slug)
Suspend a tenant by slug.
Returns: Promise<{ status: string; slug: string }>
deleteTenant(slug)
Soft-delete a tenant by slug.
Returns: Promise<{ status: string; slug: string }>
Admin: Rate Limits
listRateLimitOverrides(tenantId?, userId?)
List rate limit overrides, optionally filtered by tenant or user.
Returns: Promise<{ overrides: RateLimitOverride[]; count: number }>
interface RateLimitOverride {
id: string;
resource_type: string;
bucket: string;
limit_value: number;
tenant_id?: string;
user_id?: string;
burst_value?: number;
created_at: string;
updated_at: string;
}createRateLimitOverride(payload)
Create or update a rate limit override.
Returns: Promise<RateLimitOverride>
deleteRateLimitOverride(overrideId)
Delete a rate limit override by ID.
Returns: Promise<{ status: string; id: string }>
getRateLimitUsage(scopeType, scopeId)
Get rate limit usage for a specific scope.
| Parameter | Type | Description |
|---|---|---|
scopeType | string | Scope type (e.g., "tenant", "user") |
scopeId | string | Scope identifier |
Returns: Promise<{ usage: UsageRecord[]; count: number }>
interface UsageRecord {
scope_type: string;
scope_id: string;
resource_type: string;
bucket: string;
window_start: string;
counter: number;
}Health
healthLive()
Liveness probe. Returns { status: string }.
healthReady()
Readiness probe. Returns { status: string }.
Streaming Executions
Use streamExecution to follow a running execution via SSE:
import { AegisClient } from '@100monkeys-ai/aegis-sdk';
const client = new AegisClient('https://your-aegis-node', process.env.AEGIS_API_KEY);
const { execution_id } = await client.startExecution('agent-uuid', 'Analyze this codebase');
const stream = await client.streamExecution(execution_id);
const decoder = new TextDecoder();
const reader = stream.getReader();
while (true) {
const { value, done } = await reader.read();
if (done) break;
const text = decoder.decode(value);
for (const line of text.split('\n')) {
if (!line.startsWith('data:')) continue;
const event = JSON.parse(line.slice(5).trim());
if (event.iteration_started) {
console.log(`Iteration ${event.iteration_started.iteration_number}`);
} else if (event.execution_completed) {
console.log('Output:', event.execution_completed.final_output);
} else if (event.execution_failed) {
console.error('Failed:', event.execution_failed.reason);
}
}
}See SSE stream format for the full event schema.
Agent Manifests
The @100monkeys-ai/aegis-sdk package exports manifest types and a fluent builder for constructing agent manifest YAML files programmatically.
import { AgentManifestBuilder, ImagePullPolicy } from '@100monkeys-ai/aegis-sdk';AgentManifestBuilder
Fluent builder — the recommended API for creating manifests in code.
import { AgentManifestBuilder, ImagePullPolicy } from '@100monkeys-ai/aegis-sdk';
const manifest = new AgentManifestBuilder('my-agent', 'typescript')
.withDescription('Analyses TypeScript repos for security issues')
.withInstruction('You are a security auditor. Analyse the code and report CVEs.')
.withExecutionMode('iterative', 15)
.withImagePullPolicy(ImagePullPolicy.IfNotPresent)
.withNetworkAllow(['api.github.com', 'registry.npmjs.org'])
.withTool('read_file')
.withTool('run_command')
.withEnv('LOG_LEVEL', 'debug')
.build();Constructor:
new AgentManifestBuilder(name: string, language?: string, version?: string)Methods:
| Method | Description |
|---|---|
withDescription(description) | Set the manifest description |
withLabel(key, value) | Add a metadata label |
withInstruction(instruction) | Set the agent system instruction |
withExecutionMode(mode, maxIterations?) | Set "one-shot" or "iterative" mode |
withImage(image) | Set a custom Docker image |
withImagePullPolicy(policy) | Set the image pull policy (ImagePullPolicy enum) |
withBootstrapPath(path) | Path to a custom bootstrap script inside the image |
withNetworkAllow(domains) | Allowlist of hostnames the agent may reach |
withTool(tool) | Add a SEAL tool name to the agent's tool list |
withEnv(key, value) | Add an environment variable |
build() | Returns a validated AgentManifest |
ImagePullPolicy
enum ImagePullPolicy {
Always = 'Always',
IfNotPresent = 'IfNotPresent',
Never = 'Never',
}Manifest utility functions
| Function | Description |
|---|---|
loadManifest(path) | Load and validate a manifest from a YAML file |
saveManifest(manifest, path) | Serialise and write the manifest to a YAML file |
validateManifest(manifest) | Validate the manifest; throws on invalid |
Key manifest types
| Interface | Purpose |
|---|---|
AgentManifest | Root manifest: apiVersion, kind, metadata, spec |
ManifestMetadata | name, version, description, tags, labels, annotations |
RuntimeConfig | language, version, image, image_pull_policy, isolation, model |
TaskConfig | instruction, prompt_template, input_data |
ExecutionStrategy | mode, max_iterations, llm_timeout_seconds |
SecurityConfig | network, filesystem, resources |
AdvancedConfig | warm_pool_size, swarm_enabled, startup_script, bootstrap_path |
AgentSpec | Root spec combining all of the above |
For the full field reference, see the Agent Manifest Reference.
Error Handling
All methods throw on non-2xx responses. Catch and inspect axios.isAxiosError(err) for HTTP-level errors:
import axios from 'axios';
import { AegisClient } from '@100monkeys-ai/aegis-sdk';
const client = new AegisClient('https://your-aegis-node', process.env.AEGIS_API_KEY);
try {
const { execution_id } = await client.startExecution('agent-uuid', 'Do something');
} catch (err) {
if (axios.isAxiosError(err)) {
console.error(err.response?.status, err.response?.data);
} else {
throw err;
}
}