Skip to main content
ClaudeWave
Skill443 repo starsupdated 3mo ago

api2cli

api2cli generates a working Node.js CLI tool from any API by discovering endpoints through documentation parsing, active probing, or peek-api captures, then wraps it as a Claude Code skill. Use this when you need to expose an API as a command-line interface, create an agent-ready tool from API documentation, or scaffold a dual-mode CLI that supports both human and Claude interaction patterns.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/alexknowshtml/api2cli /tmp/api2cli && cp -r /tmp/api2cli/skill ~/.claude/skills/api2cli
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# api2cli

Generate a working Node.js CLI from any API, then wrap it in a Claude Code skill. Discovers endpoints, scaffolds a dual-mode Commander.js CLI with a full-featured API client, and creates a skill folder so Claude knows how to use it.

## Workflow

1. **Identify the API** -- user provides a docs URL, a live API base URL, or a peek-api capture
2. **Discover endpoints** -- parse docs, probe the API, or read a peek-api catalog
3. **Build endpoint catalog** -- normalize all discovered endpoints into a standard format
4. **Generate CLI** -- scaffold Commander.js CLI from the catalog
5. **User chooses destination** -- scaffold into current project or create standalone project
6. **Generate skill** -- create a SKILL.md that teaches Claude how to use the generated CLI

## Step 1: Identify the API

Ask the user:
- "What API do you want to wrap? Share a docs URL, a base URL, or point me at a peek-api capture."

Determine which discovery paths to use based on what they provide:

| Input | Discovery Path |
|-------|---------------|
| Docs URL (e.g., `https://docs.stripe.com/api`) | Docs parsing + active probing |
| Base URL (e.g., `https://api.example.com/v1`) | Active probing |
| peek-api capture dir (e.g., `./peek-api-linkedin/`) | Read existing catalog |
| Live website URL | Suggest running peek-api first, then active probing |

Also ask:
- "What auth does this API use?" (API key, Bearer token, cookies, OAuth, none)
- "Do you want this CLI in your current project or as a standalone project?"

## Step 2: Discover Endpoints

Use all applicable discovery paths. Combine results into a single catalog.

### Path A: Docs Parsing

1. Fetch the docs URL with WebFetch
2. Extract endpoint information: method, path, description, parameters, request/response examples
3. Look for pagination patterns, auth requirements, rate limit info
4. Follow links to sub-pages for individual endpoint docs if the main page is an index

### Path B: Active Probing

1. Check well-known paths for API specs:
   - `/.well-known/openapi.json`, `/.well-known/openapi.yaml`
   - `/openapi.json`, `/openapi.yaml`, `/swagger.json`, `/swagger.yaml`
   - `/api-docs`, `/docs`, `/api/docs`
   - `/graphql` (with introspection query)
2. Try `OPTIONS` on the base URL and common resource paths
3. Probe common REST patterns: `/api/v1/`, `/api/v2/`, `/v1/`, `/v2/`
4. For each discovered resource, try standard CRUD: `GET /resources`, `GET /resources/:id`, `POST /resources`, etc.
5. Parse response shapes to understand data models
6. Check response headers for rate limit info (`X-RateLimit-*`, `Retry-After`)
7. Check for pagination patterns in responses (`next`, `cursor`, `page`, `offset`)

See `references/discovery-strategies.md` for detailed probing patterns.

### Path C: peek-api Capture

1. Read the capture directory: `endpoints.json`, `auth.json`, `CAPTURE.md`
2. Parse endpoints into the standard catalog format
3. Extract auth headers and cookies from `auth.json`

If peek-api is not installed or no capture exists, tell the user:
```
To capture endpoints from a live site, install peek-api:
  git clone https://github.com/alexknowshtml/peek-api
  cd peek-api && npm install
  node bin/cli.js https://example.com
```

## Step 3: Build Endpoint Catalog

Normalize all discovered endpoints into this format:

```typescript
interface EndpointCatalog {
  service: string;           // e.g., "stripe", "nexudus"
  baseUrl: string;
  auth: {
    type: 'api-key' | 'bearer' | 'cookies' | 'oauth' | 'none';
    headerName?: string;     // e.g., "Authorization", "X-API-Key"
    envVar: string;          // e.g., "STRIPE_API_KEY"
  };
  pagination?: {
    style: 'cursor' | 'offset' | 'page' | 'link-header';
    paramName: string;       // e.g., "starting_after", "offset", "page"
    responseField: string;   // e.g., "has_more", "next", "next_page_url"
  };
  rateLimit?: {
    requests: number;
    window: string;          // e.g., "1m", "1h"
  };
  resources: ResourceGroup[];
}

interface ResourceGroup {
  name: string;              // e.g., "customers", "invoices"
  description: string;
  endpoints: Endpoint[];
}

interface Endpoint {
  method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
  path: string;              // e.g., "/v1/customers/:id"
  description: string;
  parameters: Parameter[];
  requestBody?: object;      // JSON schema or example
  responseExample?: object;
}

interface Parameter {
  name: string;
  in: 'path' | 'query' | 'header';
  required: boolean;
  type: string;
  description: string;
}
```

Present the catalog to the user for review before generating:
```
Found 24 endpoints across 5 resources:
  customers (6 endpoints): list, get, create, update, delete, search
  invoices (5 endpoints): list, get, create, send, void
  ...
Ready to generate the CLI?
```

## Step 4: Generate CLI

Generate a dual-mode CLI using Commander.js. The CLI auto-detects human vs agent output via `process.stdout.isTTY`.

### File Structure

**In-project scaffold:**
```
scripts/
  {service}.ts                    # Entry point with shebang
  {service}/
    lib/
      client.ts                   # API client (auth, pagination, retry, caching)
      envelope.ts                 # Agent JSON envelope helpers
    commands/
      {resource}.ts               # One file per resource group
```

**Standalone project:**
```
{service}-cli/
  package.json
  tsconfig.json
  bin/
    {service}.ts                  # Entry point with shebang
  src/
    lib/
      client.ts
      envelope.ts
    commands/
      {resource}.ts
```

### Code Generation Patterns

See these references for the patterns to apply during generation:

- `references/api-client-template.md` -- API client class with pagination, retry, rate limiting, caching
- `references/agent-first-patterns.md` -- JSON envelope, HATEOAS next_actions, context-safe output, error fix suggestions
- `references/commander-patterns.md` -- Commander.js subcommands, global options, interactive prompts, colored output

### Key Generat