Metadata-Version: 2.5
Name: carrot-mcp-io
Version: 1.0.1
Summary: Carrot MCP IO Server - serial, TCP, UDP
Requires-Python: >=3.12
Requires-Dist: carrot-io[all]>=1.7.0
Requires-Dist: fastmcp>=0.1.0
Description-Content-Type: text/markdown

# carrot-mcp-io

Carrot MCP IO Server - High-performance async serial, TCP, and UDP transport server for hardware and network communication, powered by the `carrot-io` engine.

## Tools

| Tool | Description |
|------|-------------|
| `version` | Get server version and carrot-io engine info |
| `list_transports` | List available transport types and system serial ports |
| `open` | Open a physical serial or network connection (serial, tcp, udp) |
| `close` | Close an open connection |
| `read` | Read data with physical framing options (default available, `until` delimiter, `exact` fixed-length) |
| `recv` | Non-blocking read directly from buffer |
| `write` | Send raw bytes (hex or ascii with escape support) |
| `query` | Atomic Request-Response (write command, optional delay, read response until delimiter or timeout) |
| `script` | Execute a sequence of I/O operations (write/read/query/wait/flush) |
| `history` | Get structured TX/RX communication and timing history |

## Transports

### Serial
```json
{
  "open": {
    "port": "COM3",
    "transport": "serial",
    "baudrate": 115200
  }
}
```

### TCP
```json
{
  "open": {
    "port": "mydevice",
    "transport": "tcp",
    "host": "192.168.1.100",
    "net_port": 5000
  }
}
```

### UDP
```json
{
  "open": {
    "port": "sensor",
    "transport": "udp",
    "host": "192.168.1.200",
    "net_port": 8888
  }
}
```

## Physical Stream Framing (Delimiter & Fixed Length)

In real-world embedded/hardware communication, raw stream bytes require clear framing boundaries:

1. **Delimiter Truncation (`until`)**: Reads until a line break or delimiter string arrives (e.g. `\n`, `\r\n` for SCPI instruments or AT commands).
   ```json
   {
     "read": {
       "port": "COM3",
       "until": "\n",
       "fmt": "ascii"
     }
   }
   ```
2. **Fixed Length (`exact=True`)**: Waits until exactly `size` bytes arrive from the hardware before returning (for fixed sensor telemetry blocks).
   ```json
   {
     "read": {
       "port": "COM3",
       "size": 32,
       "exact": true,
       "fmt": "hex"
     }
   }
   ```
3. **Atomic Request-Response (`query`)**: Writes command, waits optional physical `delay` seconds, and reads response:
   ```json
   {
     "query": {
       "port": "COM3",
       "ascii": "*IDN?\n",
       "until": "\n",
       "fmt": "ascii"
     }
   }
   ```

## Buffer & Concurrency Behavior

- Powered by `carrot-io`'s pure async `FifoBuffer` ring buffer, zero-copy reads, and hot-path memory logging.
- Concurrency-safe: non-blocking coroutines with read/write locks, no background thread polling or GIL lock contention.
- Full process lifecycle safety: automatic cleanup on server termination and `atexit` fallback to prevent OS COM port deadlocks.

## Return Format

All tools return a dict with `{"status": "ok"|"error", ...}`.

- `read`/`recv`/`query` return `data` in the specified format (default `"hex"`, uppercase e.g. `"48656C6C6F"`)
- `read`/`recv`/`query` with `fmt="ascii"` return decoded string (e.g. `"Hello\nWorld"`)
- `write`/`query` support `hex` or `ascii` input, ascii supports escape sequences (`\n`, `\x00`, etc.)
- `script` executes a sequence of operations and returns a list of step results

### Script Example

```json
[
  {"op": "write", "ascii": "AT+RST\r\n"},
  {"op": "wait", "ms": 50},
  {"op": "read", "until": "\n", "expect": "ready\r\n", "fmt": "ascii"},
  {"op": "query", "ascii": "AT+CSQ\r\n", "until": "\n", "fmt": "ascii"}
]
```

### Script Return Format

Each step result contains:
- `op`: Operation type (`"write"` | `"read"` | `"query"` | `"wait"` | `"flush"`)
- `step`: Step index (0-based)
- `status`: `"ok"` or `"error"`

Additional fields by op:
- `write`: `{bytes_written}`
- `read`/`query`: `{data, length}` + `{matched, expected}` if `expect` is provided
- `wait`: `{ms}`
- On error: `{message}`
