Metadata-Version: 2.4
Name: plivo-test-cli
Version: 0.7.0
Summary: Agent-native developer CLI for Plivo — build, test, deploy, and debug from the terminal.
Author-email: Srinivas KS <srinivas.ks@plivo.com>, Darshan D <darshan.d@plivo.com>
License: Apache-2.0
Project-URL: Homepage, https://github.com/plivo/plivo-cli
Project-URL: Issues, https://github.com/plivo/plivo-cli/issues
Keywords: plivo,cli,agent,mcp,voice,telephony
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Communications :: Telephony
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: typer>=0.12
Requires-Dist: rich>=13.7
Requires-Dist: httpx>=0.27
Requires-Dist: plivo>=4.58
Requires-Dist: openai>=1.40
Requires-Dist: anthropic>=0.39
Requires-Dist: prompt_toolkit>=3.0
Requires-Dist: python-dotenv>=1.0
Requires-Dist: fastmcp>=0.4
Requires-Dist: pyyaml>=6.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: pytest-cov>=5.0; extra == "dev"
Requires-Dist: respx>=0.21; extra == "dev"
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Dynamic: license-file

# plivo-cli

**The agent-native developer CLI for Plivo.**

[![TestPyPI](https://img.shields.io/badge/TestPyPI-0.6.2-blue.svg)](https://test.pypi.org/project/plivo-cli/0.6.2/)
[![Python](https://img.shields.io/badge/python-%3E%3D3.11-blue.svg)](https://www.python.org/downloads/)
[![License](https://img.shields.io/badge/license-Apache_2.0-blue.svg)](LICENSE)
[![Tests](https://img.shields.io/badge/tests-377_passing-brightgreen.svg)](DOCS.md#testing)

---

## What this project is

`plivo-cli` is a single command-line tool that wraps the entire Plivo telephony API and ships an AI co-pilot inside the same binary. It's built for two kinds of operator:

- **Developers** who want to build, test, and debug Plivo apps without leaving their terminal.
- **Agents** — both the in-shell co-pilot and external agents (Claude Code, Cursor, your own MCP client) — who need a uniform, machine-readable surface to drive Plivo.

Every Plivo command is registered once in a Python decorator. From that single registration, two surfaces light up: a typer-based CLI and a FastMCP server. Same code, two doorways. An agent never has to choose between "speaking CLI" and "speaking MCP" — they're the same surface.

> A reference for every command, flag, error code, and the architecture in detail: **[DOCS.md](DOCS.md)**.

---

## Why it exists

Telephony work is one of the most agent-friendly domains there is — it's deterministic, well-typed, and the operations (place a call, list numbers, doctor a recording) are bounded. But the existing Plivo SDK is library-shaped: it assumes a human developer in an IDE, not an agent in a loop.

`plivo-cli` reshapes the same operations into an interface agents thrive on:

- **One registry, two surfaces.** Add a command once with `@command("group.verb", "summary")` and it shows up in both `plivo group verb ...` and the MCP server. No drift between surfaces ever.
- **Structured error envelopes with `retry_command`.** When a call fails, the error is a JSON envelope that includes a *ready-to-execute* shell command the agent can run to recover. The agent doesn't have to re-reason — it reads `retry_command` and runs it.
- **Co-pilot built in.** `plivo shell` is a REPL where natural-language prompts become tool calls. Multi-turn memory inside one session. The same registry, exposed to OpenAI / Azure as tools.
- **One word to start.** `plivo` (no args) detects first-run and walks you through a 30-second setup; every run afterward drops straight into the agent shell. Modeled after `claude`.
- **Self-healing setup.** Credentials are stored once in `~/.plivo-cli/.env` and picked up from any directory. Stale or empty `.env` files can't trick the CLI into the broken state.

The aim is that someone — human or agent — should be able to install one package, type one word, and start operating on real Plivo resources within a minute.

---

## How an agent should think about it

If you're an LLM agent reading this to figure out how to use `plivo-cli`, here's the mental model:

1. **Every operation is a tool with a stable name.** Tools are named `<group>_<verb>` (e.g. `app_create`, `number_assign`, `trunk_create`). The full list is in the MCP tool manifest; `plivo --help` enumerates them too.
2. **Every tool returns a JSON envelope.** On success: `{"ok": true, ...resource fields...}`. On failure: `{"ok": false, "error": "<code>", "explanation": "...", "retry_command": "...", "docs": "..."}`. Read `retry_command` to recover.
3. **You can call tools two ways.** Through the MCP server (`plivo mcp serve` — preferred for agents in Claude Code / Cursor), or through the CLI (`plivo <group> <verb>` — preferred for shell-based agents).
4. **The in-shell co-pilot has the same tool surface as you.** If a user is talking to `plivo shell`, they're driving the same registry you can see via MCP.
5. **Credentials are env-only.** Never pass `--auth-id` or similar. The CLI reads `PLIVO_AUTH_ID` and `PLIVO_AUTH_TOKEN` from environment (or from `~/.plivo-cli/.env` written by `plivo init`).

The full tool semantics — argument types, return shapes, error codes — are in [DOCS.md](DOCS.md#command-surface).

---

## The product story in one minute

```bash
# Install (one line, runs anywhere with Python 3.11+)
pip install --index-url https://test.pypi.org/simple/ \
            --extra-index-url https://pypi.org/simple/ \
            plivo-cli==0.6.2

# Start (one word — that's the whole flow)
plivo
```

First run walks the user through `plivo init` (Plivo creds → OpenAI key → confirm) and auto-launches the agent shell. Second run from any directory drops straight into the shell.

Inside the shell, the user types natural language. The co-pilot picks tools, runs them, and answers with the result. Errors render structured envelopes the agent recovers from autonomously. The shell remembers context across asks within a session.

To wire `plivo-cli` into another agent (Claude Code, Cursor, your own MCP client):

```bash
plivo mcp install --target claude-code   # prints the config block
plivo mcp serve                          # runs the MCP server on stdio
```

Now that agent has every Plivo operation — apps, numbers, calls, SMS, recordings, SIP trunks, endpoints, XML — as a tool, with the same structured-error contract.

---

## Design choices worth knowing

- **No `--json` flag.** Commands emit JSON by default. The same envelope shape goes to humans and agents.
- **No fork-exec.** The `!` raw-CLI escape inside the shell uses an in-process typer runner — never a subprocess. Credentials never leak into a child shell's environment.
- **Path-traversal blocked.** `xml init` and `endpoint browser` sanitize user-supplied paths so an agent prompt can't write outside the intended directory.
- **Tokens masked everywhere.** Banners, logs, error envelopes — all show `pk_****ab12`, never the raw token.
- **Sensitive files chmod 600.** Both `~/.plivo-cli/.env` and the rendered `endpoint browser` HTML (which embeds an SDK password) are written owner-only.

---

## What's inside

```
plivo_cli/
├── core/                # one module per command group
│   ├── account.py       (whoami)         ├── lookup.py
│   ├── app.py           ├── call.py      ├── doctor.py
│   ├── endpoint.py      ├── message.py   ├── number.py
│   ├── recording.py     ├── trunk.py     ├── xml.py
│   ├── onboarding.py    (`plivo init`)   ├── shell/
│   ├── client.py        (Plivo SDK wrapper, dotenv layers)
│   ├── commands.py      (@command decorator + REGISTRY)
│   ├── errors.py        (envelope + retry_command builders)
│   └── branding.py      (one place for visual identity)
├── cli/main.py          (typer surface — walks REGISTRY)
├── mcp/server.py        (FastMCP surface — walks REGISTRY)
└── tests/               (377 tests, mocks only, no real network)
```

Adding a new Plivo command takes one Python function + one import line. Both surfaces light up automatically. See the [dev guide in DOCS.md](DOCS.md#adding-a-new-command).

---

## Track & origins

Built at the **Plivo Hackathon 2026** by **Srinivas KS** ([srinivas.ks@plivo.com](mailto:srinivas.ks@plivo.com)) and **Darshan D** ([darshan.d@plivo.com](mailto:darshan.d@plivo.com)) — submitted to the **for-agents** track.

The track is a fit because the product *is* an agent surface: an LLM co-pilot built into the CLI, every command auto-exposed as an MCP tool, structured errors specifically shaped for autonomous recovery. The agent isn't an add-on — it's the design center.

License: Apache 2.0.

---

## Where to go next

- **[DOCS.md](DOCS.md)** — architecture, every command's flags, error envelope spec, shell internals, branding system, security model, dev guide, testing patterns, build pipeline.
- **[PLAN.md](PLAN.md)** — source-of-truth project tracker (current milestone, component checklist, what's parked vs shipped).
- **[Plivo docs](https://www.plivo.com/docs/)** — the underlying API reference.
