> ## 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.

# Server

> The Mirage server in Python, a FastAPI app that holds workspaces and serves HTTP, MCP, RPC and SSH.

The Mirage server is a FastAPI app. It holds workspaces and serves them over the [HTTP](/home/access/http) routes, [MCP](/home/access/mcp) and [RPC](/home/access/rpc), and over [SSH](/home/access/ssh) when `ssh_port` is set. The TypeScript server speaks the same protocol, so a client of one works against the other.

## Install

<CodeGroup>
  ```bash pip theme={null}
  pip install mirage-ai
  ```

  ```bash with SSH theme={null}
  pip install 'mirage-ai[ssh]'
  ```
</CodeGroup>

The `ssh` extra adds [asyncssh](https://asyncssh.readthedocs.io), needed only for the SSH server.

## Run it

`build_app` returns the app. Run it with any ASGI server; it serves until you stop it.

```python theme={null}
import uvicorn

from mirage.server.app import build_app

app = build_app()
uvicorn.run(app, host="127.0.0.1", port=8765)
```

| Argument | Default | Meaning |
| - | - | - |
| `auth_config` | from `MIRAGE_AUTH_MODE` | Token or JWT [auth](/home/access/http#auth). |
| `allowed_hosts` | `MIRAGE_ALLOWED_HOSTS`, else loopback | `Host` names the app answers. `["*"]` turns the check off, safe only behind a trusted proxy. |
| `ssh_config` | from the `ssh_*` settings | The SSH server, opened with the app; off unless a port is set. |
| `snapshot_store` | `None` | An `S3Config`: the store a snapshot request may name a key in. Without one, a snapshot only goes back to the caller; the server never writes one to its own disk. |
| `state_root` | under `$MIRAGE_HOME` | Where live state is kept. |
| `on_idle_exit` | `None` | Called when the last workspace has been gone `idle_grace_seconds` (30), or on `POST /v1/shutdown`. `None` keeps serving. |
| `pid_file` | `None` | A file that holds the process id while the app runs. |

## Started by the CLI

The CLI runs the same app as a daemon, `mirage.server.daemon:app`, on `127.0.0.1:8765` in local auth mode, logging to `~/.mirage/daemon.log`. That entry adds the two daemon behaviors: it writes `$MIRAGE_HOME/daemon.pid` for `mirage daemon stop` and `kill`, and exits 30 seconds (`MIRAGE_IDLE_GRACE_SECONDS`) after its last workspace is deleted. Its settings are on the [CLI page](/home/access/cli#config).

## What is particular to this server

The protocol is the same on both servers. These are the differences in how this one serves it:

* **SSH output streams.** A line's output over SSH is sent as the line produces it. The TypeScript server sends it when the line finishes.
* **Legacy `scp -O`.** The SCP protocol is served, as well as SFTP.
* **`authorized_keys` options.** asyncssh enforces OpenSSH's options (`from=`, `command=`, ...), and `command=` forces the line that runs. `mirage-profile` binds the key to a [profile](/home/access/ssh#bind-a-key-to-a-profile).
* **Terminal line limit.** 1024 characters.
* **A thread per workspace.** Each workspace runs on its own thread and event loop through a [`WorkspaceRunner`](/python/access/in-app#beside-your-own-event-loop), so a busy workspace does not hold up another or the HTTP server.

## Code map

| Path | What |
| - | - |
| [`mirage/server/app.py`](https://github.com/strukto-ai/mirage/blob/main/python/mirage/server/app.py) | `build_app`: routers, MCP and RPC endpoints, the SSH lifespan. |
| [`mirage/server/daemon.py`](https://github.com/strukto-ai/mirage/blob/main/python/mirage/server/daemon.py) | The daemon entry the CLI starts. |
| [`mirage/server/routers/`](https://github.com/strukto-ai/mirage/tree/main/python/mirage/server/routers) | The HTTP routes: workspaces, sessions, shell, tools, jobs, asks. |
| [`mirage/server/mcp/`](https://github.com/strukto-ai/mirage/tree/main/python/mirage/server/mcp) | `MirageMcpServer`, the `/mcp` endpoint, and the stdio relay `mirage mcp` runs. |
| [`mirage/server/rpc/`](https://github.com/strukto-ai/mirage/tree/main/python/mirage/server/rpc) | `MirageRpcServer`, the `/rpc` endpoint, and the stdio relay `mirage rpc` runs. |
| [`mirage/server/ssh/`](https://github.com/strukto-ai/mirage/tree/main/python/mirage/server/ssh) | The SSH server: shell, exec, SFTP and SCP. |
| [`mirage/agents/tool_operations.py`](https://github.com/strukto-ai/mirage/blob/main/python/mirage/agents/tool_operations.py) | The agent tool table every interface calls. |
| [`mirage/cli/`](https://github.com/strukto-ai/mirage/tree/main/python/mirage/cli) | The `mirage` CLI, one module per verb. |


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