Discourse Mcp Server

by discourse

10k downloads Not rated yet

About

A Model Context Protocol (MCP) stdio server that exposes Discourse forum capabilities as tools for AI agents. Works with all deployments of discourse.org, self hosted or cloud hosted. just generate an API key to connect.

Explore

- Read‑only by default; writes are opt‑in and guarded.
- Built‑in tools: search, read topics/posts, list categories/tags, filter topics.
- Write tools: create posts, topics, categories, and users (when enabled).
- Supports Admin API Keys and User API Keys for authentication.
- Rate‑limited writes (~1 req/sec) with retries on 429/5xx.
- Remote Tool Execution API for additional dynamic tools.

Setting up with Highlight

This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:

  1. Download and install Highlight from highlightai.com/download
  2. Navigate to the plugins tab and select "Add Custom Plugin"
  3. Configure the plugin with the settings below
    Plugin Name Discourse Mcp Server
    Command (node, npx, python, etc.)

    Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.

  4. Enable "Start Automatically" if you want the plugin to start when Highlight launches

From the repository

The server registers tools under the MCP server name @discourse/mcp. Choose a target Discourse site either by:
- Using the discourse_select_site tool at runtime (validates via /about.json), or
- Supplying --site <url> to tether the server to a single site at startup (validates via /about.json and hides discourse_select_site).

- Auth
- None by default.
- Admin API Keys (require admin permissions): --auth_pairs '[{"site":"https://example.com","api_key":"...","api_username":"system"}]'
- User API Keys (any user can generate): --auth_pairs '[{"site":"https://example.com","user_api_key":"...","user_api_client_id":"..."}]'
- You can include multiple entries in auth_pairs; the matching entry is used for the selected site. If both user_api_key and api_key are provided for the same site, user_api_key takes precedence.

- Write safety
- Writes are disabled by default.
- The tools discourse_create_post, discourse_create_topic, discourse_create_category, and discourse_create_user are only registered when all are true:
- --allow_writes AND not --read_only AND some auth is configured (either default flags or a matching auth_pairs entry).
- A ~1 req/sec rate limit is enforced for write actions.

- Flags & defaults
- --read_only (default: true)
- --allow_writes (default: false)
- --timeout_ms <number> (default: 15000)
- --concurrency <number> (default: 4)
- --log_level <silent|error|info|debug> (default: info)
- debug: Shows all HTTP requests, responses, and detailed error information
- info: Shows retry attempts and general operational messages
- error: Shows only errors
- silent: No logging output
- --tools_mode <auto|discourse_api_only|tool_exec_api> (default: auto)
- --site <url>: Tether MCP to a single site and hide discourse_select_site.
- --default-search <prefix>: Unconditionally prefix every search query (e.g., tag:ai order:latest-post).
- --max-read-length <number>: Maximum characters returned for post content (default 50000). Applies to discourse_read_post and per-post content in discourse_read_topic. The tools prefer raw content by requesting include_raw=true.
- --transport <stdio|http> (default: stdio): Transport type. Use stdio for standard input/output (default), or http for Streamable HTTP transport (stateless mode with JSON responses).
- --port <number> (default: 3000): Port to listen on when using HTTP transport.
- --cache_dir <path> (reserved)
- --profile <path.json> (see below)

- Profile file (keep secrets off the command line)

{
"auth_pairs": [
{ "site": "https://try.discourse.org", "api_key": "<redacted>", "api_username": "system" },
{ "site": "https://example.com", "user_api_key": "<user_api_key>", "user_api_client_id": "<client_id>" }
],
"read_only": false,
"allow_writes": true,
"log_level": "info",
"tools_mode": "auto",
"site": "https://try.discourse.org",
"default_search": "tag:ai order:latest-post",
"max_read_length": 50000,
"transport": "stdio",
"port": 3000
}

Run with:
node dist/index.js --profile /absolute/path/to/profile.json

Flags still override values from the profile.

- Remote Tool Execution API (optional)
- With tools_mode=auto (default) or tool_exec_api, the server discovers remote tools via GET /ai/tools after you select a site (or immediately at startup if --site is provided) and registers them dynamically. Set --tools_mode=discourse_api_only to disable remote tool discovery.

- Networking & resilience
- Retries on 429/5xx with backoff (3 attempts).
- Lightweight in‑memory GET cache for selected endpoints.

- Privacy
- Secrets are redacted in logs. Errors are returned as human‑readable messages to MCP clients.

- Run (read‑only, recommended to start)

npx -y @discourse/mcp@latest

Then, in your MCP client, either:
- Call the discourse_select_site tool with { "site": "https://try.discourse.org" } to choose a site, or
- Start the server tethered to a site using --site https://try.discourse.org (in which case discourse_select_site is hidden).

- Enable writes (opt‑in, safe‑guarded)

npx -y @discourse/mcp@latest --allow_writes --read_only=false --auth_pairs '[{"site":"https://try.discourse.org","api_key":"'$DISCOURSE_API_KEY'","api_username":"system"}]'

- Use in an MCP client (example: Claude Desktop) — via npx

