> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mirage.strukto.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Streaming and stdin

> Stream shell output and send input over HTTP.

Use [Run a shell line](https://docs.mirage.strukto.ai/api/operations/shell/run-a-shell-line.md) with an
existing workspace. Set `MIRAGE_AUTH_TOKEN` to your server's configured token, or
omit the authorization header in local mode without a token.

## Stream command output

The server supports streaming shell output. Set `stream=true` and use
`curl --no-buffer` to display the response as it arrives:

```bash theme={null}
curl --no-buffer --request POST \
  --url 'http://127.0.0.1:8765/v1/workspaces/demo/shell?stream=true' \
  --header "Authorization: Bearer $MIRAGE_AUTH_TOKEN" \
  --header 'Content-Type: application/json' \
  --data '{"command":"echo hello"}'
```

The response has content type `application/x-ndjson`. Each line is a JSON record.
Output records identify `stdout` or `stderr` and carry base64-encoded `data`:

```json theme={null}
{"stream":"stdout","data":"aGVsbG8K"}
{"status":"done","result":{"kind":"io","exit_code":0,"stdout":"","stderr":"","refusal":null,"line_id":"line_019a5e2c-7b41-7c3e-9f20-4d8e1a6b5c37"},"error":null}
```

Decode each output record's `data` to display the bytes. The output example decodes
to `hello\n` on stdout. Records labeled `stderr` carry stderr bytes in the same format.
Read through the final record:

| Field | Meaning |
| - | - |
| `status` | `done`, `failed`, or `canceled`. |
| `result` | The shell result when available. Check `exit_code` to determine whether the command succeeded. |
| `error` | A request or execution error when available. |

A stream without a final status record was interrupted. HTTP `200` alone does not
mean the shell command succeeded. Closing the request cancels the running line.
Streaming cannot be combined with `explain`.

The server includes `line_id` in the result. Use it to [get the line record](https://docs.mirage.strukto.ai/api/operations/lines/get-a-line.md).

## Send stdin

The server accepts `multipart/form-data` with a JSON `request` part followed by
a `stdin` part. It accepts up to 64 MiB of input and supplies the bytes to the command
as they arrive.

```bash cURL theme={null}
printf 'b\na\n' | curl 'http://127.0.0.1:8765/v1/workspaces/demo/shell' \
  --header "Authorization: Bearer $MIRAGE_AUTH_TOKEN" \
  --form 'request={"command":"sort"};type=application/json' \
  --form 'stdin=@-'
```

```python Python theme={null}
import json
import os

import httpx

headers = {"Authorization": f"Bearer {os.environ['MIRAGE_AUTH_TOKEN']}"}
with httpx.Client(base_url="http://127.0.0.1:8765/v1", headers=headers) as client:
    response = client.post("/workspaces/demo/shell", files={
        "request": (None, json.dumps({"command": "sort"}), "application/json"),
        "stdin": ("stdin", b"b\na\n"),
    })
    response.raise_for_status()
    print(response.json()["stdout"], end="")
```

```typescript TypeScript theme={null}
const form = new FormData()
form.append('request', new Blob([JSON.stringify({ command: 'sort' })], { type: 'application/json' }))
form.append('stdin', new Blob(['b\na\n']))

const response = await fetch('http://127.0.0.1:8765/v1/workspaces/demo/shell', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.MIRAGE_AUTH_TOKEN}` },
  body: form,
})
if (!response.ok) throw new Error(`HTTP ${response.status}`)
const result = await response.json()
process.stdout.write(result.stdout)
```

The command sorts the input and returns `a\nb\n` in `stdout`.

See [Run a shell line](https://docs.mirage.strukto.ai/api/operations/shell/run-a-shell-line.md) for the complete
request fields and response schemas.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.