Skip to content
julien-mPublic

About

Generate standardized, agent-ready CLIs from REST APIs, with portable AgentSkill instructions.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

api2cli

Turn any REST API into a standardized, agent-ready CLI in minutes.

One CLI pattern. Every API. Any AI agent can use it.

Based on Melvynx/api2cli, extended with OS keychain token storage and modular AgentSkill instructions.

The Problem

There are 10,000+ SaaS products with REST APIs. AI agents can only interact with a tiny fraction of them because:

  • No CLI exists for most APIs (Typefully, Dub, Mercury, Front, etc.)
  • No MCP server for 97% of APIs
  • No standardization across the CLIs that do exist
  • No agent skills that work across platforms

The Solution

api2cli generates standardized CLIs from any API. Every generated CLI follows the exact same patterns, so an agent that learns one CLI knows them all.

api2cli create <app> → scaffold + build + link → <app>-cli ready to use

Quick Start

# Install
bun install -g api2cli

# Create a CLI for any API
api2cli create typefully \
  --base-url https://api.typefully.com \
  --auth-type bearer

# Build and link to PATH
api2cli bundle typefully
api2cli link typefully

# Use it
typefully-cli auth set "typ_xxx"
typefully-cli drafts list
typefully-cli drafts create --text "Hello world" --platform x

How It Works

1. Create a CLI scaffold

api2cli create <app> [options]
Flag Description Default
--base-url <url> API base URL https://api.example.com
--auth-type <type> bearer, api-key, basic, custom bearer
--auth-header <name> Auth header name Authorization
--docs <url> API docs URL (for agent-driven generation) -
--openapi <url> OpenAPI/Swagger spec URL -
--force Overwrite existing CLI false

This creates ~/.cli/<app>-cli/ with:

  • HTTP client with retry/backoff
  • Auth module (tokens stored in OS Keychain via creds)
  • Multi-format output (text, JSON, CSV, YAML)
  • Example resource file to copy
  • Skill instruction fragments in .api2cli/skill/instruction.md
  • Canonical AgentSkill source in .agent-sync/skills/<app>-cli/

2. Add resources

Create a file in ~/.cli/<app>-cli/src/resources/ for each API resource:

import { Command } from "commander";
import { client } from "../lib/client.js";
import { output } from "../lib/output.js";
import { handleError } from "../lib/errors.js";

export const draftsResource = new Command("drafts")
  .description("Manage drafts");

draftsResource
  .command("list")
  .description("List all drafts")
  .option("--limit <n>", "Max results", "20")
  .option("--json", "Output as JSON")
  .action(async (opts) => {
    try {
      const data = await client.get("/drafts", { limit: opts.limit });
      output(data, { json: opts.json });
    } catch (err) {
      handleError(err, opts.json);
    }
  });

Register it in src/index.ts:

import { draftsResource } from "./resources/drafts.js";
program.addCommand(draftsResource);

3. Build and link

api2cli bundle <app>        # Build the CLI
api2cli link <app>          # Add to PATH and link the skill

4. Use it

<app>-cli auth set "your-token"
<app>-cli auth test
<app>-cli <resource> list --json

All Commands

CLI Manager (api2cli)

Command Description
api2cli create <app> Generate a new CLI from API docs
api2cli bundle <app> [--compile] [--all] Build a CLI from source (--compile for standalone binary)
api2cli link <app> [--all] Add a CLI to PATH and link its skill (via cc-hub when installed)
api2cli unlink <app> Remove from PATH
api2cli list [--json] List all installed CLIs
api2cli tokens [--show] List all configured tokens (masked)
api2cli remove <app> [--keep-token] Remove a CLI entirely
api2cli doctor Check system requirements
api2cli install <source> [--force] Install from a GitHub repo
api2cli update <app> Re-sync with API changes (agent-driven)

Generated CLIs (<app>-cli)

Every generated CLI follows these exact conventions:

# Authentication (token stored in OS Keychain via creds — no plaintext)
<app>-cli auth set              # Interactive masked prompt (or pipe a value)
<app>-cli auth show             # Display masked token
<app>-cli auth show --raw      # Display full token
<app>-cli auth test            # Verify token works
<app>-cli auth remove          # Delete token

# Resources (CRUD)
<app>-cli <resource> list      # GET /resource
<app>-cli <resource> get <id>  # GET /resource/:id
<app>-cli <resource> create    # POST /resource
<app>-cli <resource> update <id>  # PATCH /resource/:id
<app>-cli <resource> delete <id>  # DELETE /resource/:id

# Global flags
--json                         # JSON output {ok, data, meta}
--format <text|json|csv|yaml>  # Output format
--verbose                      # Debug logging
--no-color                     # Disable colors
--no-header                    # Omit table headers (for piping)

# Deep help at every level
<app>-cli --help
<app>-cli <resource> --help
<app>-cli <resource> <action> --help

Output Formats

Text (default): Pretty tables for humans

id                    status    created_at
────────────────────  ────────  ──────────
abc123                draft     2026-03-07
def456                published 2026-03-06

JSON (--json): Structured envelope for agents

{
  "ok": true,
  "data": [...],
  "meta": { "total": 42 }
}

CSV (--format csv): For spreadsheets and piping

YAML (--format yaml): For config files

Sharing CLIs

Generated CLIs live entirely on your machine — there is no public registry. To share one, push it to a GitHub repo and have others install it directly:

api2cli install owner/repo
api2cli install https://github.com/owner/repo

Agent Integration

AgentSkills (Claude Code, Cursor, Gemini CLI, etc.)

Install from .agent-sync/skills/api2cli/SKILL.md, which follows the AgentSkills open standard. With cc-hub:

cc-hub skill link .agent-sync/skills/api2cli --scope global --targets all --name api2cli

Without cc-hub, symlink the folder into your agent's skills directory (for example ln -s "$PWD/.agent-sync/skills/api2cli" ~/.claude/skills/api2cli).

cc-hub is optional: when it is not on your PATH, api2cli link <app> symlinks the generated skill directly into ~/.claude/skills and ~/.agents/skills.

Once installed, just tell your agent:

"Create a CLI for the Typefully API"

The agent reads the skill, discovers the API, generates resources, builds, and links -- all automatically.

Generated CLI skills are compiled artifacts: write project-specific agent instructions in ~/.cli/<app>-cli/.api2cli/skill/*.md. api2cli bundle <app> and api2cli link <app> inject those fragments into .agent-sync/skills/<app>-cli/SKILL.md.

Supported Agents

Works with any tool that supports AgentSkills: Claude Code, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenClaw, Goose, OpenHands, Junie, Amp, OpenCode, Letta, Firebender, Mux, Autohand

Project Structure

api2cli/
├── packages/
│   ├── cli/              # api2cli manager (create, bundle, link...)
│   └── template/         # CLI scaffold (gets cloned per API)
├── .agent-sync/
│   └── skills/
│       └── api2cli/      # AgentSkills SKILL.md
├── biome.json            # Linter + formatter
├── tsconfig.base.json    # Shared TypeScript config
└── TODO.md               # Roadmap

Tech Stack

Token Storage

Tokens for every generated CLI are stored in the OS Keychain via the creds CLI. No plaintext files.

The keychain entry defaults to global/dev/<app> (overridable with --creds-entry at create time) and is recorded in the generated CLI's package.json under api2cli.credsEntry.

api2cli tokens              # List entries for installed CLIs (masked)
api2cli tokens --show       # Show full tokens
creds rm global/dev/<app>   # Manually remove a token

api2cli doctor checks that creds is available.

License

MIT — see LICENSE. Original project by Melvynx.

About

Generate standardized, agent-ready CLIs from REST APIs, with portable AgentSkill instructions.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages