npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ascend-ai/sdk

v2.1.0

Published

ASCEND SDK - Enterprise AI Governance with fail mode, circuit breaker, and MCP integration

Readme

ASCEND Node.js/TypeScript SDK v2.0

Enterprise-grade AI governance SDK for Node.js and TypeScript applications.

Features

  • Fail Mode Configuration - Choose between fail-closed (secure) or fail-open (available) when ASCEND is unreachable
  • Circuit Breaker Pattern - Automatic failure detection with graceful recovery
  • Agent Registration - Register agents with capabilities and permissions
  • Action Evaluation - Real-time authorization decisions with risk scoring
  • Completion Logging - Track action success/failure for audit trails
  • Approval Workflows - Human-in-the-loop approval for high-risk actions
  • MCP Integration - Higher-order functions for MCP server tools
  • HMAC-SHA256 Signing - Request integrity verification
  • Structured Logging - JSON logs with automatic API key masking
  • Full TypeScript Support - Complete type definitions included

Installation

npm install @ascend/sdk
# or
yarn add @ascend/sdk

Quick Start

import { AscendClient, FailMode, Decision } from '@ascend/sdk';

// Initialize client
const client = new AscendClient({
  apiKey: 'owkai_your_api_key',
  agentId: 'agent-001',
  agentName: 'My AI Agent',
  failMode: FailMode.CLOSED,  // Block on ASCEND unreachable
});

// Register agent (call once on startup)
await client.register({
  agentType: 'automation',
  capabilities: ['data_access', 'file_operations'],
  allowedResources: ['production_db', '/var/log/*'],
});

// Evaluate action before execution
const decision = await client.evaluateAction({
  actionType: 'database.query',
  resource: 'production_db',
  parameters: { query: 'SELECT * FROM users WHERE active = true' },
});

if (decision.decision === Decision.ALLOWED) {
  // Execute your action
  const result = await executeDatabaseQuery();

  // Log completion
  await client.logActionCompleted(
    decision.actionId,
    { rowsReturned: result.length },
    150  // duration in ms
  );
} else if (decision.decision === Decision.DENIED) {
  console.log(`Action denied: ${decision.reason}`);
  console.log(`Policy violations: ${decision.policyViolations}`);
} else if (decision.decision === Decision.PENDING) {
  console.log(`Awaiting approval from: ${decision.requiredApprovers}`);
}

Fail Mode Configuration

ASCEND supports two fail modes for handling service unavailability:

Fail-Closed (Recommended for Production)

const client = new AscendClient({
  apiKey: '...',
  agentId: '...',
  agentName: '...',
  failMode: FailMode.CLOSED,  // Default
});

When ASCEND is unreachable:

  • All actions are blocked
  • ConnectionError or CircuitBreakerOpenError thrown
  • Ensures no unauthorized actions occur

Fail-Open (Use with Caution)

const client = new AscendClient({
  apiKey: '...',
  agentId: '...',
  agentName: '...',
  failMode: FailMode.OPEN,
});

When ASCEND is unreachable:

  • Actions are allowed to proceed
  • Returns synthetic ALLOWED decision with fail_open_mode condition
  • Use only when availability is critical

Circuit Breaker

The SDK includes an automatic circuit breaker to prevent cascading failures:

const client = new AscendClient({
  apiKey: '...',
  agentId: '...',
  agentName: '...',
  circuitBreakerOptions: {
    failureThreshold: 5,     // Open after 5 failures
    recoveryTimeout: 30,     // Try recovery after 30s
    halfOpenMaxCalls: 3,     // Allow 3 test calls in half-open
  },
});

// Check circuit state
const state = client.getCircuitBreakerState();
console.log(`State: ${state.state}, Failures: ${state.failures}`);

// Reset circuit breaker
client.resetCircuitBreaker();

Circuit states:

  • CLOSED: Normal operation, requests flow through
  • OPEN: After threshold failures, requests fail immediately
  • HALF_OPEN: After recovery timeout, limited test requests allowed

MCP Server Integration

Integrate ASCEND governance with MCP (Model Context Protocol) servers:

