Command-line interface for Vapi voice AI — for humans and AI agents. Installs the `bvapi` binary.
This CLI-to-MCP wrapper exposes 30 tools with consistent but minimal documentation. All tools have descriptions (10 - 50 chars, below the 50 - 200 char baseline for LLM optimization) and input schemas with type definitions. However, parameter descriptions are sparse or missing entirely. Most tools accept generic 'file' or 'id' parameters with minimal context. No output schemas are documented. Error handling is absent from tool definitions. The server is designed as a thin CLI wrapper, not an LLM-optimized agent interface, tool names like 'assistant list' use space-separated verbs rather than snake_case, and parameter names like 'createdAtGt' use camelCase inconsistently. No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk levels (READ_ONLY, WRITE, DESTRUCTIVE). Composition is repetitive: 6 resource types × 5 CRUD operations = 30 tools with nearly identical patterns, no batch operations, and no chaining support.
Create assistant (POST /assistant). Body via -f <file|->
Delete assistant by id (DELETE /assistant/{id})
Fetch assistant by id (GET /assistant/{id})
List assistants (GET /assistant). Returns an array.
Patch assistant by id (PATCH /assistant/{id}). Body via -f <file|->
Save a Vapi private API key to ~/.config/bvapi/credentials.json
Remove the stored credentials file (does not affect VAPI_API_KEY env)
Show current credential source and verify the key works
Tool names use space-separated verbs ('assistant list') instead of snake_case ('list_assistants'). LLMs parse verb_noun naming more reliably for intent inference.
Descriptions are 10 - 50 characters, below the 50 - 200 char baseline for LLM optimization. E.g., 'List assistants (GET /assistant). Returns an array.' lacks context on when to use this vs other discovery tools, what fields are returned, or pagination behavior.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 37 | 2026-07-28+ | v2 |
Fetch call by id (GET /call/{id})
List calls (GET /call). Returns an array.
Upload a file (POST /file, multipart). Returns the File with its id.
Delete file by id (DELETE /file/{id})
Fetch file by id (GET /file/{id})
List files (GET /file). Returns an array.
Patch file by id (PATCH /file/{id}). Body via -f <file|->
Create phone-number (POST /phone-number). Body via -f <file|->
Delete phone-number by id (DELETE /phone-number/{id})
Fetch phone-number by id (GET /phone-number/{id})
List phone-numbers (GET /phone-number). Returns an array.
Patch phone-number by id (PATCH /phone-number/{id}). Body via -f <file|->
Create squad (POST /squad). Body via -f <file|->
Delete squad by id (DELETE /squad/{id})
Fetch squad by id (GET /squad/{id})
List squads (GET /squad). Returns an array.
Patch squad by id (PATCH /squad/{id}). Body via -f <file|->
Create tool (POST /tool). Body via -f <file|->
Delete tool by id (DELETE /tool/{id})
Fetch tool by id (GET /tool/{id})
List tools (GET /tool). Returns an array.
Patch tool by id (PATCH /tool/{id}). Body via -f <file|->
Parameter descriptions are missing or trivial. E.g., 'createdAtGt' has description 'Created after (ISO 8601, exclusive)' but no guidance on format, timezone handling, or when to use this filter vs createdAtGe. LLMs cannot infer parameter semantics from names alone.
No output schemas documented. Tools return 'an array' or 'the File with its id' but LLMs cannot plan downstream calls without knowing field names, types, and structure. E.g., does 'assistant list' return [{ id, name, ... }] or { assistants: [...], total: N }?
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite explicit risk levels (READ_ONLY, WRITE, DESTRUCTIVE). Agents cannot distinguish safe retries from irreversible operations without these hints.