The Entry Point Explosion Problem

Modern applications face a scaling challenge: every new interface multiplies implementation effort. Expose a function via CLI, and you write argv parsing and help text. Make it callable by AI agents, and you generate tool descriptions and handle structured input. Add an HTTP endpoint, and you're back to validating requests and shaping error responses. Ageniti addresses this by asking developers to define actions once and automatically deriving all interfaces from that single source of truth.

The approach

Ageniti treats actions as primitive building blocks rather than thin wrappers around business logic. Each action declares its input contract, output contract, side effects, and idempotency behavior upfront. The framework then generates surface-specific artifacts—CLI flags, MCP tool specs, OpenAI function definitions, HTTP routes—directly from this declaration. This eliminates the typical drift between interfaces where changes in one surface require manual synchronization across others.

The runtime layer handles cross-cutting concerns consistently across all surfaces. Validation, permission checks, logging with redaction, cancellation, and streaming events are managed centrally rather than reimplemented per surface. When an action runs, subscribers can observe its progress through a unified event stream that works equally well for CLI output, React UI updates, or agent monitoring.

This surface-agnostic design extends to schema handling. While Ageniti provides its own schema helpers, it accepts any Standard Schema v1 compliant library—Zod, Valibot, ArkType—wrapping foreign schemas transparently and generating the appropriate JSON Schema for each target platform.

What you actually get

Core runtime features:

  • Single invocation model with consistent envelopes across all surfaces
  • Input/output validation with pluggable schema libraries
  • Permission gating and confirmation flows for destructive operations
  • Idempotency through keyed caching with bounded memory usage
  • Concurrency limits per action with configurable retry behavior
  • Timeout and cancellation handling via AbortController signals
  • Automatic redaction of sensitive data in logs and artifacts

Multiple surface adapters:

  • CLI with built-in help, flags, and NDJSON streaming output
  • MCP stdio server for agent integration
  • HTTP handler for Express, Hono, Next.js, or raw Node servers
  • OpenAI and AI SDK tool generation (function calling, responses API, generic tools)
  • React hooks with full state machine management
  • JSON runner for programmatic invocation

Developer experience:

  • Typed client generation from action manifests
  • Test utilities with runtime stubbing and event collection
  • Bulk wrapping of existing functions as actions
  • Per-action deprecation warnings
  • Centralized error codes mapped appropriately per surface

What it doesn't do

Ageniti focuses heavily on the action primitive layer but stops short of providing higher-level orchestration. There's no built-in workflow engine for chaining actions, no built-in persistence layer for state management, and no opinionated UI components beyond the React hook foundation. The framework assumes you'll bring your own services for external integrations rather than bundling specific database or API clients. Additionally, while it supports multiple schema libraries, it doesn't include built-in schema migration tools or versioning strategies for evolving action contracts.

Trying it out

Installation is straightforward with npm i @ageniti/core, and the package provides extensive subpath exports for targeted imports. The source contains working examples demonstrating CLI, MCP, and HTTP surfaces, though generating actual action implementations requires defining your own contract declarations. See the project's Getting Started guide for implementation details.

Who should consider it

Ageniti makes sense if you're building applications that need to serve multiple caller types—human operators via CLI, automation scripts, AI agents, and web interfaces—and you want to avoid interface drift and duplicated validation logic. It's most valuable in codebase areas where consistency across surfaces matters more than surface-specific optimizations. Alternatives like tRPC or direct framework integrations might be lighter for single-surface applications, but they don't provide the automatic surface derivation that Ageniti offers. The source is on GitHub.