A lightweight, cross-platform desktop chat client with MCP (Model Context Protocol) support.
Built with Flutter.
SpecterChat connects to any OpenAI-compatible API (Ollama, LM Studio, vLLM, llama.cpp server, etc.) and lets you interact with MCP servers to extend your model's capabilities with external tools.
Existing chat clients fail at one critical thing: when an MCP tool returns an image, they either don't display it or don't forward it to the model. SpecterChat solves this — images from MCP tools are rendered inline and sent back to the model as base64 so it can actually see them.
- 3-panel layout — conversation list, chat area, and settings sidebar
- Streaming responses with real-time token display and stop button
- Markdown rendering with syntax-highlighted code blocks
- Thinking/reasoning display — collapsible chain-of-thought blocks
- MCP integration via Streamable HTTP — connect to multiple servers, discover tools, execute them
- Image handling — MCP
ImageContentdisplayed inline and forwarded to the model - Tool call display — tool name, arguments (collapsible JSON), and results
- Full generation controls — temperature, top-p, top-k, max tokens, penalties
- Local storage — chat history and settings persisted in SQLite
- Dark theme by default
Prebuilt installers for each tagged release are on the Releases page:
| Platform | Minimum version | File |
|---|---|---|
| macOS | 12 (Monterey) | SpecterChat-<version>-macos-universal.dmg (Intel + Apple Silicon) |
| Windows | 10 | SpecterChat-<version>-windows-x64-setup.exe |
| Linux | Ubuntu 22.04 / Debian 12 | SpecterChat-<version>-linux-x86_64.AppImage or …-linux-amd64.deb |
We have not paid for an Apple Developer Program membership ($99/year), so the macOS build is only ad-hoc signed — no Developer ID certificate, no notarisation. Gatekeeper cannot ask Apple whether the app is safe, so the first launch is blocked with "Apple could not verify SpecterChat.app is free of malware". Nothing is wrong with the download; it is what an unnotarised app looks like.
To run it anyway, strip the quarantine attribute the browser attached:
xattr -dr com.apple.quarantine /Applications/SpecterChat.appAlternatively, open it once, then go to System Settings → Privacy & Security and click Open Anyway. On macOS 15+ the right-click → Open trick no longer works — the dialog only offers Move to Trash / Done.
On Windows, the installer is unsigned too: click More info → Run anyway at the SmartScreen prompt.
All platforms require the Flutter SDK 3.47+ (stable channel) with desktop support enabled. Then, on every platform:
git clone https://github.com/YV17labs/specterchat.git
cd specterchat
flutter pub get
dart run build_runner buildThe Drift migration-test helpers are generated, not committed. Run this once
after cloning, otherwise flutter analyze and flutter test fail on
test/database/migration_test.dart:
dart run drift_dev schema generate --data-classes --companions \
drift_schemas/ test/database/generated_migrations/Official installers are produced by the tag-driven release workflow; the steps below build the exact same artifacts locally.
Requirements: macOS 13+, Xcode 15+ with command-line tools.
flutter run -d macos # development
flutter build macos --release # → build/macos/Build/Products/Release/SpecterChat.appThe app targets macOS 12 (Monterey) and builds a universal binary
(Intel + Apple Silicon). Release builds use CODE_SIGN_IDENTITY = "-" (ad-hoc);
signing with a real Developer ID and notarising in CI is deliberately not wired
up until the Apple Developer membership is bought — see
the note above.
If you are updating an existing clone across a Flutter SDK upgrade, the build
may stop with The sandbox is not in sync with the Podfile.lock. The CocoaPods
state is stale; refresh it once:
(cd macos && pod install)Requirements: Windows 10+, Visual Studio 2022 with the "Desktop development with C++" workload.
flutter run -d windows # development
flutter build windows --release # → build\windows\x64\runner\Release\Optionally, package the installer with Inno Setup:
iscc /DMyAppVersion=<version> installers\windows\specterchat.iss # → dist\Requirements (Debian/Ubuntu — adapt package names for other distributions):
sudo apt-get install clang cmake ninja-build pkg-config \
libgtk-3-dev liblzma-dev libstdc++-12-devflutter run -d linux # development
flutter build linux --release # → build/linux/x64/release/bundle/Optionally, package an AppImage and a .deb:
bash installers/linux/build_packages.sh <version> # → dist/Alternative — DevContainer: open the repo in VS Code with Docker and the
Dev Containers extension, select "Reopen in Container", and Flutter plus
code generation are set up automatically; then flutter run -d linux.
flutter run -d macosOnce running, the terminal offers interactive commands:
| Key | Action |
|---|---|
r |
Hot reload — applies code changes in ~1s, preserves app state (current conversation, settings) |
R |
Hot restart — full restart, resets app state |
q |
Quit |
VS Code: press F5 (or Run > Start Debugging) and hot reload happens automatically on every save (Cmd+S).
| What you changed | What to do |
|---|---|
| Widget, provider, service | Save the file, press r (or just Cmd+S in VS Code) |
| Freezed model or Drift schema | Run dart run build_runner build, then press R |
pubspec.yaml (new dependency) |
Run flutter pub get, then quit and re-run flutter run -d macos |
| Native code (macOS/Swift) | Quit and re-run flutter run -d macos |
# Install dependencies
flutter pub get
# Run code generation (after modifying models or database schema)
dart run build_runner build
# Watch mode — auto-regenerates on file changes (useful during model work)
dart run build_runner watch
# Regenerate Drift migration-test helpers (required once after cloning)
dart run drift_dev schema generate --data-classes --companions \
drift_schemas/ test/database/generated_migrations/
# Run all tests
flutter test
# Run database tests only
flutter test test/database/
# Build release (macOS)
flutter build macos --release
# Build release (Linux)
flutter build linux --releaseSpecterChat uses Drift (SQLite ORM) with a versioned migration strategy.
- Schema version history and migration steps are documented in
CLAUDE.md - Foreign key constraints are enforced at runtime (
PRAGMA foreign_keys = ON) - When modifying the database schema, follow all steps in order:
- Update table definitions in
lib/database/database.dart - Increment
schemaVersion - Add a migration step in
onUpgrade(and updateonCreateif needed) - Regenerate Drift code:
dart run build_runner build
- Export the new schema snapshot:
dart run drift_dev schema dump lib/database/database.dart drift_schemas/
- Regenerate migration test helpers:
dart run drift_dev schema generate --data-classes --companions \ drift_schemas/ test/database/generated_migrations/
- Add a migration test in
test/database/migration_test.dart(verify data preservation) - Run all database tests:
flutter test test/database/
- Update table definitions in
- Start your LLM server (Ollama, LM Studio, etc.)
- In the right sidebar, set the Base URL (e.g.
http://localhost:1234/v1) - Click the refresh button to load available models and select one
- Optionally add MCP servers (name + URL) and connect to them
- Create a new conversation and start chatting
The MCP Streamable HTTP transport in lib/services/mcp/streamable_http_transport.dart is vendored from mcp_dart (MIT, © 2025 Jhin Lee) with minor changes. See the file header for details.
Released under the MIT License. Third-party dependency licenses are listed in THIRD_PARTY_NOTICES.md.
Copyright (c) 2026 Yoann Vanitou (YV17labs). SpecterChat is built and maintained by YV17labs. Open source.
