A command-line client for the VibeCodingList agent API (/api/v1). Search
listings, submit your own, and read or write feedback — from a shell or from an
agent.
Zero runtime dependencies. Node 20 or newer; everything it uses (fetch,
node:util's parseArgs, node:crypto) ships with Node.
npm install -g @vcl-labs/agent-cli
# or, without installing
npx @vcl-labs/agent-cli whoamiCreate a key at https://vibecodinglist.com/me/developer. Keys start with
vcl_sk_ and carry explicit scopes — projects:read, projects:write,
feedback:read, feedback:write, feedback:reply — with no implication
between them. A command fails with exit code 3 if your key lacks the scope it
needs.
export VCL_API_KEY=vcl_sk_your_key_here
vcl whoami--api-key <key> overrides the environment variable for a single command.
# Who does this key act as, and what can it do?
vcl whoami
# Search public, approved listings
vcl projects search "developer tools" --limit 10 --genre Productivity
# Your own listings, including pending and rejected ones
vcl projects list --mine --limit 20
# Submit the project in the current directory
vcl projects submit --from . --thumbnail ./cover.png
# Update the name and description of listing 812 from the current directory
vcl projects update 812 --from .
# Read the feedback on a project
vcl feedback list --project 30
# Leave feedback on someone else's project
vcl feedback create 30 --body-file feedback.md
# Reply to feedback left on your own project
vcl feedback reply 76 --body-file reply.mdsubmit and update build the request from what is genuinely in the
directory:
| Field | Where it comes from |
|---|---|
name |
package.json name (scope stripped, dashes to spaces, title-cased), else the directory name |
description |
package.json description, else the first real paragraph of README.md (headings, badges and bullet lists are skipped) — at least 10 characters |
url |
package.json homepage, else repository normalised to an https URL |
thumbnail |
Nothing in a repository is reliably a cover image — pass --thumbnail |
Before sending, the CLI prints what it found, where each value came from, and what will be posted. If a required field is missing it exits 2 and names the field rather than sending a request that would be rejected.
update never sends url: the API rejects URL changes with
409 URL_CHANGE_NOT_SUPPORTED. To point a listing at a different site, submit
a new project.
Either a public image URL, or a path to a local image file. A local file is
uploaded through POST /api/v1/uploads first and the hosted URL it returns is
used — which is the safer option, because a remote URL VCL cannot fetch creates
a listing with no cover image, and a listing with no cover image cannot be
approved.
Uploads accept png, jpeg, webp and gif, up to 5 MB, decided by the file's bytes rather than its name.
vcl projects submit creates the listing approved: false, isPending: true
and queues it for review. Nothing about a successful submit means it is live.
Poll vcl projects list --mine and watch the status column.
submit, update, feedback create and feedback reply all create public
content. Each prints a preview to stderr and asks before sending. --yes skips
the prompt. When stdin is not a TTY and --yes was not passed, the command
refuses with exit code 2 rather than hanging or guessing.
Every write generates a fresh Idempotency-Key. If a write fails in a way that
leaves you unsure whether it landed (a timeout, a dropped connection), retry it
with the same key:
vcl feedback create 30 --body-file feedback.md --idempotency-key 7f1c2a64-4d3b-9e77-0001Reusing a key for a different request is rejected by the server with
422 IDEMPOTENCY_KEY_REUSE. Keys are remembered for 24 hours.
Prints the raw API response to stdout and nothing else — no banners, no
progress text, no colour. Diagnostics, previews, prompts and errors always go
to stderr, so vcl projects search notes --json | jq . is safe.
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Unexpected or runtime error — network failure, non-JSON response, 5xx, 429, 413, or a declined confirmation prompt |
| 2 | Usage error — bad flags, missing arguments, a required field --from could not find, or a non-TTY without --yes |
| 3 | Auth error — HTTP 401 or 403, or no API key configured |
| 4 | Not found — HTTP 404 |
| 5 | Conflict — HTTP 409 (duplicate submission, duplicate feedback, rejected URL change) |
| 6 | Rejected by server validation — HTTP 400 or 422 |
Errors print the server's own message, and its code when it sent one. The
authentication, scope and rate-limit layers return a message with no code, so a
missing code is normal and not a sign of anything wrong.
| Variable | Purpose |
|---|---|
VCL_API_KEY |
Your vcl_sk_ key |
VCL_API_URL |
Base URL, default https://vibecodinglist.com. Set it to e.g. http://localhost:5000 to work against a local server; /api/v1 is appended for you |
The API this wraps is documented at /openapi.json and /auth.md on the same
host, both public and needing no key.