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

@apijack/core

v1.3.0

Published

Jack into any OpenAPI spec and rip a full-featured CLI with AI-agentic workflow automation

Downloads

1,840

Readme

apijack

Jack into any OpenAPI spec and rip a full-featured CLI with AI-agentic workflow automation.

npm tests e2e buy me a coffee

Getting Started

bun install -g @apijack/core

Claude Code Plugin

Install as a Claude Code plugin to let Claude interact with your APIs directly:

apijack plugin install

Then in Claude Code, run /reload-plugins. The plugin exposes 10 MCP tools and 3 skills:

MCP Tools

| Tool | Description | |------|-------------| | setup | Configure API credentials for an environment | | generate | Regenerate CLI from the active environment's OpenAPI spec | | run_commands | Run one or more CLI commands sequentially | | run_routine | Execute a named routine workflow | | list_commands | List available CLI commands (optionally filtered) | | list_routines | List available routines | | get_routine_templates | Get YAML routine step templates for commands | | config_list | List configured environments | | config_switch | Switch active environment | | get_config | Get active environment config | | get_spec | Get summary of generated API types |

Skills

| Skill | Description | |-------|-------------| | /setup-api | Connect to an API, configure credentials, generate the CLI | | /write-routine | Author YAML workflow automations that chain CLI commands |

Example Prompt

"Use /setup-api to connect apijack to my todo list API at http://localhost:8080, then use /write-routine to automate an e2e test: create 10 todos and then delete them all."

Direct CLI Usage

Use apijack directly from the terminal without the plugin:

apijack setup              # Configure URL + credentials (auth auto-detected)
apijack generate            # Pull OpenAPI spec, generate types/client/commands
apijack --help              # See all generated commands

As a Framework

For building dedicated CLI products with apijack as a framework:

bun add @apijack/core
import { createCli, BasicAuthStrategy } from "@apijack/core";

const cli = createCli({
  name: "mycli",
  description: "My API CLI",
  version: "1.0.0",
  specPath: "/v3/api-docs",
  auth: new BasicAuthStrategy(),
});

cli.run();

Generate your CLI from a running API:

mycli setup        # Configure URL + credentials
mycli generate     # Pull OpenAPI spec, generate types/client/commands
mycli --help       # See all generated commands

Features

  • OpenAPI codegen -- types, client, and Commander commands from any spec
  • Claude Code plugin -- one-command setup, MCP server, AI-integrated skills
  • Pluggable auth strategies -- Basic, Bearer, API Key, or build your own
  • Secure credential handling -- dev URLs stored locally, production APIs require env vars
  • Multi-environment config -- switch between dev/staging/prod with config switch
  • YAML routine engine -- variables, conditions, forEach, assertions, sub-routines
  • Composable dispatcher -- built-in meta-commands (wait-until, session refresh, sub-routines)
  • -o routine-step export -- run any command with -o routine-step to emit YAML you can paste into workflows
  • Built-in commands -- setup, config, generate, routine run/list/validate/test, plugin

Credential Security

apijack classifies API URLs and restricts credential storage:

Development (localhost, 127.0.0.1, ::1, allowed CIDRs): credentials stored in ~/.{cli}/config.json.

Production (everything else): credentials blocked from plaintext storage. Use environment variables:

export MYCLI_URL=https://api.example.com
export [email protected]
export MYCLI_PASS=secret

Or pass --allow-insecure-storage to override (not recommended).

Internal Networks

Configure allowed CIDRs for internal networks:

apijack plugin config add-cidr 192.168.1.0/24
apijack plugin config add-cidr 10.0.0.0/8

CLI developers can also set defaults:

createCli({
  // ...
  allowedCidrs: ["192.168.0.0/16", "10.0.0.0/8"],
});

Project Mode

Drop an .apijack.json in your project root to make apijack project-aware:

{
  "name": "my-api",
  "specUrl": "http://localhost:8080/v3/api-docs",
  "generatedDir": "./src/generated"
}

With a project file, apijack:

  • Reads defaults from .apijack.json (committed to git)
  • Stores credentials in .apijack/config.json (add .apijack/ to .gitignore)
  • Generates files to your project's configured directory
  • Loads routines from ./routines/ in addition to global ones

Project Extensions

Extend apijack with project-local code in .apijack/:

.apijack/
├── config.json          # credentials (gitignored)
├── auth.ts              # custom auth strategy (export default)
├── commands/            # custom commands (each file exports a registrar)
│   └── deploy.ts
└── dispatchers/         # custom dispatchers (each file exports a handler)
    └── notify.ts

Custom auth (.apijack/auth.ts):

export default {
  async authenticate(config) {
    const token = await fetchToken(config);
    return { headers: { Authorization: `Bearer ${token}` } };
  },
  async restore(cached) { return cached; },
};

Custom command (.apijack/commands/deploy.ts):

export const name = 'deploy';
export default function register(program, ctx) {
  program.command('deploy')
    .description('Deploy the current environment')
    .action(async () => { /* ... */ });
}

Without a project file, apijack runs in global mode using ~/.apijack/.

Routines

Routines are YAML-based workflow definitions stored in ~/.{cli}/routines/. They chain CLI commands with variables, conditionals, loops, assertions, and sub-routines.

name: my-routine
description: Example workflow
variables:
  project_name: "default-value"
steps:
  - name: create-resource
    command: resources create
    args:
      --name: "$project_name"
    output: created

  - name: verify-resource
    command: resources get
    args:
      --id: "$created.id"
    assert:
      - path: "$.name"
        equals: "$project_name"

Discover command signatures for building routines:

mycli resources create --name test -o routine-step

Auth Strategies

Basic Auth

import { BasicAuthStrategy } from "@apijack/core";
const auth = new BasicAuthStrategy();

Bearer Token

import { BearerTokenStrategy } from "@apijack/core";
const auth = new BearerTokenStrategy(async (config) => {
  const res = await fetch(`${config.baseUrl}/oauth/token`, {
    method: "POST",
    body: JSON.stringify({ username: config.username, password: config.password }),
  });
  const { access_token } = await res.json();
  return access_token;
});

API Key

import { ApiKeyStrategy } from "@apijack/core";
const auth = new ApiKeyStrategy("X-API-Key", "your-api-key");

Custom

Implement the AuthStrategy interface:

import type { AuthStrategy, AuthSession, ResolvedAuth } from "@apijack/core";

class MyStrategy implements AuthStrategy {
  async authenticate(config: ResolvedAuth): Promise<AuthSession> {
    return { headers: { Authorization: "Custom ..." } };
  }
  async restore(cached: AuthSession): Promise<AuthSession | null> {
    return cached;
  }
}

MCP Server (Other Editors)

For MCP-compatible editors other than Claude Code (Cursor, Windsurf, etc.), add to your project's .mcp.json:

{
  "mcpServers": {
    "apijack": {
      "type": "stdio",
      "command": "apijack",
      "args": ["mcp"]
    }
  }
}

This exposes the same 10 tools as the Claude Code plugin.

OpenAPI Spec Compatibility

OpenAPI 3.0

| Feature | Status | Notes | |---------|--------|-------| | Schemas | | | | Primitive types (string, number, integer, boolean) | :white_check_mark: | | | $ref resolution | :white_check_mark: | Recursive refs handled | | allOf composition | :white_check_mark: | Intersection types, inline members with JSDoc | | oneOf / anyOf | :white_check_mark: | Union types, inline variant resolution | | Discriminated unions (discriminator + mapping) | :white_check_mark: | Tagged union output | | enum types | :white_check_mark: | String literal unions | | nullable | :white_check_mark: | T \| null | | array with items | :white_check_mark: | Wraps union/intersection in parens | | Nested inline objects | :white_check_mark: | Up to depth 3 | | additionalProperties | :white_check_mark: | Typed and untyped index signatures | | required fields | :white_check_mark: | Non-optional properties, requiredOption in CLI | | readOnly / writeOnly | :white_check_mark: | readOnly skipped from CLI flags, JSDoc annotated | | default values | :white_check_mark: | JSDoc @default tag | | format hints | :white_check_mark: | date-time, email, uri, uuid, int32, int64, float, double | | Constraints | :white_check_mark: | minimum, maximum, minLength, maxLength, pattern, minItems, maxItems, uniqueItems | | example values | :white_check_mark: | JSDoc @example tag | | deprecated schemas | :white_check_mark: | JSDoc @deprecated tag | | Operations | | | | Path parameters | :white_check_mark: | CLI positional args, @param JSDoc | | Query parameters | :white_check_mark: | With enum, default, format, description | | Path-level parameters | :white_check_mark: | Merged with operation-level | | Parameter style / explode | :white_check_mark: | JSDoc annotation | | JSON request bodies | :white_check_mark: | Property decomposition to CLI flags | | Primitive body types | :white_check_mark: | string, number, boolean, string[], number[] | | Array request bodies | :white_check_mark: | | | Typed response resolution | :white_check_mark: | 200, 201, 202, 204 | | Operation summary / description | :white_check_mark: | CLI descriptions, JSDoc | | deprecated operations | :white_check_mark: | [DEPRECATED] marker, JSDoc | | Tag-based command grouping | :white_check_mark: | Normalized (lowercase, split on whitespace/slashes/colons) | | Verb deduplication | :white_check_mark: | Falls back to operationId kebab-case | | -o routine-step YAML export | :white_check_mark: | Build workflows interactively | | Variant-specific flags | :white_check_mark: | Hidden by default, -V to show | | Not Yet Supported | | | | multipart/form-data bodies | :x: | Use custom commands | | Multiple content types per operation | :x: | | | Response headers | :x: | | | Cookie parameters | :x: | | | OAuth2 / OpenID Connect schemes | :x: | Use custom AuthStrategy | | Callbacks / Webhooks | :x: | | | links on responses | :x: | | | XML request/response bodies | :x: | | | Server variables / templating | :x: | |

OpenAPI 3.1

| Feature | Status | Notes | |---------|--------|-------| | Type arrays (["string", "null"]) | :white_check_mark: | Emits union type string \| null | | const values | :white_check_mark: | Literal types, @const JSDoc | | $defs (local definitions) | :white_check_mark: | Flattened into schema map | | $ref siblings (properties alongside $ref) | :white_check_mark: | Merged as intersection | | not (negation) | :white_check_mark: | Exclude<> types, @not JSDoc | | prefixItems (tuples) | :white_check_mark: | [string, number, ...] tuple types | | patternProperties | :white_check_mark: | Typed index signatures | | Widened enum (number, boolean, null values) | :white_check_mark: | Mixed literal unions | | multipleOf constraint | :white_check_mark: | JSDoc @multipleOf tag | | minProperties / maxProperties | :white_check_mark: | JSDoc annotations | | contentMediaType / contentEncoding | :x: | | | if / then / else | :x: | | | dependentRequired / dependentSchemas | :x: | | | JSON Schema $id / $anchor | :x: | | | unevaluatedProperties | :x: | |

Requirements

License

MIT