v0.1.0
Ctrl K

Maat Documentation

Maat is a free, open-source mobile application that lets you chat securely with your locally hosted Large Language Models — via LM Studio — from anywhere on your home network.

By utilizing a native desktop application (PyQt6 + FastAPI) on your PC and a fast Flutter mobile client, Maat ensures that all inference runs on your own hardware. Your chats remain 100% private, with zero data sent to the cloud. Setup takes less than a minute via a simple QR code scan.

Quick Download

Don't want to build from source? Download the latest pre-compiled Android APK from the Releases page.

Features

Zero Configuration

Open the desktop app on your PC to instantly generate a pairing QR code for your mobile device. No IP addresses to type.

100% Local & Private

No cloud servers. All communication happens over your home Wi-Fi between your phone and your PC.

Real-time Streaming

Watch the AI generate responses on your phone in real-time via Server-Sent Events streaming.

Model Switching

Easily switch between local models in LM Studio and remote Cloud LLMs (OpenAI, Gemini, Anthropic).

Custom Personalities

Choose from predefined AI personas — Coding Partner, Creative Writer — or inject your own system prompts.

Rich Markdown

Code blocks, bolding, and italics are rendered beautifully in the chat interface with full syntax highlighting.

Architecture

Maat is split into two main components that communicate over your local Wi-Fi network:

📱
Mobile App
Flutter / Dart
HTTP / SSE
🖥️
Desktop Gateway
PyQt6 / FastAPI
Localhost API
🧠
LM Studio
Local LLM Server
Inference
Local LLM
Qwen, Llama, Gemma…

Prerequisites

Before setting up Maat, ensure you have the following installed on your system:

LM Studio — installed and running on your PC with the "Local Server" started on the default port 1234.
Python 3.12+ — required to run the gateway server.
Flutter SDK — only needed if you want to build the mobile app from source. Otherwise, download the APK from Releases.
Both your phone and PC must be connected to the same Wi-Fi network.

Quick Start

Get Maat running in under a minute with these two steps.

Step 1 — Run the Desktop Gateway

PowerShell
cd gateway
python -m venv venv
.\venv\Scripts\activate
pip install -r requirements.txt
python main.py

Step 2 — Run the Mobile App (from source)

PowerShell
cd mobile
flutter pub get
flutter run

Step 1 — Run the Desktop Gateway

Terminal
cd gateway
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python main.py

Step 2 — Run the Mobile App (from source)

Terminal
cd mobile
flutter pub get
flutter run

Step 1 — Run the Desktop Gateway

Bash
cd gateway
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python main.py

Step 2 — Run the Mobile App (from source)

Bash
cd mobile
flutter pub get
flutter run

A native desktop window will open displaying your pairing QR code. Open the Maat app and scan it to pair. That's it!

Pairing Guide

Maat uses a QR-code based pairing system to securely connect your mobile device to the gateway without manual IP configuration.

1

Start LM Studio's Local Server

Open LM Studio on your PC. Go to the Local Server tab and click Start Server. The default port is 1234.

2

Run the Desktop Gateway

In your terminal, navigate to the gateway/ directory and run python main.py. The desktop app will launch and display a QR code containing your local IP address and a one-time pairing token.

3

Scan with the Mobile App

Open the Maat app on your phone. It will launch the QR scanner automatically. Point your camera at the desktop QR code. The app will decode the server URL and pairing token, register itself with the gateway, and navigate you straight to the chat screen.

How it works under the hood

The QR code encodes a JSON payload: {"server": "http://192.168.x.x:8080", "device_name": "YOUR-PC", "pairing_token": "..."}. The mobile app sends a POST /pair request with this token to register itself and receives a persistent device token for subsequent API calls.

Troubleshooting

📶 "Can't connect" after scanning QR code

  • Ensure both your phone and PC are on the same Wi-Fi network (same SSID, same subnet).
  • Check that Windows Firewall isn't blocking port 8080. You may need to add an inbound rule for the gateway.
  • Try accessing http://<your-pc-ip>:8080/health from your phone's browser to verify connectivity.

🧠 "LM Studio is disconnected"

  • Make sure LM Studio's Local Server is running on port 1234.
  • The gateway will retry the connection every 10 seconds automatically.
  • You can also specify a custom LM Studio URL: python main.py --lmstudio-url http://localhost:1234

📱 App shows a blank screen or crashes

  • Make sure you're using the latest release APK from GitHub Releases.
  • If building from source, ensure your Flutter SDK version is ^3.11.3 or later.

Gateway API Overview

The Maat Gateway exposes a RESTful API built with FastAPI. All endpoints (except /health and /pair) require a valid X-Device-Token header obtained through the pairing process.

The default base URL is http://<your-pc-ip>:8080.

Authentication

Include the header X-Device-Token: <your-device-token> on every authenticated request. Failing to do so returns a 401 Unauthorized error.

Health Check

GET /health

Returns the gateway and LM Studio connection status. No authentication required.

Response

JSON
{
  "status": "ok",
  "lmstudio": true,
  "version": "0.1.0",
  "gateway": true
}

