Metadata-Version: 2.4
Name: timeverse-printer-mcp
Version: 1.0.1
Summary: TimeVerse Printer Control MCP Server - multi-transport printer control for AI agents
Author: TimeVerse
License: MIT
Project-URL: Homepage, https://github.com/elimyliu/timeverse-printer-mcp
Project-URL: Repository, https://github.com/elimyliu/timeverse-printer-mcp
Project-URL: Documentation, https://github.com/elimyliu/timeverse-printer-mcp
Keywords: mcp,printer,ipp,escpos,zpl,printing,model-context-protocol
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Printing
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.12
Description-Content-Type: text/markdown
Requires-Dist: mcp>=1.0.0
Requires-Dist: pywin32>=306; sys_platform == "win32"
Requires-Dist: pyusb>=1.2.1
Requires-Dist: pyserial>=3.5
Requires-Dist: pyipp>=0.3.0
Requires-Dist: pysnmp>=4.4.12
Requires-Dist: zeroconf>=0.131.0
Requires-Dist: pycups>=2.0.1; sys_platform != "win32"
Requires-Dist: pypdf>=4.0.0
Requires-Dist: reportlab>=4.0.0
Requires-Dist: Pillow>=10.0.0
Requires-Dist: python-escpos>=3.0.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"

# TimeVerse Printer MCP Server

**English** | [中文](./README_zh.md)

A comprehensive Model Context Protocol (MCP) server for printer control, supporting multiple communication protocols and page description languages. Lets AI agents discover printers, print documents, query status, and manage print queues.

## Features

### 7 Transport Methods
| Transport | Port/Interface | Protocol | Use Case |
|-----------|---------------|----------|----------|
| **Win32 Spooler** | System API | pywin32 | Windows default (primary) |
| **IPP** | 631 | pyipp | Modern network printers, AirPrint |
| **Raw Socket** | 9100 | socket | HP JetDirect, fast direct print |
| **LPD/LPR** | 515 | socket | Legacy/Unix printers |
| **USB** | USB | pyusb | Thermal printers, label printers |
| **Serial** | RS-232 | pyserial | Old thermal/label printers |
| **CUPS** | System API | pycups | Linux/macOS |

### 6 Page Description Languages
PDF, PCL 5/6, ESC/POS (receipts), ZPL (labels), Plain Text, Images (PNG/JPEG/BMP)

### 18 MCP Tools
- **Discovery (3)**: `list_printers`, `discover_printers`, `get_printer_info`
- **Printing (6)**: `print_file`, `print_text`, `print_image`, `print_raw`, `print_escpos`, `print_zpl`
- **Status (2)**: `get_printer_status`, `get_printer_capabilities`
- **Queue (5)**: `get_print_jobs`, `cancel_print_job`, `cancel_all_jobs`, `pause_printer`, `resume_printer`
- **Management (2)**: `get_default_printer`, `set_default_printer`

## Installation

### Prerequisites
- Python 3.12+
- Windows (recommended for full Win32 Spooler support) or Linux/macOS (CUPS)

### Install

```bash
# Clone or copy the project
cd timeverse-printer-mcp

# Create a virtual environment
python -m venv .venv

# Activate it
# Windows:
.venv\Scripts\activate
# Linux/macOS:
source .venv/bin/activate

# Install the package
pip install -e .
```