import { AscendClient } from '@ascend/sdk';
import { mcpGovernance, highRiskAction } from '@ascend/sdk/mcp';

const client = new AscendClient({ ... });

// Basic governance wrapper
const queryDatabase = mcpGovernance(client, {
  actionType: 'database.query',
  resource: 'production_db',
})(async (sql: string) => {
  return await db.execute(sql);
});

// High-risk action requiring human approval
const deleteRecords = highRiskAction(client, 'database.delete', 'production_db')(
  async (table: string, whereClause: string) => {
    return await db.execute(`DELETE FROM ${table} WHERE ${whereClause}`);
  }
);

// Use the governed functions
const result = await queryDatabase('SELECT * FROM users');

MCP Governance Configuration

import { mcpGovernance, MCPGovernanceConfig } from '@ascend/sdk/mcp';

const config: MCPGovernanceConfig = {
  waitForApproval: true,           // Wait for pending approvals
  approvalTimeoutMs: 300000,       // 5 minute timeout
  approvalPollIntervalMs: 5000,    // Check every 5 seconds
  raiseOnDenial: true,             // Throw error on denial
  logAllDecisions: true,           // Log all authorization decisions
  onApprovalRequired: (decision, toolName) => {
    notifyAdmin(`Approval needed for ${toolName}`);
  },
};

const writeConfig = mcpGovernance(client, {
  actionType: 'file.write',
  resource: '/etc/config',
  config,
})(writeToFile);

Middleware Pattern

import { MCPGovernanceMiddleware } from '@ascend/sdk/mcp';

const middleware = new MCPGovernanceMiddleware(client);

// Wrap multiple tools
const tools = {
  query: middleware.wrap('database.query', 'prod_db', queryFn),
  write: middleware.wrap('file.write', '/var/log', writeFn),
  delete: middleware.wrapHighRisk('database.delete', 'prod_db', deleteFn),
};

// Check governed tools
console.log(`Governed tools: ${middleware.governedTools}`);

Approval Workflows

Handle human-in-the-loop approvals for high-risk actions:

// Request with automatic approval waiting
const decision = await client.evaluateAction({
  actionType: 'financial.transfer',
  resource: 'payment_gateway',
  parameters: { amount: 50000, currency: 'USD' },
  waitForApproval: true,        // Block until approved/denied
  approvalTimeout: 300000,      // 5 minute timeout
  requireHumanApproval: true,   // Force human review
});

// Manual approval polling
const decision = await client.evaluateAction({
  actionType: 'financial.transfer',
  resource: 'payment_gateway',
  parameters: { amount: 50000 },
});

if (decision.decision === Decision.PENDING) {
  const approvalId = decision.approvalRequestId!;

  // Poll for approval
  while (true) {
    const status = await client.checkApproval(approvalId);
    if (status.status === 'approved') {
      // Execute action
      break;
    } else if (status.status === 'rejected') {
      // Handle rejection
      break;
    }
    await sleep(5000);
  }
}

Webhook Configuration

Receive real-time notifications for authorization events:

await client.configureWebhook({
  url: 'https://your-app.com/webhooks/ascend',
  events: [
    'action.evaluated',
    'action.approved',
    'action.denied',
    'action.completed',
    'action.failed',
  ],
  secret: 'your_webhook_secret',  // For signature verification
});

Structured Logging

The SDK includes structured JSON logging with automatic API key masking:

const client = new AscendClient({
  apiKey: '...',
  agentId: '...',
  agentName: '...',
  logLevel: 'DEBUG',  // DEBUG, INFO, WARNING, ERROR
  jsonLogs: true,     // Enable JSON format
});

// Logs automatically mask API keys:
// {"timestamp":"2024-01-15T10:30:00Z","level":"INFO","message":"Evaluating action","api_key":"owkai_****"}

Error Handling

import {
  AscendClient,
  AuthenticationError,
  AuthorizationError,
  CircuitBreakerOpenError,
  ConnectionError,
  TimeoutError,
  RateLimitError,
} from '@ascend/sdk';