Pairing

GET /pair/qr

Returns a PNG image of the QR code for pairing. Open this URL in a browser to display the QR code visually.

GET /pair/info

Returns the JSON pairing payload containing the server URL, device name, and pairing token.

Response

JSON
{
  "server": "http://192.168.1.100:8080",
  "device_name": "MY-PC",
  "pairing_token": "a1b2c3d4..."
}
POST /pair

Registers a new device using the one-time pairing token from the QR code.

Request Body

JSON
{
  "device_name": "My Phone",
  "pairing_token": "a1b2c3d4..."
}

Response

JSON
{
  "success": true,
  "device_id": "uuid-device-token..."
}

Models

GET /models

Returns a list of all models available in LM Studio. Requires authentication.

Response

JSON
[
  { "id": "qwen2.5-coder-7b-instruct" },
  { "id": "llama-3.1-8b-instruct" },
  { "id": "gemma-2-9b-it" }
]
POST /models/{model_id}/load

Force LM Studio to load a specific model into VRAM by sending a dummy inference request. This blocks until the model is fully loaded.

Response

JSON
{
  "success": true,
  "model": "qwen2.5-coder-7b-instruct"
}

Chat

POST /chat

Stream a chat completion. Returns a text/event-stream response with Server-Sent Events (SSE). Each event is a JSON object with the streamed token.

Request Body

JSON
{
  "conversation_id": "optional-uuid",
  "model": "qwen2.5-coder-7b-instruct",
  "message": "Explain quicksort in Python",
  "personality": "coding_partner"
}
Conversation ID

If conversation_id is omitted, a new conversation is created. Include it to continue an existing conversation thread.

POST /chat/retry

Retry the last message in a conversation. Regenerates the AI's response.

Request Body

JSON
{
  "conversation_id": "your-conversation-uuid"
}
POST /chat/stop

Stop an ongoing generation for a specific conversation.

Request Body

JSON
{
  "conversation_id": "your-conversation-uuid"
}

Conversations

GET /conversations

Retrieve a list of all saved conversations.

GET /conversations/{conversation_id}

Retrieve a specific conversation by its ID, including the full message history.

PUT /conversations/{conversation_id}

Rename a conversation.

Request Body

JSON
{
  "title": "My Python Chat"
}
DELETE /conversations/{conversation_id}

Permanently delete a conversation and all its messages.

Gateway Configuration

The gateway can be configured via environment variables (in a .env file in the gateway/ directory) or CLI arguments.

Variable Default Description
GATEWAY_HOST 0.0.0.0 Host address to bind the gateway to.
GATEWAY_PORT 8080 Port number for the gateway server.
LMSTUDIO_BASE_URL http://localhost:1234 LM Studio API base URL.
LMSTUDIO_RETRY_INTERVAL 10 Seconds between LM Studio reconnection attempts.
MAX_CONTEXT_MESSAGES 50 Maximum messages sent as context to the LLM.
MODEL_CACHE_TTL 30 Seconds to cache the model list.
DEVICE_NAME hostname Display name shown in pairing QR code.

CLI Arguments

Bash
python main.py --port 9090 --host 0.0.0.0 --lmstudio-url http://localhost:1234

Mobile App

The mobile client is a Flutter application built with Material 3 and Riverpod for state management.

Project Structure

Directory
mobile/
├── lib/
│   ├── screens/
│   │   ├── chat/           # Main chat interface
│   │   ├── personality/    # AI persona selection
│   │   ├── qr_connection/  # QR code scanner & pairing
│   │   ├── settings/       # App settings
│   │   └── splash/         # Splash screen
│   ├── theme/              # App-wide theming (Material 3)
│   └── widgets/            # Reusable UI components
├── assets/
│   └── logo.png
└── pubspec.yaml

Key Dependencies

Package Purpose
flutter_riverpod Reactive state management
mobile_scanner QR code scanning for device pairing
flutter_markdown Rich markdown rendering in chat
shared_preferences Persistent local storage for tokens and settings
http HTTP client for API communication

Building from Source

Bash
# Debug build (runs on connected device/emulator)
cd mobile
flutter pub get
flutter run

# Release APK build
flutter build apk --release

How to Contribute

We are building Maat in public and are actively looking for contributors! Whether you are a student looking for resume experience, a Flutter developer, or a Python backend engineer, we want your help.

1

Find an Issue

Check the Issues tab for tasks labeled good first issue or help wanted.

2

Fork & Branch

Fork the repository and create a new branch for your feature or bugfix.

3

Submit a Pull Request

Open a PR against main with a clear description of what you changed and why.

Roadmap

Maat is currently at Version 0.1 MVP. Here's what's planned for future releases:

v0.1 — MVP

QR pairing, streaming chat, model switching, personalities, chat history, markdown rendering.

v0.2 — Enhanced Experience

Ollama backend support, multi-device management, image generation, chat export.

v0.3 — Beyond the LAN

Secure remote tunnels for chat outside your home network, end-to-end encryption, iOS App Store release.