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.
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:
Prerequisites
Before setting up Maat, ensure you have the following installed on your system:
1234.
Quick Start
Get Maat running in under a minute with these two steps.
Step 1 — Run the Desktop Gateway
cd gateway
python -m venv venv
.\venv\Scripts\activate
pip install -r requirements.txt
python main.pyStep 2 — Run the Mobile App (from source)
cd mobile
flutter pub get
flutter runStep 1 — Run the Desktop Gateway
cd gateway
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python main.pyStep 2 — Run the Mobile App (from source)
cd mobile
flutter pub get
flutter runStep 1 — Run the Desktop Gateway
cd gateway
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python main.pyStep 2 — Run the Mobile App (from source)
cd mobile
flutter pub get
flutter runA 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.
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.
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.
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.
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/healthfrom 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.3or 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.
Include the header X-Device-Token: <your-device-token> on every authenticated request. Failing to do so returns a 401 Unauthorized error.
Health Check
/health
Returns the gateway and LM Studio connection status. No authentication required.
Response
{
"status": "ok",
"lmstudio": true,
"version": "0.1.0",
"gateway": true
}Pairing
/pair/qr
Returns a PNG image of the QR code for pairing. Open this URL in a browser to display the QR code visually.
/pair/info
Returns the JSON pairing payload containing the server URL, device name, and pairing token.
Response
{
"server": "http://192.168.1.100:8080",
"device_name": "MY-PC",
"pairing_token": "a1b2c3d4..."
}/pair
Registers a new device using the one-time pairing token from the QR code.
Request Body
{
"device_name": "My Phone",
"pairing_token": "a1b2c3d4..."
}Response
{
"success": true,
"device_id": "uuid-device-token..."
}Models
/models
Returns a list of all models available in LM Studio. Requires authentication.
Response
[
{ "id": "qwen2.5-coder-7b-instruct" },
{ "id": "llama-3.1-8b-instruct" },
{ "id": "gemma-2-9b-it" }
]/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
{
"success": true,
"model": "qwen2.5-coder-7b-instruct"
}Chat
/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
{
"conversation_id": "optional-uuid",
"model": "qwen2.5-coder-7b-instruct",
"message": "Explain quicksort in Python",
"personality": "coding_partner"
}If conversation_id is omitted, a new conversation is created. Include it to continue an existing conversation thread.
/chat/retry
Retry the last message in a conversation. Regenerates the AI's response.
Request Body
{
"conversation_id": "your-conversation-uuid"
}/chat/stop
Stop an ongoing generation for a specific conversation.
Request Body
{
"conversation_id": "your-conversation-uuid"
}Conversations
/conversations
Retrieve a list of all saved conversations.
/conversations/{conversation_id}
Retrieve a specific conversation by its ID, including the full message history.
/conversations/{conversation_id}
Rename a conversation.
Request Body
{
"title": "My Python Chat"
}/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
python main.py --port 9090 --host 0.0.0.0 --lmstudio-url http://localhost:1234Mobile App
The mobile client is a Flutter application built with Material 3 and Riverpod for state management.
Project Structure
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.yamlKey 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
# Debug build (runs on connected device/emulator)
cd mobile
flutter pub get
flutter run
# Release APK build
flutter build apk --releaseHow 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.
Find an Issue
Check the Issues tab for tasks labeled good first issue or help wanted.
Fork & Branch
Fork the repository and create a new branch for your feature or bugfix.
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:
QR pairing, streaming chat, model switching, personalities, chat history, markdown rendering.
Ollama backend support, multi-device management, image generation, chat export.
Secure remote tunnels for chat outside your home network, end-to-end encryption, iOS App Store release.