Mattermost.NET
4.0.3
See the version list below for details.
dotnet add package Mattermost.NET --version 4.0.3
NuGet\Install-Package Mattermost.NET -Version 4.0.3
<PackageReference Include="Mattermost.NET" Version="4.0.3" />
<PackageVersion Include="Mattermost.NET" Version="4.0.3" />
<PackageReference Include="Mattermost.NET" />
paket add Mattermost.NET --version 4.0.3
#r "nuget: Mattermost.NET, 4.0.3"
#:package Mattermost.NET@4.0.3
#addin nuget:?package=Mattermost.NET&version=4.0.3
#tool nuget:?package=Mattermost.NET&version=4.0.3
<a id="readme-top"></a>
Mattermost.NET
Mattermost.NET is a ready-to-use .NET Standard library for building Mattermost bots and integrations in C#.
It provides a clean, strongly typed wrapper around the Mattermost API, including messages, channels, users, file uploads, post props, and real-time WebSocket events. The client supports token-based authentication, username/password login, automatic WebSocket reconnects, custom HttpClient transport, and configurable incoming message filtering.
For a detailed endpoint map and implementation status, see API coverage.
Installation
Install the package from NuGet:
dotnet add package Mattermost.NET
Quick start
using Mattermost;
const string server = "https://mm.your-server.com";
const string token = "your-personal-access-token-or-bot-token";
const string channelId = "target-channel-id";
using var client = new MattermostClient(server, token);
await client.CreatePostAsync(channelId, "Hello from Mattermost.NET!");
Authentication
Use a personal access token or bot token
using Mattermost;
const string server = "https://mm.your-server.com";
const string token = "your-personal-access-token-or-bot-token";
using var client = new MattermostClient(server, token);
var me = await client.GetMeAsync();
Console.WriteLine($"Authenticated as @{me.Username}");
When a token is provided through the constructor, Mattermost.NET validates and caches the current user on the first authorized API call.
Use username and password
using Mattermost;
const string server = "https://mm.your-server.com";
using var client = new MattermostClient(server);
var me = await client.LoginAsync("username-or-email", "password");
Console.WriteLine($"Authenticated as @{me.Username}");
You cannot use LoginAsync on a client that was constructed with an API token.
Receiving real-time events
Call StartReceivingAsync to connect to the Mattermost WebSocket API and receive events.
using Mattermost;
const string server = "https://mm.your-server.com";
const string token = "your-personal-access-token-or-bot-token";
using var client = new MattermostClient(server, token);
client.OnConnected += (_, e) =>
{
Console.WriteLine($"Connected to {e.Uri}");
};
client.OnDisconnected += (_, e) =>
{
Console.WriteLine($"Disconnected: {e.CloseStatusDescription}");
};
client.OnLogMessage += (_, e) =>
{
Console.WriteLine(e.Message);
};
client.OnMessageReceived += (_, e) =>
{
string text = e.Message.Post.Text ?? string.Empty;
if (string.Equals(text, "ping", StringComparison.OrdinalIgnoreCase))
{
_ = e.Client.CreatePostAsync(e.Message.Post.ChannelId, "pong");
}
};
await client.StartReceivingAsync();
Console.WriteLine("Bot is running. Press Enter to stop.");
Console.ReadLine();
await client.StopReceivingAsync();
The client automatically reconnects when the WebSocket connection is lost. You only need StartReceivingAsync when you want to receive WebSocket events; regular REST API calls work without it.
Incoming message filtering
By default, MattermostClient ignores messages authored by the currently authorized user. This prevents common bot loops where a bot reacts to its own posts.
client.Options.IgnoreOwnMessages = true; // default
To receive the bot's own messages too, disable this option:
client.Options.IgnoreOwnMessages = false;
MessageEventArgs.IsCurrentUser tells whether the received message was authored by the currently authorized user.
client.OnMessageReceived += (_, e) =>
{
if (e.IsCurrentUser)
{
Console.WriteLine("Received my own message.");
}
};
You can also provide a custom incoming message filter. Return true to dispatch OnMessageReceived; return false to suppress the event.
client.Options.IncomingMessageFilter = e =>
{
string text = e.Message.Post.Text ?? string.Empty;
return text.StartsWith("!", StringComparison.Ordinal);
};
The custom filter runs after the built-in own-message filter. If you want the custom filter to evaluate own messages, set IgnoreOwnMessages to false.
client.Options.IgnoreOwnMessages = false;
client.Options.IncomingMessageFilter = e => !e.IsCurrentUser;
Using a custom HttpClient
You can pass your own HttpClient when you need custom transport behavior, such as a proxy, timeout, custom handler, logging handler, or IHttpClientFactory integration.
using Mattermost;
using System.Net;
using System.Net.Http;
const string server = "https://mm.your-server.com";
const string token = "your-personal-access-token-or-bot-token";
var handler = new HttpClientHandler
{
Proxy = new WebProxy("http://corp-proxy:8080")
};
using var httpClient = new HttpClient(handler)
{
Timeout = TimeSpan.FromSeconds(20)
};
using var client = new MattermostClient(server, token, httpClient);
var me = await client.GetMeAsync();
Console.WriteLine($"Authenticated as @{me.Username}");
When an external HttpClient is provided, Mattermost.NET uses it only as transport and does not dispose it. The Mattermost server URL still comes from server / serverUri; HttpClient.BaseAddress is not used as the Mattermost server identity.
Mattermost.NET sends authentication per request and does not mutate HttpClient.DefaultRequestHeaders.Authorization. Any default headers configured by the caller remain owned by the caller.
Available constructors:
new MattermostClient();
new MattermostClient(string serverUrl);
new MattermostClient(Uri serverUri);
new MattermostClient(string serverUrl, string apiKey);
new MattermostClient(Uri serverUri, string apiKey);
new MattermostClient(string serverUrl, HttpClient httpClient);
new MattermostClient(Uri serverUri, HttpClient httpClient);
new MattermostClient(string serverUrl, string apiKey, HttpClient httpClient);
new MattermostClient(Uri serverUri, string apiKey, HttpClient httpClient);
Common operations
Send a message
await client.CreatePostAsync(channelId, "Hello, World!");
Reply to a thread
await client.CreatePostAsync(
channelId: channelId,
message: "Thread reply",
replyToPostId: rootPostId);
Edit a post
await client.UpdatePostAsync(postId, "Updated message text");
Delete a post
await client.DeletePostAsync(postId);
Upload a file and attach it to a post
var file = await client.UploadFileAsync(channelId, "report.pdf", stream);
await client.CreatePostAsync(
channelId: channelId,
message: "Uploaded report",
files: new[] { file.Id });
Read channel posts
var posts = await client.GetChannelPostsAsync(channelId, perPage: 60);
foreach (var post in posts.Posts.Values)
{
Console.WriteLine(post.Text);
}
Get current user
var me = await client.GetMeAsync();
Console.WriteLine(me.Username);
Find users
var byId = await client.GetUserAsync(userId);
var byUsername = await client.GetUserByUsernameAsync("username");
var byEmail = await client.GetUserByEmailAsync("user@example.com");
Work with channels
var channel = await client.GetChannelAsync(channelId);
var found = await client.FindChannelByNameAsync(teamId, "town-square");
var direct = await client.CreateDirectChannelAsync(userId);
Post props and attachments
Mattermost.NET supports Mattermost post props, including attachments and interactive action metadata.
using Mattermost.Models.Posts;
var props = new PostProps();
props.Attachments.Add(new PostPropsAttachment
{
Text = "Attachment text"
});
await client.CreatePostAsync(
channelId: channelId,
message: "Message with props",
props: props);
Raw props are also supported when you need to send a custom JSON property bag.
var rawProps = new Dictionary<string, object>
{
["custom_key"] = "custom value"
};
await client.CreatePostWithRawPropsAsync(
channelId: channelId,
message: "Message with raw props",
rawProps: rawProps);
Builders
PostBuilder
using Mattermost.Builders;
using Mattermost.Enums;
await new PostBuilder()
.ToChannel(channelId)
.AddText("Important message")
.SetPriority(MessagePriority.Important)
.SendMessageAsync(client);
Markdown table builder
using Mattermost.Builders;
using Mattermost.Models.Enums;
string table = new TableMarkdownBuilder(3, TableAlignment.Center)
.AddHeader("Name", "Status", "Score")
.AddRow("Build", "OK", 100)
.AddRow("Tests", "OK", 100)
.ToString();
await client.CreatePostAsync(channelId, table);
API coverage
The public API is exposed through IMattermostClient and includes:
- authentication and logout;
- current user, users by id, username, or email;
- create, update, delete, read, and list posts;
- thread posts;
- channel lookup, creation, archiving, and membership changes;
- direct and group channels;
- file upload, download, streaming, and metadata;
- Calls plugin channel state;
- WebSocket events for messages, status changes, connection changes, and raw events.
See IMattermostClient for the full list of implemented methods.
Missing a Mattermost API method? Please open an issue with the exact Mattermost endpoint or scenario you need:
https://github.com/bvdcode/Mattermost.NET/issues/new?template=Blank+issue
Target framework
Mattermost.NET targets .NET Standard 2.1.
License
Distributed under the MIT License. See LICENSE.md for more information.
Contact
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- System.Text.Json (>= 10.0.6)
-
.NETStandard 2.1
- System.Text.Json (>= 10.0.6)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 4.0.4 | 76 | 4/25/2026 | |
| 4.0.3 | 68 | 4/25/2026 | |
| 4.0.2 | 62 | 4/25/2026 | |
| 4.0.1 | 73 | 4/25/2026 | |
| 4.0.0 | 67 | 4/25/2026 | |
| 3.0.7 | 93 | 4/16/2026 | |
| 3.0.6 | 87 | 4/15/2026 | |
| 3.0.5 | 151 | 3/25/2026 | |
| 3.0.4 | 93 | 3/25/2026 | |
| 3.0.3 | 1,374 | 8/9/2025 | |
| 3.0.2 | 164 | 8/9/2025 | |
| 3.0.1 | 320 | 8/8/2025 | |
| 3.0.0 | 262 | 8/6/2025 | |
| 2.0.3 | 167 | 7/31/2025 | |
| 2.0.2 | 163 | 7/31/2025 | |
| 2.0.1 | 164 | 7/29/2025 | |
| 2.0.0 | 146 | 7/29/2025 | |
| 1.0.5 | 143 | 7/29/2025 | |
| 1.0.4 | 172 | 7/18/2025 | |
| 1.0.3 | 174 | 7/18/2025 |