Files
mattermost-dl/mattermost-search/SKILL.md
T
Сергей Маринкевич 6f8648f7fa Run mattermost-search MCP over shared HTTP and fix FTS hangs.
Avoid per-agent stdio contention on the sqlite index, sort FTS by rank with created tie-break, and add mm_search_tag for dated #plan/#report substring search.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-04 15:05:01 +07:00

8.0 KiB
Raw Blame History

name, description
name description
mattermost-search Search Mattermost export dumps via mattermost-search MCP (mm_search_mcp.py): message text, attachment names, attachment text content, filters by user/channel/team/date. Use when the user asks to find messages, posts, or files in Mattermost exports, mattermost-dl results, or the local sqlite index; or about daily #plan/#report in System/HW (see everyday.md). Requires MCP server mattermost-search. Index bypass (no_index, regex, CLI, grep) needs explicit user permission.

Mattermost Search (MCP)

Search local Mattermost JSON exports produced by mattermost-dl.py. Always use MCP tools (mm_search, mm_search_tag, mm_resolve_user, mm_search_users, mm_user_directory_refresh, mm_search_index_status) as the default path.

Mandatory rules

Поиск в обход индекса и MCP — только с явного разрешения пользователя.

Не делать самостоятельно, пока пользователь явно не попросил:

Всё про ежедневные планы или отчёты смотри: everyday.md. Там и формат описан, и каналы.

My username: sergey.marinkevich. Resolve others via mm_resolve_user(ref="Цисык") → vladislav.tsisyk (needs user directory — see below).

Обход Примеры
Индекс no_index=true, regex=true (сканирует JSON), прямое чтение/grep по results/
MCP запуск mm_search.py, python mm_search.py …, любой shell вместо MCP tools

Разрешено без спроса: mm_search с индексом (used_index: true) — обычный search_mode="message", file_name, file_content.

Если индекс недоступен или нужен regex/scan: остановиться, сообщить пользователю (нет db_exists, нужен mm_index.py, или требуется медленный обход JSON) и дождаться явного «да» перед no_index, regex, CLI или чтением файлов экспорта.

Prerequisites

  • mattermost-search MCP server connected (mm_search, mm_search_index_status visible).
  • Export JSON under results/ (or MM_SEARCH_ROOT).
  • SQLite index mattermost_index.sqlite (or MM_SEARCH_DB) for fast search and required for attachment search. Build/update: python mm_index.py.

Prefer one shared HTTP instance (not stdio per agent). User systemd unit: mm-search-mcp.service → http://127.0.0.1:8766/mcp. In ~/.cursor/mcp.json:

"mattermost-search": { "url": "http://127.0.0.1:8766/mcp" }

Server env (HTTP service / stdio env):

Variable Default
MM_SEARCH_ROOT results
MM_SEARCH_DB mattermost_index.sqlite
MM_CONFIG_PATH config.json (for mm_user_directory_refresh(from_api=true))
MM_MCP_TRANSPORT stdio (http for shared server)
MM_MCP_HOST / MM_MCP_PORT 127.0.0.1 / 8766

Quick start

  1. mm_search_index_status() without paramters — confirm db_exists, root_exists, json_files.
  2. Pick search_mode (see table below).
  3. mm_search(query=…, …) with filters; keep limit small (10–50) unless the user needs all hits.
  4. Read matches[].post.message; for attachments also matches[].attachment.

Tools

Need Tool
Search messages / attachments mm_search(query, …)
#plan / #report in a date range mm_search_tag(keyword, after, before, …)
Resolve display name → username mm_resolve_user(ref)
Search users by name mm_search_users(query)
Refresh user directory mm_user_directory_refresh(from_api=true)
Check index & export layout mm_search_index_status(db, root)

User directory is stored in the sqlite DB (users table). Sources: users.json in export root (written by mattermost-dl.py), Mattermost API (from_api=true), and distinct usernames from indexed posts.

Choose search_mode

Goal search_mode Notes
Text in post body message (default) Uses FTS index; JSON scan only with user permission
Attachment filename file_name Index required; no regex
Text inside attachment file_content Index required; UTF-8 text files only
Regex in message message + regex=true User permission required — scans JSON, skips index
Tag #plan / #report by date use mm_search_tag Required after/before; substring #keyword; newest first

mm_search parameters

Param Role
query Search string (or regex pattern)
user Exact username filter
channel Exact display_name or name
team Exact team name
after / before YYYY-MM-DD or ISO datetime
limit Max matches (apply early — large exports)
ignore_case Default: on for substring, off for regex
no_index Force JSON file scan — user permission required
output json (default) or human (CLI-style lines)
show_file Prefix file:idx: in human output

Response shape (output=json)

{
  "count": 2,
  "used_index": true,
  "search_mode": "message",
  "root": "results",
  "db": "mattermost_index.sqlite",
  "matches": [
    {
      "file": "results/20260605/user/channel.json",
      "channel": "general",
      "team": "myteam",
      "post": {
        "id": "…",
        "idx": 42,
        "created": "2026-01-15T10:00:00Z",
        "username": "alice",
        "message": "…",
        "files": ["path/to/file.pdf"]
      },
      "attachment": {
        "filename": "doc.txt",
        "path": "…",
        "is_text": true
      }
    }
  ]
}

attachment is present only for file_name / file_content hits.

Common workflows

Find what someone wrote about a topic

mm_search(query="deploy rollback", user="alice", after="2026-01-01", limit=20)

Find posts in a channel

mm_search(query="incident", channel="alerts", limit=30)

Resolve user, then search their posts

mm_user_directory_refresh(from_api=true)
mm_resolve_user(ref="Цисык")
mm_search(query="#report", user="vladislav.tsisyk", channel="System/HW", limit=30)

Check somebody report (when username is known)

mm_search(query="#report", user="ivan.pavlov", channel="System/HW", limit=30)

Find attachment by name

mm_search(query="report.pdf", search_mode="file_name", limit=10)

Regex over raw JSON (no index) — только после явного разрешения пользователя

mm_search(query="ERROR-\\d+", regex=true, no_index=true, limit=50)

Human-readable listing for the user

mm_search(query="standup", output="human", show_file=true, limit=15)

Pitfalls

  • file_name / file_content + regex=true → error.
  • Attachment search without index → error; run mm_index.py first.
  • channel / user / team are exact matches, not substring — resolve display names with mm_resolve_user first.
  • User directory empty → run mm_user_directory_refresh(from_api=true) or re-export with mattermost-dl.py (writes users.json).
  • Token budget: prefer limit, narrow after/before, then widen if empty.
  • If count=0 with index: broaden query, drop filters, suggest mm_index.py — не переключаться на no_index / regex / CLI без явного разрешения.

Использовать только по явной просьбе пользователя (обход MCP):

CLI MCP equivalent
mm_search.py QUERY mm_search(query=QUERY)
--file-name search_mode="file_name"
--file-content search_mode="file_content"
--regex regex=true (permission required)
--no-index no_index=true (permission required)
mm_index.py not in MCP — предложить пользователю, не запускать самому