{
"mcpServers": {
"discourse": {
"command": "npx",
"args": ["-y", "@discourse/mcp@latest"],
"env": {}
}
}
}

> Alternative: if you prefer a global binary after install, the package exposes discourse-mcp.
>

> {
> "mcpServers": {
> "discourse": { "command": "discourse-mcp", "args": [] }
> }
> }
>

```bash

discourse_select_site

Validate and select a Discourse site. Returns JSON with site URL and title.

discourse_search

Search site content. Returns JSON object with results array of matching topics (id, slug, title) and meta (total, has_more).

discourse_filter_topics

Filter topics with a concise query language. Returns JSON object with results array (id, slug, title) and meta (page, limit, has_more). Query syntax: category/categories (comma=OR, '=category'=without subcats, '-'=exclude), tag/tags (comma=OR, '+'=AND), status:(open|closed|archived|listed|unlisted|public), in:(bookmarked|watching|tracking|muted|pinned), dates: created/activity-(before|after) YYYY-MM-DD or N days, order: activity|created|latest-post|likes|views with optional -asc.

discourse_read_topic

Read topic metadata and posts. Returns JSON with id, title, slug, category_id, tags, and posts array.

discourse_read_post

Read a specific post. Returns JSON with id, topic_id, post_number, username, created_at, and raw content.

discourse_get_user

Get user info. Returns JSON with id, username, name, trust_level, created_at, bio, admin, and moderator.

discourse_list_user_posts

Get paginated list of user posts/replies. Returns JSON object with posts array (id, topic_id, post_number, slug, title, created_at, excerpt, category_id) and meta (page, limit, has_more).

discourse_list_users

List users via admin API. Requires admin API key. Returns ~100 users per page (Discourse's fixed page size). Returns JSON with users array and pagination meta.

discourse_get_chat_messages

Get messages from a chat channel. Returns JSON object with channel_id, messages array (id, username, created_at, message, edited, thread_id, in_reply_to_id), and meta.

discourse_get_draft

Retrieve a specific draft by key. Returns JSON with draft_key, sequence, and parsed data (title, reply, categoryId, tags, action).

discourse_get_query

Get full details of a Data Explorer query including SQL and parameters. Requires admin API key.

discourse_run_query

Execute a Data Explorer query with parameters. Returns columns, rows, result_count, duration_ms. Queries run in read-only transactions with 10-second timeout. Requires admin API key.

Built‑in tools (always present unless noted):

- discourse_search
- Input: { query: string; with_private?: boolean; max_results?: number (1–50, default 10) }
- Output: text summary plus a compact footer like:

    { "results": [{ "id": 123, "url": "https://…", "title": "…" }] }

- discourse_read_topic
- Input: { topic_id: number; post_limit?: number (1–20, default 5) }
- discourse_read_post
- Input: { post_id: number }
- discourse_list_categories
- Input: {}
- discourse_list_tags
- Input: {}
- discourse_get_user
- Input: { username: string }
- discourse_filter_topics
- Input: { filter: string; page?: number (default 1); per_page?: number (1–50) }
- Query language (succinct): key:value tokens separated by spaces; category/categories (comma = OR, =category = without subcats, - prefix = exclude); tag/tags (comma = OR, + = AND) and tag_group; status:(open|closed|archived|listed|unlisted|public); personal in: (bookmarked|watching|tracking|muted|pinned); dates: created/activity/latest-post-(before|after) with YYYY-MM-DD or relative days N; numeric: likes[-op]-(min|max), posts-(min|max), posters-(min|max), views-(min|max); order: activity|created|latest-post|likes|likes-op|posters|title|views|category with optional -asc; free text terms are matched.
- discourse_create_post (only when writes enabled; see Write safety)
- Input: { topic_id: number; raw: string (≤ 30k chars) }

- discourse_create_topic (only when writes enabled; see Write safety)
- Input: { title: string; raw: string (≤ 30k chars); category_id?: number; tags?: string[] }

- discourse_create_user (only when writes enabled; see Write safety)
- Input: { username: string (1-20 chars); email: string; name: string; password: string; active?: boolean; approved?: boolean }

- discourse_create_category (only when writes enabled; see Write safety)
- Input: { name: string; color?: hex; text_color?: hex; parent_category_id?: number; description?: string }

Notes:
- Outputs are human‑readable first. Where applicable, a compact JSON is embedded in fenced code blocks to ease structured extraction by agents.

Claude Desktop / Cursor

Paste into your MCP client config file to install this server.

{
    "mcpServers": {
        "discourse mcp server": {
            "discourse": {
                "command": "npx",
                "args": [
                    "-y",
                    "@discourse/mcp@latest"
                ],
                "env": []
            }
        }
    }
}

McpServers

{
    "discourse": {
        "command": "npx",
        "args": [
            "-y",
            "@discourse/mcp@latest"
        ],
        "env": []
    }
}

Step 3: Run the MCP server with your new key

npx @discourse/mcp@latest --profile profile.json --allow_writes --read_only=false

Other Examples

- Read‑only session against try.discourse.org:

bash
npx -y @discourse/mcp@latest --log_level debug

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.