diff --git a/docs.json b/docs.json
index 5c92ad2cc..ec40b98fb 100644
--- a/docs.json
+++ b/docs.json
@@ -560,6 +560,7 @@
"en/usage/platforms/discord",
"en/usage/platforms/telegram",
"en/usage/platforms/slack",
+ "en/usage/platforms/mattermost",
"en/usage/platforms/line",
"en/usage/platforms/webpage",
"en/usage/platforms/http-bot",
@@ -892,6 +893,7 @@
"zh/usage/platforms/discord",
"zh/usage/platforms/telegram",
"zh/usage/platforms/slack",
+ "zh/usage/platforms/mattermost",
"zh/usage/platforms/line",
"zh/usage/platforms/webpage",
"zh/usage/platforms/http-bot"
@@ -1159,6 +1161,7 @@
"ja/usage/platforms/discord",
"ja/usage/platforms/telegram",
"ja/usage/platforms/slack",
+ "ja/usage/platforms/mattermost",
"ja/usage/platforms/line",
"ja/usage/platforms/webpage",
"ja/usage/platforms/http-bot",
diff --git a/en/usage/platforms/mattermost.mdx b/en/usage/platforms/mattermost.mdx
new file mode 100644
index 000000000..586fed532
--- /dev/null
+++ b/en/usage/platforms/mattermost.mdx
@@ -0,0 +1,48 @@
+---
+title: "Mattermost"
+description: "Connect a Mattermost bot to LangBot and bring agents and workflows to your Mattermost server in minutes."
+icon: "/images/platforms/mattermost.svg"
+---
+
+
+The screenshots below use the Chinese interface. Follow the corresponding menu items and fields described in the text.
+
+
+## Create a bot account
+
+Log in to your Mattermost instance (self-hosted or hosted by Mattermost). Click the `Mattermost icon` in the upper-left corner and select `Integrations` from the menu.
+
+
+
+On the Integrations page, select `Bot Accounts` in the left menu, then click `Add Bot Account` in the upper-right corner.
+
+
+
+Choose a username for the bot.
+
+
+
+Set the role to `Member` (administrator-related features are not currently supported). Select `post:all` if you need direct messages, or select only `post:channels` if you only need public channels. Then click `Create Bot Account` in the lower-right corner.
+
+
+
+Click the button to copy the token. It is shown only once, so save it securely. Then click `Done` in the lower-right corner.
+
+
+
+## Configure the bot in LangBot
+
+Open LangBot Cloud or your self-hosted LangBot instance and follow the red arrows in the screenshot below:
+
+- Hover over the `Bots` tab on the left and click the `+` icon that appears.
+- Enter a name in the `Bot Name` field.
+- Open the platform adapter dropdown and select `Mattermost`.
+- Enter the address of your Mattermost instance and the token for the bot account you just created.
+- (Optional) Disable streaming output if your pipeline or AI provider does not support it.
+- Click `Submit` in the upper-right corner to open the bot editing page.
+
+
+
+Bind an existing pipeline, configure routing if needed, and click `Save` in the upper-right corner.
+
+
diff --git a/en/usage/platforms/readme.mdx b/en/usage/platforms/readme.mdx
index 6661a3bad..4e905d3cb 100644
--- a/en/usage/platforms/readme.mdx
+++ b/en/usage/platforms/readme.mdx
@@ -13,6 +13,7 @@ Bots are used to receive message events from messaging platforms and call pipeli
| Discord | ✅ | | [Tutorial](/en/usage/platforms/discord) |
| Telegram | ✅ | | [Tutorial](/en/usage/platforms/telegram) |
| Slack | ✅ | | [Tutorial](/en/usage/platforms/slack) |
+| Mattermost | ✅ | Supports the open-source, Free, Professional, and Enterprise editions | [Tutorial](/en/usage/platforms/mattermost) |
| LINE | ✅ | | [Tutorial](/en/usage/platforms/line) |
| KOOK | ✅ | | [Tutorial](/en/usage/platforms/kook) |
| Lark | ✅ | | [Tutorial](/en/usage/platforms/lark) |
diff --git a/images/platforms/mattermost.svg b/images/platforms/mattermost.svg
new file mode 100644
index 000000000..d185ef27d
--- /dev/null
+++ b/images/platforms/mattermost.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/images/zh/deploy/bots/mattermost/Mattermost_bot_account.png b/images/zh/deploy/bots/mattermost/Mattermost_bot_account.png
new file mode 100644
index 000000000..dd2f5dc2b
Binary files /dev/null and b/images/zh/deploy/bots/mattermost/Mattermost_bot_account.png differ
diff --git a/images/zh/deploy/bots/mattermost/Mattermost_bot_add_new.png b/images/zh/deploy/bots/mattermost/Mattermost_bot_add_new.png
new file mode 100644
index 000000000..ea6de9643
Binary files /dev/null and b/images/zh/deploy/bots/mattermost/Mattermost_bot_add_new.png differ
diff --git a/images/zh/deploy/bots/mattermost/Mattermost_bot_deploy.png b/images/zh/deploy/bots/mattermost/Mattermost_bot_deploy.png
new file mode 100644
index 000000000..ea6643e93
Binary files /dev/null and b/images/zh/deploy/bots/mattermost/Mattermost_bot_deploy.png differ
diff --git a/images/zh/deploy/bots/mattermost/Mattermost_bot_token.png b/images/zh/deploy/bots/mattermost/Mattermost_bot_token.png
new file mode 100644
index 000000000..763dae316
Binary files /dev/null and b/images/zh/deploy/bots/mattermost/Mattermost_bot_token.png differ
diff --git a/images/zh/deploy/bots/mattermost/Mattermost_langbot_add_new.png b/images/zh/deploy/bots/mattermost/Mattermost_langbot_add_new.png
new file mode 100644
index 000000000..9a48ebc3b
Binary files /dev/null and b/images/zh/deploy/bots/mattermost/Mattermost_langbot_add_new.png differ
diff --git a/images/zh/deploy/bots/mattermost/Mattermost_langbot_deploy.png b/images/zh/deploy/bots/mattermost/Mattermost_langbot_deploy.png
new file mode 100644
index 000000000..d375b2172
Binary files /dev/null and b/images/zh/deploy/bots/mattermost/Mattermost_langbot_deploy.png differ
diff --git a/images/zh/deploy/bots/mattermost/Mattermost_main_page.png b/images/zh/deploy/bots/mattermost/Mattermost_main_page.png
new file mode 100644
index 000000000..d50dc365f
Binary files /dev/null and b/images/zh/deploy/bots/mattermost/Mattermost_main_page.png differ
diff --git a/ja/usage/platforms/mattermost.mdx b/ja/usage/platforms/mattermost.mdx
new file mode 100644
index 000000000..cd20a64d9
--- /dev/null
+++ b/ja/usage/platforms/mattermost.mdx
@@ -0,0 +1,48 @@
+---
+title: "Mattermost"
+description: "LangBot に Mattermost ボットを接続し、エージェントやワークフローを数分で Mattermost サーバーに導入します。"
+icon: "/images/platforms/mattermost.svg"
+---
+
+
+以下のスクリーンショットは中国語の画面です。本文で説明する対応するメニューや入力欄を参照して操作してください。
+
+
+## ボットアカウントの作成
+
+Mattermost インスタンス(セルフホスト版または Mattermost が提供するホスト版)にログインします。左上の `Mattermost アイコン`をクリックし、メニューから「統合機能(Integrations)」を選択します。
+
+
+
+統合機能のページで、左側のメニューから「ボットアカウント(Bot Accounts)」を選択し、右上の「ボットアカウントを追加(Add Bot Account)」をクリックします。
+
+
+
+ボットのユーザー名を入力します。
+
+
+
+ロールは「メンバー(Member)」を選択します(管理者向けの機能には現在対応していません)。ダイレクトメッセージが必要な場合は `post:all`、公開チャンネルのみを使用する場合は `post:channels` だけを選択します。右下の「ボットアカウントを作成(Create Bot Account)」をクリックします。
+
+
+
+ボタンをクリックしてトークンをコピーします。トークンは一度しか表示されないため、安全な場所に保存してください。右下の「完了(Done)」をクリックします。
+
+
+
+## LangBot でのボット設定
+
+LangBot Cloud またはセルフホストの LangBot インスタンスを開き、以下の画像の赤い矢印の順に操作します。
+
+- 左側の「ボット」タブにカーソルを合わせ、表示される `+` アイコンをクリックします。
+- 「ボット名」欄にボットの名前を入力します。
+- プラットフォームアダプターのドロップダウンを開き、`Mattermost` を選択します。
+- Mattermost インスタンスのアドレスと、先ほど作成したボットアカウントのトークンを入力します。
+- (任意)パイプラインまたは AI プロバイダーがストリーミング出力に対応していない場合は、このオプションを無効にします。
+- 右上の「送信(Submit)」をクリックすると、ボットの編集画面が開きます。
+
+
+
+既存のパイプラインを紐付け、必要に応じてルーティングを設定し、右上の「保存(Save)」をクリックします。
+
+
diff --git a/ja/usage/platforms/readme.mdx b/ja/usage/platforms/readme.mdx
index 453761c54..347291929 100644
--- a/ja/usage/platforms/readme.mdx
+++ b/ja/usage/platforms/readme.mdx
@@ -13,6 +13,7 @@ description: "LangBot を各メッセージングプラットフォームに接
| Discord | ✅ | | [チュートリアル](/ja/usage/platforms/discord) |
| Telegram | ✅ | | [チュートリアル](/ja/usage/platforms/telegram) |
| Slack | ✅ | | [チュートリアル](/ja/usage/platforms/slack) |
+| Mattermost | ✅ | オープンソース版・無料版・Professional 版・Enterprise 版に対応 | [チュートリアル](/ja/usage/platforms/mattermost) |
| LINE | ✅ | | [チュートリアル](/ja/usage/platforms/line) |
| KOOK | ✅ | | [チュートリアル](/ja/usage/platforms/kook) |
| Lark | ✅ | | [チュートリアル](/ja/usage/platforms/lark) |
diff --git a/tests/fumapress-migration.test.mjs b/tests/fumapress-migration.test.mjs
index 47ec0ad60..7738db42c 100644
--- a/tests/fumapress-migration.test.mjs
+++ b/tests/fumapress-migration.test.mjs
@@ -170,8 +170,8 @@ test("MDX compatibility normalization removes internal .html route suffixes", ()
test("canonical MDX and nested OpenAPI sources are discovered", async () => {
const docs = JSON.parse(await readFile(path.join(root, "docs.json"), "utf8"));
const pages = await collectMdxDocuments(root);
- assert.equal(pages.length, 302);
- assert.deepEqual(Object.fromEntries([...pages.reduce((acc, page) => acc.set(page.split("/", 1)[0], (acc.get(page.split("/", 1)[0]) ?? 0) + 1), new Map()).entries()]), { en: 96, zh: 110, ja: 96 });
+ assert.equal(pages.length, 305);
+ assert.deepEqual(Object.fromEntries([...pages.reduce((acc, page) => acc.set(page.split("/", 1)[0], (acc.get(page.split("/", 1)[0]) ?? 0) + 1), new Map()).entries()]), { en: 97, zh: 111, ja: 97 });
assert.deepEqual(collectOpenApiSources(docs), [
{ locale: "en", source: "openapi/service-api-en.json", directory: "en/api-reference" },
{ locale: "zh", source: "openapi/service-api-zh.json", directory: "zh/api-reference" },
@@ -216,7 +216,7 @@ test("prebuild is deterministic and preserves local assets and SEO files", async
const first = await prepareFumapress({ root, outRoot: temp });
const second = await prepareFumapress({ root, outRoot: temp });
assert.deepEqual(first, second);
- assert.equal(first.documents, 302);
+ assert.equal(first.documents, 305);
assert.equal(first.fallbackDefaults, 0);
assert.equal(first.localeOnlyDocuments, 14);
assert.equal(first.redirects, 103);
diff --git a/tests/test_mattermost_docs.py b/tests/test_mattermost_docs.py
new file mode 100644
index 000000000..936f711c7
--- /dev/null
+++ b/tests/test_mattermost_docs.py
@@ -0,0 +1,78 @@
+"""Read-only contracts for Mattermost documentation translations; no network access."""
+
+import json
+from pathlib import Path
+import re
+import unittest
+
+
+ROOT = Path(__file__).resolve().parents[1]
+LOCALES = {"en": "en", "cn": "zh", "jp": "ja"}
+GUIDE = "usage/platforms/mattermost"
+IMAGE = re.compile(r"!\[([^\]]*)\]\((/images/[^)]+)\)")
+
+
+class MattermostDocsTests(unittest.TestCase):
+ def test_each_site_locale_has_a_guide_and_support_table_entry(self):
+ docs = json.loads((ROOT / "docs.json").read_text(encoding="utf-8"))
+ for language in docs["navigation"]["languages"]:
+ locale = LOCALES[language["language"]]
+ with self.subTest(locale=locale):
+ guide = ROOT / f"{locale}/{GUIDE}.mdx"
+ self.assertTrue(guide.is_file(), f"Missing translated guide: {guide}")
+ readme = (guide.parent / "readme.mdx").read_text(encoding="utf-8")
+ rows = [line for line in readme.splitlines() if line.startswith("| Mattermost |")]
+ self.assertEqual(len(rows), 1)
+ self.assertIn("✅", rows[0])
+ self.assertIn(f"](/{locale}/{GUIDE})", rows[0])
+ self.assertTrue(rows[0].split("|")[3].strip(), "Edition support notes missing")
+
+ def test_each_site_locale_lists_mattermost_in_bot_navigation(self):
+ docs = json.loads((ROOT / "docs.json").read_text(encoding="utf-8"))
+
+ def page_lists(value):
+ if isinstance(value, dict):
+ if "pages" in value:
+ yield value["pages"]
+ for child in value.values():
+ yield from page_lists(child)
+ elif isinstance(value, list):
+ for child in value:
+ yield from page_lists(child)
+
+ for language in docs["navigation"]["languages"]:
+ locale = LOCALES[language["language"]]
+ with self.subTest(locale=locale):
+ groups = [pages for pages in page_lists(language)
+ if f"{locale}/usage/platforms/slack" in pages]
+ self.assertEqual(len(groups), 1)
+ self.assertEqual(groups[0].count(f"{locale}/{GUIDE}"), 1)
+
+ def test_translations_preserve_source_steps_permissions_and_assets(self):
+ source = (ROOT / f"zh/{GUIDE}.mdx").read_text(encoding="utf-8")
+ source_images = [url for _, url in IMAGE.findall(source)]
+ for locale, screenshot_note in (("en", "Chinese"), ("ja", "中国語")):
+ with self.subTest(locale=locale):
+ path = ROOT / f"{locale}/{GUIDE}.mdx"
+ self.assertTrue(path.is_file(), f"Missing translated guide: {path}")
+ text = path.read_text(encoding="utf-8")
+ self.assertTrue(text.startswith('---\ntitle: "Mattermost"\n'))
+ self.assertRegex(text, r'(?m)^description: ".+"$')
+ self.assertIn('icon: "/images/platforms/mattermost.svg"', text)
+ self.assertTrue((ROOT / "images/platforms/mattermost.svg").is_file())
+ for permission in ("`post:all`", "`post:channels`"):
+ self.assertIn(permission, text)
+ self.assertEqual(len(re.findall(r"^## ", text, re.M)),
+ len(re.findall(r"^## ", source, re.M)))
+ self.assertEqual(len(re.findall(r"^- ", text, re.M)),
+ len(re.findall(r"^- ", source, re.M)))
+ self.assertIn(screenshot_note, text)
+ images = IMAGE.findall(text)
+ self.assertEqual([url for _, url in images], source_images)
+ for alt, url in images:
+ self.assertTrue(alt.strip(), "Translated screenshot alt text missing")
+ self.assertTrue((ROOT / url.lstrip("/")).is_file(), url)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/zh/usage/platforms/mattermost.mdx b/zh/usage/platforms/mattermost.mdx
new file mode 100644
index 000000000..6c461e77e
--- /dev/null
+++ b/zh/usage/platforms/mattermost.mdx
@@ -0,0 +1,44 @@
+---
+title: "Mattermost"
+description: "用 LangBot 接入 Mattermost 机器人,几分钟内将 智能体/工作流 接入 Mattermost 服务器。"
+icon: "/images/platforms/mattermost.svg"
+---
+
+## 创建机器人账号
+
+登录Mattermost实例(自部署/官方皆可),点击左上角的`Mattermost图标`,在下拉菜单中选择`集成`。
+
+
+
+进入集成页面后,在左侧菜单中选择`机器人账号`,点击右上角的添加机器人账号。
+
+
+
+为机器人起一个用户名。
+
+
+
+身份选择`成员`即可(暂不支持管理员相关功能),需要私聊选`post:all`,仅需要公共频道就只勾选`post:channels`,然后点击右下角的`创建机器人账号`。
+
+
+
+点击按钮复制令牌(只显示一次,记得保存),点右下角`完成`。
+
+
+
+## 配置LangBot机器人
+
+进入LangBot官网或自部署实例,按下图中红箭头指示的顺序操作:
+
+- 光标移到左侧`机器人`选项卡上,会显示一个加号`+`,点击加号
+- 给机器人起一个名字,输进`机器人名称`的文本框
+- 点击平台适配器选择的选项框,在下拉菜单中选择`Mattermost`
+- 输入`Mattermost`实例的地址和刚才创建的机器人账号的令牌
+- (可选)如果你的流水线/AI供应商不支持流式输出,则关闭该选项
+- 点击右上角的提交后会进入编辑该机器人的界面
+
+
+
+绑定现有的流水线,以及配置路由(如果有需求的话),并点击右上角的保存。
+
+
diff --git a/zh/usage/platforms/readme.mdx b/zh/usage/platforms/readme.mdx
index 21f6f1e76..6e85b13ef 100644
--- a/zh/usage/platforms/readme.mdx
+++ b/zh/usage/platforms/readme.mdx
@@ -21,6 +21,7 @@ description: "将 LangBot 接入各消息平台:Discord、Telegram、Slack、
| Discord | ✅ | | [教程](/zh/usage/platforms/discord) |
| Telegram | ✅ | | [教程](/zh/usage/platforms/telegram) |
| Slack | ✅ | | [教程](/zh/usage/platforms/slack) |
+| Mattermost | ✅ | 适用于开源版、免费版、专业版、企业版 | [教程](/zh/usage/platforms/mattermost) |
| LINE | ✅ | | [教程](/zh/usage/platforms/line) |
| KOOK | ✅ | | [教程](/zh/usage/platforms/kook) |
| 页面机器人 | ✅ | 将聊天组件嵌入网站 | [教程](/zh/usage/platforms/webpage) |