Metadata-Version: 2.4
Name: cmdop
Version: 2026.3.18
Summary: Python SDK for CMDOP agent interaction
Project-URL: Homepage, https://cmdop.com
Project-URL: Documentation, https://cmdop.com/docs/sdk/python/
Project-URL: Repository, https://github.com/commandoperator/cmdop-sdk
Project-URL: Issues, https://github.com/commandoperator/cmdop-sdk/issues
Author: CMDOP Team
License: MIT
License-File: LICENSE
Keywords: agent,automation,cmdop,terminal
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: beautifulsoup4>=4.14.3
Requires-Dist: click>=8.1.0
Requires-Dist: grpcio>=1.78.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: protobuf>=5.29.0
Requires-Dist: pydantic-settings>=2.0.0
Requires-Dist: pydantic>=2.5.0
Requires-Dist: pyte>=0.8.2
Requires-Dist: rich>=13.0.0
Requires-Dist: textual>=0.50.0
Provides-Extra: dev
Requires-Dist: grpcio-tools>=1.78.0; extra == 'dev'
Requires-Dist: mypy>=1.8.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Description-Content-Type: text/markdown

# CMDOP

![CMDOP](https://raw.githubusercontent.com/markolofsen/assets/main/libs/cmdop/cmdop.webp)

**Your OS. Online.**

Full access to your machines from anywhere. Not files — the whole system.

```
Your Code ──── Cloud Relay ──── Agent (on server)
                   │
       Outbound only, works through any NAT/firewall
```

## Install

```bash
pip install cmdop
```

## Quick Start

```python
from cmdop import AsyncCMDOPClient

async with AsyncCMDOPClient.remote(api_key="cmdop_xxx") as client:
    # Terminal
    await client.terminal.set_machine("my-server")
    output, code = await client.terminal.execute("uname -a")

    # Files
    content = await client.files.read("/etc/hostname")
    await client.files.write("/tmp/config.json", b'{"key": "value"}')

    # AI Agent with typed output
    from pydantic import BaseModel

    class Health(BaseModel):
        cpu: float
        memory: float
        issues: list[str]

    await client.agent.set_machine("my-server")
    result = await client.agent.run("Check server health", output_model=Health)
    health: Health = result.data  # Typed!

    # Skills — run predefined AI workflows
    await client.skills.set_machine("my-server")
    skills = await client.skills.list()
    result = await client.skills.run("code-review", "Review the auth module")

```

## Connection

```python
from cmdop import CMDOPClient, AsyncCMDOPClient

# Remote (via cloud relay) - works through any NAT
client = CMDOPClient.remote(api_key="cmdop_xxx")

# Local (direct IPC to running agent)
client = CMDOPClient.local()

# Async
async with AsyncCMDOPClient.remote(api_key="cmdop_xxx") as client:
    ...
```

## Documentation

| Topic | Description |
|-------|-------------|
| [Terminal](docs/terminal.md) | Execute commands, stream output, SSH sessions |
| [Auth](docs/auth.md) | Agent password authentication, session tokens |
| [Files](docs/files.md) | Read, write, list files on remote machines |
| [Agent](docs/agent.md) | AI tasks with structured typed output |
| [Skills](docs/skills.md) | Predefined AI workflows with tool access |
| [Download](docs/download.md) | Download files from URLs via remote server |
| [SDKBaseModel](docs/base_model.md) | Auto-cleaning Pydantic model for scraped data |

## Architecture

```
┌─────────────┐    gRPC/HTTP2    ┌─────────────┐    gRPC    ┌─────────┐
│   Python    │◀────────────────▶│   Cloud     │◀──────────▶│  Agent  │
│     SDK     │   Bidirectional  │   Relay     │  Outbound  │  (Go)   │
└─────────────┘                  └─────────────┘            └─────────┘
```

- Agent makes outbound connection (no port forwarding)
- SDK connects via gRPC (works through any firewall)
- All services multiplexed over single connection

## Comparison

| Feature | CMDOP | Tailscale | ngrok | SSH |
|---------|-------|-----------|-------|-----|
| Terminal streaming | gRPC | VPN + SSH | No | Yes |
| File operations | Built-in | SFTP | No | SCP |
| AI agent | Built-in | No | No | No |
| Reusable AI skills | Built-in | No | No | No |
| NAT traversal | Outbound | WireGuard | Outbound | Port forward |
| Client install | None | VPN client | None | SSH client |
| Structured output | Pydantic | No | No | No |

## Requirements

- Python 3.10+
- CMDOP agent running locally or API key for remote access

## Links

- [Examples](examples/)
- [Documentation](https://cmdop.com/docs/sdk/python)
- [Bot Documentation](https://cmdop.com/docs/sdk/python-bot)
- [Skills Catalog](https://cmdop.com/skills/)
- [Agent Download](https://cmdop.com/download)
- [GitHub](https://github.com/commandoperator/cmdop-sdk)
