ThreadDesk Documentation
What is ThreadDesk?¶
ThreadDesk is an alternative wrapper UI over Mattermost — designed for people who work across many channels and threads simultaneously throughout the day.
If you find yourself constantly switching between threads, forgetting what needs a reply, or losing track of open discussions, ThreadDesk brings them all into a single structured view — similar to how an email client like Superhuman or HEY handles inbox management, but for your Mattermost workspace.
The Problem with Native UI¶
The native Mattermost interface works well for simple team setups, but becomes difficult to manage when you are active in many threads at once:
- No thread status — you read a message someone asked you something in, switch to another task, and forget. Or you asked something and got no answer — that just disappears.
- Unread ≠ Important — the unread indicator tells you nothing about whether action is required from you, or whether it's just noise.
- No unified thread view across teams — when you are in multiple Mattermost teams, there is no single place to see all active threads together.
- Direct messages are scattered — personal conversations are randomly tied to the team where they were first created, making them hard to find. DMs appear in every team's thread list, creating confusion. Additionally, non-threaded personal conversations are completely invisible in the thread view, so you easily forget about them.
- Everything blinks at once — with many active channels it becomes impossible to prioritize mentally what needs attention now vs. later.
The Solution: Zero Inbox & Status Flow¶
ThreadDesk applies the Zero Inbox approach (like email) combined with a Kanban-style flow for thread lifecycle — from incoming message to resolved. Statuses can be renamed to fit your team's language. The default flow:
📥 Reply Needed / Not Answered
The main inbox. Threads land here when:
- Someone mentioned you and the last message is not from you
- You received a direct message that hasn't been replied to
A reply includes your emoji reaction. Certain acknowledgment messages from colleagues (e.g. "Ok", "Thanks") are automatically recognized as resolved, moving the thread out of this column.
🔄 Open
Threads where you are a participant (mentioned or initiated) but no immediate response is required from you — the discussion is ongoing, waiting on others, or has ended without a clear summary. Also catches informational messages that don't need action but you don't want to ignore.
🕒 Snoozed / Todo / Remind
Manually flagged threads — things you need to get back to later:
- Remind a colleague tomorrow
- Something you need to do and don't want to forget
Note: By default, anything you Save / Mark (flag) natively in Mattermost also syncs into this group automatically.
👁 Following
Threads where you are not a participant (not mentioned, didn't write) — but you are subscribed to the channel and want to stay informed. These are visible but do not demand action.
✅ Resolved / Completed / Finished
The key status with no equivalent in native Mattermost. You mark a thread as resolved when the discussed question is answered or the conversation is complete.
Ideally, whoever initiated the thread leaves a final summary comment — or at minimum, the thread title is updated. The resolution might be "task created in the tracker" rather than the actual work being done — the point is that no open questions remain.
This lets you clearly distinguish resolved from hanging threads.
🔕 Ignored
The second type of closure — for threads that are not resolved but are no longer relevant to you:
- You unfollowed the thread in Mattermost (no longer want to track it)
- You manually flagged a message/thread as something to skip (remove from Open)
Difference from Resolved: Resolved threads you may return to later (e.g. "what did we decide last week?"). Ignored threads are noise you want out of your view.
Preparation & Team Guidelines¶
ThreadDesk works best when combined with some basic communication hygiene agreements with your team. No tool fixes a chaotic channel structure — but these are standard practices for Slack / Mattermost:
- Don't discuss everything in one big channel — split by topic
- Within channels, use threads — one thread per question/topic
- Don't run multiple discussions inside one thread (endless threads are hard to resolve)
Personal setup — configure Following:
ThreadDesk only listens to channels you follow. By default this is:
- Threads where you were mentioned
- Threads you started yourself
You can additionally subscribe to full channels (all messages) for channels that are important to you. Everything else is ignored.
MCP (AI Integration)¶
ThreadDesk exposes an MCP (Model Context Protocol) server, so agents like Claude Desktop, Claude Code, or any MCP‑aware client can read your curated thread state directly.
Why not just use the Mattermost MCP?
The official Mattermost MCP gives an agent low‑level access to channels, posts, and users — the agent has to load and filter everything itself, which burns context fast and rarely surfaces what actually needs your attention.
ThreadDesk's MCP serves a pre‑organized, status‑aware view: only threads grouped by status (Reply Needed, Open, Snoozed, Following, Resolved) — the same Zero‑Inbox structure you see in the UI. The agent gets a short, prioritized context instead of the full firehose.
Connecting to Claude Desktop
Add to claude_desktop_config.json:
{ "mcpServers": { "threaddesk": { "command": "npx", "args": [ "-y", "mcp-remote", "https://threaddesk.your-company.com/mcp", "--transport", "http-only", "--header", "X-MM-PAT: YOUR_MATTERMOST_PAT" ] } } }
Replace threaddesk.your-company.com with your ThreadDesk host, and YOUR_MATTERMOST_PAT with a Mattermost
Personal Access Token. The PAT scopes ThreadDesk's view to your user — the agent only sees what you can see.
Available tools
Brief overview of what the server exposes:
| Tool | Purpose |
|---|---|
list_threads | Paginated thread summaries filtered by status (OPEN, SNOOZED, DONE); optional teamId (direct for DMs) and lastMessageSince. |
get_thread_details | Fetch a single thread by root post id, with up to the last 100 messages in chronological order. |
update_thread | Toggle a thread's status flags: isAnswered, isDone, isRemind, isOpen, isFollowing. |
list_teams | List the Mattermost teams the user is a member of. |
list_channels | List channels the user has access to in a given team. |
Example prompts
Once connected, you can ask the agent things like:
- Weekly status report — "Using threaddesk, collect a brief weekly status: what we completed last week — resolved threads, key decisions. Group by team, keep it short."
- Triage by priority — "In the
platformteam, list unfinished threads and tell me who to ping, in priority order." - Inbox health check — "How many threads are in Reply Needed right now? Flag anything older than 3 days."
- Catch up after time off — "I was away Mon–Fri. Summarize what I missed in the channels I follow — only items where I'm mentioned or directly involved."
Self-Hosted Installation¶
Quick Start
The fastest way to get ThreadDesk running:
docker run -d --restart always \ --name threaddesk \ -p 8080:8080 \ -v threaddesk:/app/data \ syschema/threaddesk:latest
After starting, the service is available at http://localhost:8080.
Production Setup
Example with docker-compose.yml:
services: threaddesk: image: syschema/threaddesk:latest container_name: threaddesk restart: always ports: - "8080:8080" volumes: - threaddesk_data:/app/data environment: - MATTERMOST_BASE_URL=https://mattermost.company.com - MATTERMOST_CLIENT_ID=your_oauth_client_id - MATTERMOST_CLIENT_SECRET=your_oauth_client_secret - LOGGING_LEVEL=INFO logging: driver: "json-file" options: max-size: "10m" max-file: "3" volumes: threaddesk_data:
Key parameters:
| Variable | Description |
|---|---|
MATTERMOST_BASE_URL | URL of your Mattermost server. If omitted, users enter it manually. |
MATTERMOST_CLIENT_ID | OAuth2 Application Client ID from Mattermost. |
MATTERMOST_CLIENT_SECRET | OAuth2 Application Client Secret from Mattermost. |
LOGGING_LEVEL | Log verbosity. Default: INFO. |
Getting OAuth2 credentials:
Register an OAuth2 application in your Mattermost instance following the official guide:
Mattermost OAuth2 App Setup
After registering the app, copy the Client ID and Client Secret into the environment variables above.
Nginx Reverse Proxy
To serve ThreadDesk on a corporate domain (e.g. threaddesk.company.com) via Nginx:
server { listen 443 ssl; server_name threaddesk.company.com; ssl_certificate /etc/ssl/certs/threaddesk.company.com.crt; ssl_certificate_key /etc/ssl/private/threaddesk.company.com.key; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; } }
Security Items¶
ThreadDesk is designed with a minimal attack surface by default:
- No outbound traffic — the service only communicates with your Mattermost instance. You can safely close all outbound network access except for the IP/host of your Mattermost server.
- No persistent database needed. ThreadDesk stores only a local cache of recent threads (configurable 7–14 days). No separate database to maintain or secure.
- Closed deployment: Keep ThreadDesk inside your corporate network / VPN. Do not expose it directly to the public internet.
- Use OAuth2 via Mattermost instead of PATs — All login is handled via Mattermost OAuth2. This means credentials are never stored or handled by ThreadDesk Enable two-factor authentication (2FA) in Mattermost — this protects ThreadDesk access automatically
- The service works as a regular client with user rights — it accesses Mattermost with the user's own token and can only see data that the user already has access to. It is effectively a UI client, like the web or desktop app, just purpose-built for thread management.
- Logs contain no message content or any private user data. Log verbosity defaults to
INFOand log size is capped in the provided Docker Compose configuration.
Licensing¶
Cloud Version
A hosted cloud version is available for evaluation. Most companies prefer self-hosted deployment since Mattermost is typically within their corporate network.
Self-Hosted — Free Use
Self-hosted deployment is free for personal use on localhost, single-user deployment on your own VM, with unlimited instances in this scenario.
Self-Hosted — Team Use (License Required)
If a single ThreadDesk instance serves multiple users or teams within a company, a license key is required. Two licensing options:
| Option | Description |
|---|---|
| Per active user | Counted by users who actively used the service within the past week |
| Per instance | Flat fee for unlimited users on one instance |
Important: When purchasing a license, specify the exact Mattermost server hostname that ThreadDesk will connect to. The license is bound to that host.
License keys can be purchased on the ThreadDesk website and entered directly in the application settings.