try {
  const decision = await client.evaluateAction({ ... });
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.log(`Invalid API key: ${error.message}`);
  } else if (error instanceof AuthorizationError) {
    console.log(`Authorization denied: ${error.message}`);
    console.log(`Policy violations: ${error.policyViolations}`);
    console.log(`Risk score: ${error.riskScore}`);
  } else if (error instanceof CircuitBreakerOpenError) {
    console.log(`Service unavailable: ${error.message}`);
    console.log(`Recovery in: ${error.recoveryTimeSeconds}s`);
  } else if (error instanceof ConnectionError) {
    console.log(`Connection failed: ${error.message}`);
  } else if (error instanceof TimeoutError) {
    console.log(`Request timed out after ${error.timeoutMs}ms`);
  } else if (error instanceof RateLimitError) {
    console.log(`Rate limited, retry after ${error.retryAfter}s`);
  }
}

API Reference

AscendClient

interface AscendClientOptions {
  apiKey: string;                    // Required: Organization API key
  agentId: string;                   // Required: Unique agent identifier
  agentName: string;                 // Required: Human-readable name
  apiUrl?: string;                   // Default: 'https://pilot.owkai.app'
  environment?: string;              // Default: 'production'
  failMode?: FailMode;               // Default: FailMode.CLOSED
  timeout?: number;                  // Request timeout in ms (default: 30000)
  maxRetries?: number;               // Default: 3
  debug?: boolean;                   // Enable debug logging
  logLevel?: LogLevel;               // 'DEBUG' | 'INFO' | 'WARNING' | 'ERROR'
  jsonLogs?: boolean;                // Use JSON format (default: true)
  enableMetrics?: boolean;           // Enable metrics collection
  signingSecret?: string;            // For HMAC signing
  circuitBreakerOptions?: {
    failureThreshold?: number;       // Default: 5
    recoveryTimeout?: number;        // Default: 30
    halfOpenMaxCalls?: number;       // Default: 3
  };
}

Methods

| Method | Description | |--------|-------------| | register(options) | Register agent with ASCEND | | evaluateAction(options) | Evaluate action for authorization | | logActionCompleted(actionId, result?, durationMs?) | Log successful completion | | logActionFailed(actionId, error, durationMs?) | Log action failure | | checkApproval(approvalRequestId) | Check approval status | | configureWebhook(options) | Configure webhook notifications | | testConnection() | Test API connectivity | | getCircuitBreakerState() | Get circuit breaker state | | resetCircuitBreaker() | Reset circuit breaker | | getMetrics() | Get metrics snapshot |

Types

// Decision values
enum Decision {
  ALLOWED = 'allowed',
  DENIED = 'denied',
  PENDING = 'pending',
}

// Evaluation result
interface EvaluateActionResult {
  decision: Decision;
  actionId: string;
  reason?: string;
  riskScore?: number;
  policyViolations: string[];
  conditions: string[];
  approvalRequestId?: string;
  requiredApprovers: string[];
  expiresAt?: string;
  metadata: Record<string, unknown>;
}

// Registration response
interface RegisterResponse {
  agentId: string;
  status: string;
  registeredAt: string;
  capabilities: string[];
  metadata?: Record<string, unknown>;
}

Legacy Client (v1.0)

For backward compatibility, the legacy OWKAIClient is still available:

import { OWKAIClient } from '@ascend/sdk';

const client = new OWKAIClient({
  apiKey: 'your-api-key',
});

const decision = await client.submitAction({
  agentId: 'agent-001',
  agentName: 'My Agent',
  actionType: ActionType.DATA_ACCESS,
  resource: 'customer_data',
});

Compliance

This SDK supports the following compliance frameworks:

  • SOC 2 Type II (CC6.1) - Access control and audit trails
  • HIPAA (164.312(e)) - Transmission security
  • PCI-DSS (8.2, 8.3) - API key management, MFA
  • NIST AI RMF - Govern, Map, Measure, Manage
  • NIST 800-63B - Authentication standards

Support

  • Documentation: https://docs.ascendowkai.com
  • Issues: https://github.com/anthropics/ascend-sdk-nodejs/issues
  • Email: [email protected]