← MCP Security Catalog

Discourse MCP 0.3.1

npm · @discourse/mcp · latest release

Confirmed vulnerable
Security result
16
Observed tools
Version rating
Change risk

Independent inventory

Observed 2026-08-25T08:21:41.539Z using mcpSecurity-inventory. Protocol 2025-06-18.

ToolCategoryRisk
discourse_filter_topicsDiscover topics through a filtered, top, or hot view. Filtered uses Discourse TopicsFilter syntax; top uses Discourse's authoritative top score and defaults to weekly; hot is defined exactly as daily top (not sentiment, controversy, or real-time velocity). Returns a uniform rich topic projection and truthful pagination metadata.
Input schema
{
  "type": "object",
  "properties": {
    "filter": {
      "type": "string",
      "description": "TopicsFilter query (required for the filtered view)"
    },
    "view": {
      "type": "string",
      "enum": [
        "filtered",
        "top",
        "hot"
      ],
      "default": "filtered"
    },
    "top_period": {
      "type": "string",
      "enum": [
        "daily",
        "weekly",
        "monthly",
        "quarterly",
        "yearly",
        "all"
      ],
      "description": "Top period (top view only; defaults to weekly)"
    },
    "page": {
      "type": "integer",
      "minimum": 0,
      "description": "Page number (0-based, default: 0)"
    },
    "per_page": {
      "type": "integer",
      "minimum": 1,
      "maximum": 50,
      "description": "Items per page (default 20, max 50)"
    }
  },
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
discourse_get_chat_messagesGet 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.
Input schema
{
  "type": "object",
  "properties": {
    "channel_id": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "description": "The chat channel ID"
    },
    "page_size": {
      "type": "integer",
      "minimum": 1,
      "maximum": 50,
      "description": "Number of messages to return (default: 50, max: 50)"
    },
    "target_message_id": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "description": "Message ID to query around or paginate from"
    },
    "direction": {
      "type": "string",
      "enum": [
        "past",
        "future"
      ],
      "description": "Pagination direction: 'past' for older messages, 'future' for newer"
    },
    "target_date": {
      "type": "string",
      "description": "ISO 8601 date string to query messages around"
    }
  },
  "required": [
    "channel_id"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
discourse_get_draftRetrieve a specific draft by key. Returns JSON with draft_key, sequence, and parsed data (title, reply, categoryId, tags, action).
Input schema
{
  "type": "object",
  "properties": {
    "draft_key": {
      "type": "string",
      "minLength": 1,
      "maxLength": 40,
      "description": "Draft key (e.g., \"new_topic\", \"topic_123\", \"new_private_message\")"
    },
    "sequence": {
      "type": "integer",
      "minimum": 0,
      "description": "Expected sequence number (optional)"
    }
  },
  "required": [
    "draft_key"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
discourse_get_queryGet full details of a Data Explorer query including SQL and parameters. Requires admin API key.
Input schema
{
  "type": "object",
  "properties": {
    "id": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "description": "Query ID"
    }
  },
  "required": [
    "id"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
discourse_get_userGet user info. Returns JSON with id, username, name, trust_level, created_at, bio, admin, and moderator.
Input schema
{
  "type": "object",
  "properties": {
    "username": {
      "type": "string",
      "minLength": 1
    }
  },
  "required": [
    "username"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
discourse_list_private_messagesList authenticated personal or group private-message mailboxes. Returns normalized JSON messages and pagination metadata.
Input schema
{
  "type": "object",
  "properties": {
    "username": {
      "type": "string"
    },
    "mailbox": {
      "type": "string",
      "enum": [
        "inbox",
        "sent",
        "archive",
        "unread",
        "new"
      ]
    },
    "group_name": {
      "type": "string"
    },
    "page": {
      "type": "integer",
      "minimum": 0
    },
    "per_page": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    }
  },
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
discourse_list_user_postsGet 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).
Input schema
{
  "type": "object",
  "properties": {
    "username": {
      "type": "string",
      "minLength": 1
    },
    "page": {
      "type": "integer",
      "minimum": 0
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 50,
      "description": "Posts per page (max 50, default 30)"
    }
  },
  "required": [
    "username"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
discourse_list_usersList 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.
Input schema
{
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "enum": [
        "active",
        "new",
        "staff",
        "suspended",
        "silenced",
        "pending",
        "staged"
      ],
      "default": "active",
      "description": "User query type"
    },
    "filter": {
      "type": "string",
      "description": "Search by username, email, or IP address"
    },
    "order": {
      "type": "string",
      "enum": [
        "created",
        "last_emailed",
        "seen",
        "username",
        "trust_level",
        "days_visited",
        "posts"
      ],
      "description": "Sort order field"
    },
    "asc": {
      "type": "boolean",
      "default": false,
      "description": "Sort ascending (default: false/descending)"
    },
    "page": {
      "type": "integer",
      "minimum": 0,
      "description": "Page number (0-indexed)"
    }
  },
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
discourse_read_postRead a specific post. Returns JSON with id, topic_id, post_number, username, created_at, and raw content.
Input schema
{
  "type": "object",
  "properties": {
    "post_id": {
      "type": "integer",
      "exclusiveMinimum": 0
    }
  },
  "required": [
    "post_id"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
discourse_read_private_messageRead an authenticated private message, its posts, and direct allowed-user and allowed-group records. Rejects public topics.
Input schema
{
  "type": "object",
  "properties": {
    "topic_id": {
      "type": "integer",
      "exclusiveMinimum": 0
    },
    "post_limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 50,
      "description": "Max posts to return (default 5, max 50)"
    },
    "start_post_number": {
      "type": "integer",
      "minimum": 1,
      "description": "Start from this post number (1-based)"
    }
  },
  "required": [
    "topic_id"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
discourse_read_topicRead topic metadata and posts. Large post limits can require multiple upstream requests. For moderation queues, prefer reviewable list/detail evidence instead of fanning this tool out across flagged topics.
Input schema
{
  "type": "object",
  "properties": {
    "topic_id": {
      "type": "integer",
      "exclusiveMinimum": 0
    },
    "post_limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 50,
      "description": "Max posts to return (default 5, max 50)"
    },
    "start_post_number": {
      "type": "integer",
      "minimum": 1,
      "description": "Start from this post number (1-based)"
    }
  },
  "required": [
    "topic_id"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
discourse_read_topic_postsRead exact, earliest, latest, around-post, or username-filtered topic evidence. Selection is bounded to 50 posts and reports the visible stream size without claiming the entire topic was loaded.
Input schema
{
  "type": "object",
  "properties": {
    "topic_id": {
      "type": "integer",
      "exclusiveMinimum": 0
    },
    "selection_mode": {
      "type": "string",
      "enum": [
        "latest",
        "earliest",
        "post_ids",
        "around_post",
        "usernames"
      ]
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 50
    },
    "post_ids": {
      "type": "array",
      "items": {
        "type": "integer",
        "exclusiveMinimum": 0
      },
      "minItems": 1,
      "maxItems": 50
    },
    "post_number": {
      "type": "integer",
      "exclusiveMinimum": 0
    },
    "usernames": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      },
      "minItems": 1,
      "maxItems": 50
    },
    "replies_only": {
      "type": "boolean"
    }
  },
  "required": [
    "topic_id",
    "selection_mode"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
discourse_run_queryExecute 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.
Input schema
{
  "type": "object",
  "properties": {
    "id": {
      "type": "integer",
      "description": "Query ID to run"
    },
    "params": {
      "type": "object",
      "additionalProperties": {},
      "description": "Query parameters as key-value pairs"
    },
    "limit": {
      "anyOf": [
        {
          "type": "integer",
          "exclusiveMinimum": 0
        },
        {
          "type": "string",
          "const": "ALL"
        }
      ],
      "description": "Maximum number of rows to return (default: query default, use 'ALL' for unlimited)"
    },
    "explain": {
      "type": "boolean",
      "description": "Include query execution plan in response"
    }
  },
  "required": [
    "id"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
discourse_searchSearch site content. Returns JSON object with results array of matching topics (id, slug, title) and meta (total, has_more).
Input schema
{
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "minLength": 1,
      "description": "Search query"
    },
    "max_results": {
      "type": "integer",
      "minimum": 1,
      "maximum": 50
    }
  },
  "required": [
    "query"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
discourse_search_postsSearch post-level evidence with Discourse query syntax. Unlike discourse_search, this preserves matched posts, highlighted blurbs, authors, topics, categories, and truthful bounded continuation. This is keyword search, not Discourse AI semantic search.
Input schema
{
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "minLength": 1
    },
    "page": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10
    }
  },
  "required": [
    "query"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}
Annotations
{
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
discourse_select_siteValidate and select a Discourse site. Returns JSON with site URL and title.
Input schema
{
  "type": "object",
  "properties": {
    "site": {
      "type": "string",
      "format": "uri",
      "description": "Base URL of the Discourse site"
    }
  },
  "required": [
    "site"
  ],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}

Resources 8

Resource templates 2

Prompts 1

Changes from previous version

No completed comparison is available.

RiskChangeSubject
No material changes recorded.

Confirmed vulnerabilities

SeverityFindingAdvisory
highSsrf in @discourse/mcp (tool discourse_filter_topics, argument filter)MCPSEC-1021CC946DF3BE0F
highSsrf in @discourse/mcp (tool discourse_get_chat_messages, argument target_date)MCPSEC-50E8F2A734EB8445
highSsrf in @discourse/mcp (tool discourse_get_draft, argument draft_key)MCPSEC-B968D454060B0E54
highSsrf in @discourse/mcp (tool discourse_get_user, argument username)MCPSEC-E1AED05CF366E300
highSsrf in @discourse/mcp (tool discourse_list_user_posts, argument username)MCPSEC-AD7C8E28F12A8494
highSsrf in @discourse/mcp (tool discourse_search, argument query)MCPSEC-6EE1E652F228B813
highSsrf in @discourse/mcp (tool discourse_select_site, argument site)MCPSEC-308AFFABF88E6DB1

Provenance

Artifact SHA-256: 91e6df1d0bd07e4f443bb368a5230718f89ce4319010b009af5d024dfd24704e

Scanner: mcp-proof-engine 0.1.0.

Let’s talk about MCP security.

Share your details and our security team will contact you.