### Optional: USB Driver (Windows)
For USB printer support on Windows, install [Zadig](https://zadig.akeo.ie/) and replace the printer's driver with `libusbK` or `WinUSB`.

## MCP Client Configuration

Add this to your MCP client config (e.g. Claude Desktop, WorkBuddy):

```json
{
  "mcpServers": {
    "timeverse-printer": {
      "command": "python",
      "args": ["-m", "timeverse_printer_mcp.server"],
      "env": {
        "TIMEVERSE_PRINTER_MCP_LOG_LEVEL": "info"
      }
    }
  }
}
```

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `TIMEVERSE_PRINTER_MCP_SCAN_SUBNET` | (none) | SNMP scan subnet, e.g. `192.168.1.0/24` |
| `TIMEVERSE_PRINTER_MCP_SCAN_TIMEOUT` | `5000` | Discovery scan timeout (ms) |
| `TIMEVERSE_PRINTER_MCP_SNMP_COMMUNITY` | `public` | SNMP community string |
| `TIMEVERSE_PRINTER_MCP_DEFAULT_TRANSPORT` | `auto` | Default transport method |
| `TIMEVERSE_PRINTER_MCP_LOG_LEVEL` | `warning` | Log level: debug, info, warning, error |

## Usage Examples

### List Installed Printers
```
Tool: list_printers(include_network=true)
```

### Discover Network Printers
```
Tool: discover_printers(method="all", subnet="192.168.1.0/24", timeout=5000)
```

### Print a PDF File
```
Tool: print_file(
  file_path="C:/Documents/report.pdf",
  printer="HP LaserJet Pro M404",
  copies=2,
  duplex="long-edge",
  color="monochrome"
)
```

### Print a Receipt (ESC/POS)
```
Tool: print_escpos(
  printer="192.168.1.100:9100",
  commands=[
    {"type": "init"},
    {"type": "align", "params": {"alignment": "center"}},
    {"type": "bold", "params": {"enable": true}},
    {"type": "font_size", "params": {"width": 2, "height": 2}},
    {"type": "text", "value": "My Store"},
    {"type": "feed", "params": {"lines": 1}},
    {"type": "align", "params": {"alignment": "left"}},
    {"type": "text", "value": "Item 1 ......... $10.00"},
    {"type": "text", "value": "Item 2 ......... $5.50"},
    {"type": "feed", "params": {"lines": 1}},
    {"type": "align", "params": {"alignment": "center"}},
    {"type": "qrcode", "value": "https://example.com", "params": {"size": 6}},
    {"type": "cut", "params": {"mode": "full"}}
  ]
)
```

### Print a Label (ZPL)
```
Tool: print_zpl(
  printer="192.168.1.200:9100",
  zpl="^XA^FO20,20^A0N,50,50^FDHello World^FS^FO20,80^BCN,100,Y,N,N^FD12345678^FS^XZ",
  labels=3
)
```

### Query Printer Status
```
Tool: get_printer_status(printer="HP LaserJet Pro M404", method="auto")
```

### Manage Print Queue
```
Tool: get_print_jobs(printer="HP LaserJet Pro M404")
Tool: cancel_print_job(printer="HP LaserJet Pro M404", job_id=42)
Tool: cancel_all_jobs(printer="HP LaserJet Pro M404")
Tool: pause_printer(printer="HP LaserJet Pro M404")
Tool: resume_printer(printer="HP LaserJet Pro M404")
```

## Printer Identifier Formats

The `printer` parameter accepts multiple formats:

| Format | Example | Resolved Transport |
|--------|---------|--------------------|
| System printer name | `HP LaserJet Pro M404` | Win32 Spooler / CUPS |
| IP address | `192.168.1.50` | Auto (IPP or Raw) |
| IP:port | `192.168.1.50:9100` | Raw Socket |
| IPP URL | `ipp://192.168.1.50/ipp/print` | IPP |
| USB VID:PID | `usb:04b8:0202` | USB |
| Serial port | `COM3` or `/dev/ttyUSB0` | Serial |

## Architecture

```
MCP Tool Layer (18 tools)
    |
Transport Router (auto-selects best transport)
    |
Transport Layer (Win32 Spooler / IPP / Raw / LPD / USB / Serial / CUPS)
    |
Document Layer (PDF / Image / Text / ESC/POS / ZPL / PCL)
    |
Discovery Layer (mDNS / SNMP / Win32 Enum / USB Scan)
```

## Dependencies

### Core
- `mcp` — Official MCP Python SDK (FastMCP)
- `pywin32` — Win32 Print Spooler API (Windows only)
- `pyipp` — IPP client
- `pyusb` — USB communication
- `pyserial` — Serial port communication
- `pysnmp` — SNMP status queries
- `zeroconf` — mDNS/Bonjour discovery
- `pycups` — CUPS API (Linux/macOS only)

### Document Processing
- `pypdf` — PDF reading
- `reportlab` — PDF generation
- `Pillow` — Image processing
- `python-escpos` — ESC/POS command library

## Project Structure

```
timeverse-printer-mcp/
├── src/timeverse_printer_mcp/
│   ├── server.py              # MCP server entry point
│   ├── tools/                 # 18 MCP tools
│   │   ├── discovery.py       # list_printers, discover_printers, get_printer_info
│   │   ├── printing.py        # print_file, print_text, print_image, print_raw, print_escpos, print_zpl
│   │   ├── status.py          # get_printer_status, get_printer_capabilities
│   │   ├── queue.py           # get_print_jobs, cancel_print_job, cancel_all_jobs, pause_printer, resume_printer
│   │   └── management.py      # get_default_printer, set_default_printer
│   ├── transports/            # 7 transport implementations + router
│   │   ├── base.py            # Abstract transport base class
│   │   ├── router.py          # Transport auto-router
│   │   ├── win32_spooler.py   # Windows Print Spooler (pywin32)
│   │   ├── ipp_transport.py   # IPP (pyipp)
│   │   ├── raw_socket.py      # Raw Socket (port 9100)
│   │   ├── lpd.py             # LPD/LPR (port 515)
│   │   ├── usb_transport.py   # USB (pyusb)
│   │   ├── serial_transport.py# Serial (pyserial)
│   │   ├── cups_transport.py  # CUPS (pycups, Linux/macOS)
│   │   └── snmp_status.py     # SNMP status query (pysnmp)
│   ├── documents/             # Document handlers
│   │   ├── pdf_handler.py     # PDF processing
│   │   ├── image_handler.py   # Image processing
│   │   ├── text_handler.py    # Text formatting
│   │   ├── escpos_builder.py  # ESC/POS command builder
│   │   ├── zpl_builder.py     # ZPL command builder
│   │   └── pcl_builder.py     # PCL command builder
│   ├── discovery/             # Printer discovery
│   │   ├── mdns_discovery.py  # mDNS/Bonjour discovery
│   │   ├── snmp_scan.py       # SNMP subnet scanner
│   │   ├── win32_enum.py      # Windows printer enumeration
│   │   └── usb_scan.py        # USB device scanner
│   └── utils/                 # Shared utilities
│       ├── types.py           # Data models (PrinterTarget, PrintResult, etc.)
│       ├── errors.py          # Error handling
│       ├── logger.py          # Logging
│       └── platform.py        # Platform detection
├── tests/
├── pyproject.toml
└── README.md
```

## License

MIT
