Skip to main content
Glama
yui666a

mcp-server-for-mattermost

by yui666a

mcp-server-for-mattermost

日本語

A remote MCP server that lets AI clients (claude.ai, Claude Code, Codex CLI, and other MCP clients) read and post to Mattermost as each user. Users add one URL as a connector and sign in with their own Mattermost account; the server only ever sees and does what that user can.

Tool descriptions, tool output, the consent page, and the documents under docs/ are written in Japanese.

Why this exists

Mattermost ships an official MCP server inside the Mattermost Agents plugin. Its documentation lists Mattermost Server v12.0 or later, and an Enterprise license or higher to turn on the HTTP endpoint that external clients connect to. It offers a much larger tool catalog (about 120 tools). If you have that license and version, it is the natural choice.

This project targets the other case:

  • Standalone. It runs as its own container beside an existing Mattermost and needs no plugin. It talks to Mattermost only through the REST API and its OAuth 2.0 service provider.

  • Works with Team Edition. It is developed and tested against Mattermost Team Edition 11.7.8.

  • Per-user OAuth with its own authorization server. MCP clients register themselves (Dynamic Client Registration) and receive tokens that are valid only for this server. The user's Mattermost tokens are kept server-side, encrypted, and are never handed to the MCP client (no token passthrough). Every authorization shows a consent page that displays the client's redirect URI.

  • Scheduled posts on Team Edition. Mattermost's scheduled-post API is not available on Team Edition, so the server stores scheduled posts itself and posts them with the user's token when they are due.

  • Guard rails for an LLM caller. It suppresses duplicate posts when a client retries, edits and deletes only the user's own posts, refuses to delete a thread root that has replies, and does not overwrite a different draft unless asked.

Related MCP server: mattermost-mcp

Tools

Tool

Purpose

search_posts

Search messages in the user's teams with Mattermost search syntax (from:, in:, before:, ...)

read_channel

Read a channel's posts, newest first

read_thread

Read a thread's root and replies, oldest first

get_post

Read one post by post ID or permalink URL

get_file

Read an attached file; images are returned as a preview image

search_channels

Find channels (public, joined private, DMs, group DMs) by name

list_my_channels

List joined channels by most recent post

get_channel

Channel type, purpose, header, member count, and pinned posts

get_unreads

Unread channels and, with collapsed reply threads, unread threads

get_mentions

Posts that mention the user

search_users

Find users by name or username

get_user

A user's profile with time zone, local time, and status

send_message

Post to a channel or thread, optionally with small file attachments

add_reaction / remove_reaction

Add or remove the user's own reaction

edit_message / delete_message

Edit or delete the user's own post

save_draft

Save a Mattermost draft for the user to send from the UI

schedule_message

Schedule a post for a later time (1 minute to 30 days ahead)

list_scheduled_messages

List the user's scheduled posts with status and permalink

update_scheduled_message / cancel_scheduled_message

Change or cancel a pending scheduled post

Times are in JST: a schedule_message time without an offset (YYYY-MM-DDTHH:mm[:ss[.sss]]) is read as +09:00, so append Z or +hh:mm (-hh:mm) for another zone. Search dates (on:, before:, after:) are JST days, and output shows each time in both UTC and JST.

Read-only tools carry the MCP readOnlyHint annotation so clients can ask before writes.

Architecture

MCP client ──(MCP token)──> mcp-server-for-mattermost ──(user's Mattermost token)──> Mattermost REST API
     │                                │
     └─ sign-in: /mcp/oauth/authorize ─> consent page ─> Mattermost /oauth/authorize (login)
  • Streamable HTTP at <PUBLIC_URL>/mcp, stateless, POST only.

  • OAuth metadata at /.well-known/oauth-protected-resource/mcp and /.well-known/oauth-authorization-server/mcp (path-inserted form, so it can share an origin with Mattermost's own metadata).

  • One confidential OAuth app registered in Mattermost; one process; state in a SQLite file.

  • Per-user and global limits on Mattermost API calls (300 and 600 per minute), plus timeouts and concurrency caps.

The full design is in docs/superpowers/specs/2026-11-01-mattermost-mcp-design.md.

Requirements

  • Mattermost with the OAuth 2.0 service provider enabled. Tested with Team Edition 11.7.8; run the integration tests before using another version.

  • Node.js 26 or later and pnpm 11 (pinned through packageManager) for development; Docker for running the server and the local Mattermost.

  • An HTTPS origin for the server and a reverse proxy in front of it.

Quick start (local)

pnpm install
pnpm dev:up    # starts Mattermost 11.7.8 on http://localhost:8065 and writes dev/.state.json

pnpm dev:up creates the users admin, alice, and bob (password Passw0rd!dev123), two teams, the load-test users load1 to load6, and an OAuth app whose callback is http://localhost:3000/mcp/oauth/callback. Set MATTERMOST_IMAGE_TAG to try another Mattermost version.

Start the server against it:

export PUBLIC_URL=http://localhost:3000 MM_URL=http://localhost:8065
export MM_OAUTH_CLIENT_ID=$(node -p "require('./dev/.state.json').oauth.clientId")
export MM_OAUTH_CLIENT_SECRET=$(node -p "require('./dev/.state.json').oauth.clientSecret")
export TOKEN_ENC_KEY=$(openssl rand -base64 32) DB_PATH=/tmp/mcp-dev.sqlite
pnpm start
curl -s http://localhost:3000/.well-known/oauth-protected-resource/mcp

The consent page sets a __Host- cookie with Secure, so to sign in from a real MCP client, put the server behind an HTTPS tunnel, set PUBLIC_URL to the tunnel's origin, and point the OAuth app at it with node dev/setup.ts --callback https://<tunnel>/mcp/oauth/callback.

Tests:

pnpm test        # unit tests
pnpm typecheck
pnpm test:int    # integration tests against the local Mattermost (needs pnpm dev:up)
pnpm dev:down    # stop the local Mattermost and delete its data

Deploying

See docs/deployment.md for the Mattermost settings to check, creating the OAuth app, environment variables, a compose.yml example, and the reverse-proxy requirements with an nginx example. The server can share Mattermost's origin (under /mcp) or run on its own host.

Connecting a client

Use <PUBLIC_URL>/mcp, for example https://mcp.example.com/mcp.

  • Claude Code: claude mcp add --transport http mattermost https://mcp.example.com/mcp, then sign in from /mcp.

  • claude.ai: add a custom connector with the URL.

  • Codex CLI: codex mcp add mattermost --url https://mcp.example.com/mcp, then codex mcp login mattermost.

Measured client behavior is in docs/measurements.md.

Documentation

License

MIT

Mattermost is a trademark of Mattermost, Inc. This project is not affiliated with, sponsored by, or endorsed by Mattermost, Inc.

Related MCP Connectors

Related MCP Servers