Skip to main content
Glama
devzspy

discourse-mcp-extended

by devzspy

Discourse MCP (extended fork)

This is a fork of discourse/discourse-mcp, extended with tools for working the Discourse review queue (/review) — listing pending/flagged items and approving or rejecting them. Everything else is unchanged from upstream. See What's added in this fork below.

A Model Context Protocol (MCP) stdio server that exposes Discourse forum capabilities as tools and resources for AI agents.

  • Entry point: src/index.ts → compiled to dist/index.js (binary name: discourse-mcp)

  • SDK: @modelcontextprotocol/sdk

  • Node: >= 24

  • Version: 0.2.4 (0.2.x has breaking changes from 0.1.x - JSON-only output, resources replace list tools)

What's added in this fork

  • discourse_list_reviewables — list items in the review queue (as seen at /review?sort_order=score), e.g. new/queued posts awaiting approval and flagged posts. Requires an admin or moderator API key/user API key for the site.

  • discourse_perform_reviewable_action — approve, reject, or otherwise act on a review queue item (only registered when writes are enabled, same as other write tools).

Full input/output details are in the Tools section below. Since this build isn't published to npm, run it locally from a build of this repo (pnpm install && pnpm build, then point your MCP client at dist/index.js) instead of npx @discourse/mcp@latest.

Quick start (release)

  • 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": [] }
  }
}

Related MCP server: MCP-Discord

Configuration

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":"..."}]'

    • HTTP Basic Auth (for sites behind a reverse proxy): Add http_basic_user and http_basic_pass to any auth_pairs entry. This is useful for Discourse sites protected by HTTP Basic Authentication at the reverse proxy level.

    • 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.

    • Write tools (discourse_create_post, discourse_create_topic, discourse_create_category, discourse_update_topic, discourse_create_user, discourse_update_user, discourse_upload_file, discourse_save_draft, discourse_delete_draft, discourse_perform_reviewable_action) are only registered when --allow_writes AND not --read_only.

    • Write tools require a matching auth_pairs entry for the selected site; otherwise they return an error.

    • 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

    • --show_emails (default: false). includes emails in user tools. Requires admin access

    • --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).

    • --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.

    • --allowed_upload_paths <paths>: Comma-separated list or JSON array of directories allowed for local file uploads. Required to enable local file uploads in discourse_upload_file. Example: --allowed_upload_paths "/home/user/images,/tmp/uploads" or --allowed_upload_paths '["/home/user/images"]'

    • --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>"
    },
    {
      "site": "https://protected.example.com",
      "api_key": "<redacted>",
      "api_username": "system",
      "http_basic_user": "username",
      "http_basic_pass": "password"
    }
  ],
  "read_only": false,
  "allow_writes": true,
  "show_emails": true,
  "log_level": "info",
  "tools_mode": "auto",
  "site": "https://try.discourse.org",
  "default_search": "tag:ai order:latest",
  "max_read_length": 50000,
  "transport": "stdio",
  "port": 3000,
  "allowed_upload_paths": ["/home/user/images", "/tmp/uploads"]
}

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.

MCP Resources

Resources provide static/semi-static read-only data via URI addressing. Use these instead of tools for listing operations.

  • discourse://site/categories

    • List all categories with hierarchy and permissions

    • Output: { categories: [{id, name, slug, pid, read_restricted, topic_count, post_count, perms}], meta: {total} }

    • perms is array of {gid, perm} where perm: 1=full, 2=create_post, 3=readonly

    • Note: perms is only populated with admin/moderator auth. Without admin auth, only read_restricted boolean is available.

  • discourse://site/tags

    • List all tags with usage counts

    • Output: { tags: [{id, name, count}], meta: {total} }

  • discourse://site/groups

    • List all groups with visibility, interaction levels, and access settings

    • Output: { groups: [{id, name, automatic, user_count, vis, members_vis, mention, msg, public_admission, public_exit, allow_membership_requests}], meta: {total} }

    • Levels (0-4): 0=public, 1=logged_on_users, 2=members, 3=staff, 4=owners

    • Use case: Resolve gid values from category permissions to group names, replicate group settings during migrations

  • discourse://chat/channels

    • List all public chat channels

    • Output: { channels: [{id, title, slug, status, members_count, description}], meta: {total} }

  • discourse://user/chat-channels

    • List user's chat channels (public + DMs) with unread/mention counts

    • Output: { public_channels: [...], dm_channels: [...], meta: {total} }

    • Requires authentication

  • discourse://user/drafts

    • List user's drafts

    • Output: { drafts: [{draft_key, sequence, title, category_id, created_at, reply_preview}], meta: {total} }

    • Requires authentication

Tools

Built‑in tools (always present unless noted). All tools return strict JSON (no Markdown).

  • discourse_search

    • Input: { query: string; max_results?: number (1–50, default 10) }

    • Output: { results: [{id, slug, title}], meta: {total, has_more} }

  • discourse_read_topic

    • Input: { topic_id: number; post_limit?: number (1–50, default 5); start_post_number?: number }

    • Output: { id, title, slug, category_id, tags, posts_count, posts: [{id, post_number, username, created_at, raw}], meta }

  • discourse_read_post

    • Input: { post_id: number }

    • Output: { id, topic_id, topic_slug, post_number, username, created_at, raw, truncated }

  • discourse_get_user

    • Input: { username: string }

    • Output: { id, username, name, trust_level, created_at, bio, admin, moderator }

  • discourse_list_user_posts

    • Input: { username: string; page?: number (0-based); limit?: number (1–50, default 30) }

    • Output: { posts: [{id, topic_id, post_number, slug, title, created_at, excerpt, category_id}], meta: {page, limit, has_more} }

  • discourse_filter_topics

    • Input: { filter: string; page?: number; per_page?: number (1–50) }

    • Output: { results: [{id, slug, title}], meta: {page, limit, has_more} }

    • 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_get_chat_messages

    • Input: { channel_id: number; page_size?: number (1–50, default 50); target_message_id?: number; direction?: "past" | "future"; target_date?: string (ISO 8601) }

    • Output: { channel_id, messages: [{id, username, created_at, message, edited, thread_id, in_reply_to_id}], meta }

  • discourse_get_draft

    • Input: { draft_key: string; sequence?: number }

    • Output: { draft_key, sequence, found, data: {title, reply, category_id, tags, action} }

  • discourse_list_reviewables (requires admin/moderator API key)

    • Input: { status?: "pending"|"approved"|"rejected"|"ignored"|"deleted"|"reviewed"|"all"; type?: string; priority?: "low"|"medium"|"high"; sort_order?: "score"|"score_asc"|"created_at"|"created_at_asc"; category_id?: number; topic_id?: number; page?: number }

    • Output: { reviewables: [{id, type, status, score, created_at, topic_id, category_id, post_id, target_user_id, created_by, target_created_by, title, excerpt, version, actions}], meta: {page, limit, total, has_more} }

    • Lists items from the review queue (as seen at /review?sort_order=score), including new/queued posts awaiting approval and flagged posts. actions is the list of valid action ids for that item (e.g. approve_post, reject_post, agree_and_hide, disagree, delete) to pass to discourse_perform_reviewable_action. 10 items per page (Discourse's fixed page size).

  • discourse_perform_reviewable_action (only when writes enabled; see Write safety)

    • Input: { reviewable_id: number; action_id: string; version: number; reject_reason?: string; revise_feedback?: string }

    • Output: { success, reviewable_id, action_id, version, created_post_id, created_post_topic_id, reviewable_updates }

    • Approves, rejects, or otherwise acts on a review queue item. Use discourse_list_reviewables first to get the reviewable_id, current version, and valid action_id values for that specific item.

  • discourse_save_draft (only when writes enabled; see Write safety)

    • Input: { draft_key: string; reply: string; title?: string; category_id?: number; tags?: string[]; sequence?: number (default 0); action?: "createTopic" | "reply" | "edit" | "privateMessage" }

    • Output: { draft_key, sequence, saved }

  • discourse_delete_draft (only when writes enabled; see Write safety)

    • Input: { draft_key: string; sequence: number }

    • Output: { draft_key, deleted }

  • discourse_create_post (only when writes enabled; see Write safety)

    • Input: { topic_id: number; raw: string (<= 30k chars); author_username?: string }

    • Output: { id, topic_id, post_number }

  • discourse_create_topic (only when writes enabled; see Write safety)

    • Input: { title: string; raw: string (<= 30k chars); category_id?: number; tags?: string[]; author_username?: string }

    • Output: { id, topic_id, slug, title }

  • discourse_update_topic (only when writes enabled; see Write safety)

    • Input: { topic_id: number; title?: string; category_id?: number; tags?: string[]; featured_link?: string; original_title?: string; original_tags?: string[] }

    • Output: { success, topic_id, updated_fields, topic: {id, title, slug, category_id, tags, featured_link} }

  • discourse_list_users (requires admin API key)

    • Input: { query?: "active"|"new"|"staff"|"suspended"|"silenced"|"pending"|"staged"; filter?: string; order?: "created"|"last_emailed"|"seen"|"username"|"trust_level"|"days_visited"|"posts"; asc?: boolean; page?: number }

    • Output: { users: [{id, username, name, email, avatar_template, trust_level, created_at, last_seen_at, admin, moderator, suspended, silenced}], meta: {page, has_more} }

    • Note: Returns ~100 users per page (Discourse's fixed page size). avatar_template contains {size} placeholder - replace with pixel size (e.g., 120) to get avatar URL

  • 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; upload_id?: number }

    • Output: { success, username, name, email, active, avatar_updated, message, avatar_error? }

    • Note: If upload_id is provided but avatar update fails, avatar_error contains the error message

  • discourse_update_user (only when writes enabled; see Write safety)

    • Input: { username: string; name?: string; bio_raw?: string; location?: string; website?: string; title?: string; date_of_birth?: string; locale?: string; profile_background_upload_url?: string; card_background_upload_url?: string; upload_id?: number }

    • Output: { success, username, updated_fields, avatar_updated, user: {...}, avatar_error? }

    • Note: If upload_id is provided but avatar update fails, avatar_error contains the error message

  • discourse_upload_file (only when writes enabled; see Write safety)

    • Input: { upload_type: "avatar"|"profile_background"|"card_background"|"composer"; image_data?: string (base64); url?: string; filename?: string; user_id?: number }

    • Output: { id, url, short_url, short_path, original_filename, extension, width, height, filesize, human_filesize }

    • Constraints:

      • Provide exactly one of: image_data (requires filename), remote HTTP(S) URL, or absolute local file path

      • user_id is required for avatar/profile_background/card_background uploads

      • Local file uploads require --allowed_upload_paths configuration (security: prevents arbitrary file reads)

    • Note: Use short_url (e.g., upload://abc123.png) to embed images in posts.

  • discourse_create_category (only when writes enabled; see Write safety)

    • Input: { name: string; color?: hex; text_color?: hex; emoji?: string; icon?: string; parent_category_id?: number; description?: string }

    • Output: { id, slug, name }

  • discourse_select_site (hidden when --site is provided)

    • Input: { site: string }

    • Output: { site, title }

Development

  • Requirements: Node >= 24, pnpm.

  • Install / Build / Typecheck / Test

pnpm install
pnpm typecheck
pnpm build
pnpm test
  • Run locally (with source maps)

pnpm build && pnpm dev
  • Project layout

    • Server & CLI: src/index.ts

    • HTTP client: src/http/client.ts

    • Tool registry: src/tools/registry.ts

    • Resource registry: src/resources/registry.ts

    • Built‑in tools: src/tools/builtin/*

    • Remote tools: src/tools/remote/tool_exec_api.ts

    • JSON helpers: src/util/json_response.ts

    • Logging/redaction: src/util/logger.ts, src/util/redact.ts

  • Testing notes

    • Tests run with Node’s test runner against compiled artifacts (dist/test/**/*.js). Ensure pnpm build before pnpm test if invoking scripts individually.

  • Publishing (optional)

    • The package is published as @discourse/mcp and exposes a bin named discourse-mcp. Prefer npx @discourse/mcp@latest for frictionless usage.

  • Conventions

    • All outputs are JSON-only for reliable programmatic parsing by agents.

    • Be careful with write operations; keep them opt‑in and rate‑limited.

See AGENTS.md for additional guidance on using this server from agent frameworks.

Examples

Quick Start with User API Key (No Admin Required)

# Step 1: Generate a User API Key
npx @discourse/mcp@latest generate-user-api-key \
  --site https://discourse.example.com \
  --save-to profile.json

# Step 2: Visit the authorization URL shown, approve the request, and paste the payload

# 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:

npx -y @discourse/mcp@latest --log_level debug
# In client: call discourse_select_site with {"site":"https://try.discourse.org"}
  • Tether to a single site:

npx -y @discourse/mcp@latest --site https://try.discourse.org
  • Create a post with Admin API Key (writes enabled):

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"}]'
  • Create a post with User API Key (writes enabled, no admin required):

npx -y @discourse/mcp@latest --allow_writes --read_only=false --auth_pairs '[{"site":"https://try.discourse.org","user_api_key":"'$DISCOURSE_USER_API_KEY'"}]'
  • Create a category (writes enabled):

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"}]'
# In your MCP client, call discourse_create_category with for example:
# { "name": "AI Research", "color": "0088CC", "text_color": "FFFFFF", "description": "Discussions about AI research" }
  • Create a topic (writes enabled):

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"}]'
# In your MCP client, call discourse_create_topic, for example:
# { "title": "Agentic workflows", "raw": "Let's discuss agent workflows.", "category_id": 1, "tags": ["ai","agents"] }
  • Run with HTTP transport (on port 3000):

npx -y @discourse/mcp@latest --transport http --port 3000 --site https://try.discourse.org
# Server will start on http://localhost:3000
# Health check: http://localhost:3000/health
# MCP endpoint: http://localhost:3000/mcp
  • Connect to a site behind HTTP Basic Auth:

npx -y @discourse/mcp@latest --auth_pairs '[{"site":"https://protected.example.com","api_key":"'$DISCOURSE_API_KEY'","api_username":"system","http_basic_user":"username","http_basic_pass":"password"}]' --site https://protected.example.com

Authentication

Admin API Keys vs User API Keys

This MCP server supports two types of Discourse API authentication:

  1. Admin API Keys (api_key + api_username)

    • Require admin/moderator permissions to generate

    • Created via Admin Panel → API → New API Key

    • Can perform all operations including user/category creation

    • Use headers: Api-Key and Api-Username

  2. User API Keys (user_api_key + optional user_api_client_id)

    • Can be generated by any user (no admin required)

    • User-specific permissions and rate limits

    • Ideal for personal use and non-admin operations

    • Use headers: User-Api-Key and User-Api-Client-Id

    • Auto-expire after 180 days of inactivity (configurable per site)

    • Learn more: https://meta.discourse.org/t/user-api-keys-specification/48536

Obtaining a User API Key

This package includes a convenient command to generate User API Keys:

# Interactive mode - follow the prompts
npx @discourse/mcp@latest generate-user-api-key --site https://discourse.example.com

# Save directly to a profile file
npx @discourse/mcp@latest generate-user-api-key --site https://discourse.example.com --save-to profile.json

# Specify custom scopes
npx @discourse/mcp@latest generate-user-api-key --site https://discourse.example.com --scopes "read,write,notifications"

# Get help
npx @discourse/mcp@latest generate-user-api-key --help

The command will:

  1. Generate an RSA key pair

  2. Display an authorization URL for you to visit

  3. Prompt you to paste the encrypted payload after authorization

  4. Decrypt and display your User API Key

  5. Optionally save it to a profile file

Manual Method

User API Keys require an OAuth-like flow documented at https://meta.discourse.org/t/user-api-keys-specification/48536. Key steps:

  1. Generate a public/private key pair

  2. Request authorization via /user-api-key/new with your public key, application name, client ID, and requested scopes

  3. User approves the request (after login if needed)

  4. Discourse returns an encrypted payload with the User API Key

  5. Decrypt using your private key and use the key in your configuration

You can also manually create User API Keys via the Discourse UI (if enabled by the site):

  • Visit your user preferences → Security → API

  • Or use third-party tools that implement the User API Key flow

FAQ

  • Why is create_post missing? You're in read‑only mode. Enable writes as described above.

  • Can I disable remote tool discovery? Yes, run with --tools_mode=discourse_api_only.

  • Can I avoid exposing discourse_select_site? Yes, start with --site <url> to tether to a single site.

  • Time outs or rate limits? Increase --timeout_ms, and note built‑in retry/backoff on 429/5xx.

  • Should I use Admin API Keys or User API Keys? Use User API Keys for personal use (no admin required). Use Admin API Keys only when you need admin-level operations or are setting up a system-wide integration.

  • Getting "fetch failed" errors? Run with --log_level debug to see detailed error information including:

    • The exact URL being requested

    • HTTP status codes and response bodies

    • Network-level errors (DNS, SSL/TLS, connectivity issues)

    • Retry attempts and timing

    • Timeout diagnostics

Available Tools

13 tools
discourse_filter_topicsFilter TopicsA

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number (0-based, default: 0)
filterYesFilter query, e.g. 'category:support status:open created-after:30 order:activity'
per_pageNoItems per page (max 50)

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses the return format (JSON with results and meta), including pagination fields (page, limit, has_more), and explains the query syntax thoroughly. It does not explicitly state side effects or permissions, but the read-only nature is strongly implied by 'filter' and the output description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized. The opening sentence states the core purpose, the second sentence covers the return format, and the remainder compactly lists query syntax options. Every sentence provides necessary information, and the structure is easy to scan despite its length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has a complex query language and no output schema, so the description must compensate. It does so by specifying the exact return shape (results array with id, slug, title; meta with page, limit, has_more) and covering the major query facets: category, tag, status, in, date, and order. This makes the behavior of the tool understandable without additional schema information.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but the description goes far beyond by detailing the entire query language syntax, including operators for categories, tags, status, in-options, date filters, and ordering. This adds substantial meaning beyond the schema's simple example and parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool filters topics using a concise query language, and it distinguishes itself from siblings like discourse_search by describing the specific filtering capabilities and output format. The verb 'filter' and resource 'topics' are explicitly named, making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use this tool—when you need to filter topics by categories, tags, status, date, or ordering—and provides a detailed query syntax. However, it does not explicitly contrast with alternatives like discourse_search or state when not to use it, so clear context is provided but exclusions are absent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

discourse_get_chat_messagesGet Chat MessagesC

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
directionNoPagination direction: 'past' for older messages, 'future' for newer
page_sizeNoNumber of messages to return (default: 50, max: 50)
channel_idYesThe chat channel ID
target_dateNoISO 8601 date string to query messages around
target_message_idNoMessage ID to query around or paginate from

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

There are no annotations, so the description carries full responsibility for behavioral disclosure. It reveals the return object structure but does not mention pagination behavior, how parameters like direction or target_date interact, authentication requirements, or that it is a read-only operation. The description adds minimal behavioral context beyond the action verb.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences, front-loaded with the primary action and scope, followed by a concise breakdown of the return structure. There is no wasted wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has 5 parameters, no annotations, and no output schema, but the description only explains the return structure. It does not clarify pagination semantics, defaults, or how to combine direction, target_date, and target_message_id. The description is not rich enough for the tool's complexity, even with the schema providing parameter descriptions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with all five parameters documented. The description adds no parameter-level detail beyond what the schema already provides, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool gets messages from a chat channel, specifying the resource and action. However, it does not explicitly differentiate from sibling tools like discourse_read_topic or discourse_get_query, though the chat channel scope implies distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. The description only states what it does, not when it should be preferred, nor does it mention any exclusions or alternative tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

discourse_get_draftGet DraftA

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

ParametersJSON Schema
NameRequiredDescriptionDefault
sequenceNoExpected sequence number (optional)
draft_keyYesDraft key (e.g., "new_topic", "topic_123", "new_private_message")

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of behavioral disclosure. It states the operation is a read ('Retrieve') and describes the response format, which is useful. But it omits details like error behavior, authentication requirements, or whether the sequence parameter is validated. This is acceptable but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is one sentence, front-loaded with the action and target, and includes a compact list of return fields. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read tool with 2 parameters and no output schema, the description covers the essential aspects: what it does, what input it takes (via schema), and what it returns. It doesn't document edge cases, but the tool is straightforward enough that this is not a significant gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are already well-documented in the schema. The description adds little beyond restating that the draft is retrieved by key and referencing the returned fields. The baseline of 3 applies because the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Retrieve') and resource ('specific draft by key'), clearly distinguishing it from sibling tools that handle users, topics, queries, etc. It also previews the returned fields, making the tool's scope unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage: when you need a draft by its key. It provides clear context on what the tool does, but does not explicitly mention when not to use it or name alternatives. However, no sibling tool deals with drafts, so this is adequate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

discourse_get_queryGet Data Explorer QueryA

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

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesQuery ID

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of disclosing behavior. It mentions the admin API key requirement, which is useful auth context, and 'Get' implies a read-only operation. However, it does not explicitly confirm non-mutating behavior, describe error handling, or detail the response structure beyond SQL and parameters.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with zero filler. It front-loads the core purpose and includes a critical prerequisite (admin key) without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-parameter GET tool with no output schema, the description adequately covers the return content (SQL and parameters) and an access constraint. It is thorough enough for an agent to select and invoke correctly, though it omits potential error behaviors or response format details.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already provides 100% coverage with a description for the 'id' parameter ('Query ID'), and the description adds context by specifying it's a Data Explorer query ID and that details include SQL/parameters. This adds marginal value beyond the schema but does not fully compensate since the parameter meaning is straightforward.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's action ('Get full details') and resource ('Data Explorer query'), and specifies the scope ('including SQL and parameters'). This distinguishes it from sibling tools like discourse_run_query, which executes queries rather than retrieving their definitions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this tool is for retrieving query metadata rather than executing it, and the admin API key requirement provides context for when it can be used. However, it does not explicitly state when not to use it or mention alternative tools, though the sibling discourse_run_query clearly serves a different purpose.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

discourse_get_userGet UserB

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

ParametersJSON Schema
NameRequiredDescriptionDefault
usernameYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It lists the return fields, which provides some transparency, but it omits error handling, authentication requirements, and an explicit statement that this is a read-only operation. The added behavioral context is partial.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise: two sentences with the action front-loaded. It lists the returned fields efficiently without unnecessary detail, making it easy to scan.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter read tool, the description covers the return fields but lacks mention of the required parameter, error behavior, and usage context. It is marginally adequate but leaves gaps that the agent would need to resolve.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description does not mention the 'username' parameter at all. The parameter name and tool name imply its meaning, but the description fails to connect the parameter to the tool's function, so it adds no meaningful semantic value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves user info and enumerates the returned fields, distinguishing it from siblings like discourse_list_users by implying a single-user lookup. The verb 'Get' and resource 'user info' are specific and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool vs alternatives like discourse_list_users or discourse_search. The description does not mention selection criteria, prerequisites, or exclusions, leaving the agent to infer usage from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

discourse_list_reviewablesList ReviewablesB

List items in the review queue (as seen at /review), e.g. queued/pending posts and flagged posts. Returns JSON with reviewables array (id, type, status, score, created_at, topic_id, category_id, post_id, created_by, target_created_by, title, excerpt, version, actions) and meta (page, limit, has_more, total). The actions array lists valid action ids for discourse_perform_reviewable_action (e.g. approve_post, reject_post, agree_and_hide, disagree, delete).

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number (0-based, 10 items per page - Discourse's fixed page size)
typeNoFilter by reviewable type, e.g. ReviewableQueuedPost, ReviewableFlaggedPost, ReviewableUser
statusNoFilter by status (default: pending)
priorityNoMinimum priority filter
topic_idNo
sort_orderNoSort order (default: score, matching /review?sort_order=score)
category_idNo

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden for behavioral disclosure. It describes the response structure and links to another tool but does not state whether the tool is read-only, requires authentication, has rate limits, or any side effects. The read-only nature is implied but not explicit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two efficient sentences that front-load the purpose and follow with response details and cross-tool references. Every sentence adds value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description provides a good overview of the response and connections to another tool, but given 7 parameters and no annotations, it lacks complete guidance on parameter semantics and usage context. It is adequate but has clear gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 71% but the description adds no additional parameter information beyond what the schema already provides. Two parameters (topic_id, category_id) lack descriptions even in the schema, but the description does not fill that gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists items in the review queue with concrete examples (queued/pending posts, flagged posts). It explicitly differentiates from sibling tools by focusing on reviewable items, which is distinct from topics or users.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives like discourse_filter_topics or discourse_search. The description does not provide context or exclusions for usage, leaving the agent without decision support.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

discourse_list_user_postsList User PostsA

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo
limitNoPosts per page (max 50, default 30)
usernameYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must carry the full burden. The verb 'Get' implies a read-only operation, and the return structure is disclosed (posts array and meta). However, it does not explicitly state side effects, authentication needs, or that it never modifies data, which is a minor gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that front-loads the core action and includes a concise summary of the return shape. No filler or unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple list tool with no output schema, the description adequately explains what is returned and the pagination structure. It lacks details on ordering or filtering, but given the low complexity (3 params, no nested objects), it is sufficiently complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 33% (only limit is described). The description adds context by mentioning pagination and the meta fields (page, limit, has_more), but it doesn't explain the username or page parameters beyond their names. It provides marginal value but does not fully compensate for the schema gaps.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Get paginated list of user posts/replies' with a specific verb and resource, which distinguishes it from sibling tools like discourse_list_users (lists all users) and discourse_read_post (reads a single post).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the use case (listing a user's posts) clearly, but it does not explicitly mention alternatives or when-not-to-use. Since the context is obvious and no exclusions are needed, it earns a 4.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

discourse_list_usersList UsersA

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
ascNoSort ascending (default: false/descending)
pageNoPage number (0-indexed)
orderNoSort order field
queryNoUser query typeactive
filterNoSearch by username, email, or IP address

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden. It discloses the auth requirement (admin API key), pagination behavior (~100 users per page), and response structure (JSON with users array and pagination meta). It does not cover potential errors or rate limits, but the provided details are meaningful.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, front-loaded with the purpose, and each sentence provides useful information: admin API requirement, fixed page size, and response format. No waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a list tool with 5 parameters and no output schema, the description covers the essential behavioral aspects (pagination, response format, auth). It does not explain retry behavior or error handling, but these are not critical for a simple list endpoint.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema descriptions cover all 5 parameters (100% coverage) with definitions, defaults, and enums, so the description adds no parameter-specific meaning. Baseline of 3 is appropriate since the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the specific action 'List users' and the resource via 'admin API', clearly distinguishing from sibling tools like discourse_get_user (which retrieves a single user) and discourse_list_user_posts (which lists a user's posts). It also mentions the response format, reinforcing scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context by stating 'Requires admin API key', implying it is for admin-level user listing. It does not explicitly name alternatives or state when not to use it, but the admin requirement and the plural 'users' offer reasonable guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

discourse_read_postRead PostA

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

ParametersJSON Schema
NameRequiredDescriptionDefault
post_idYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the burden of behavioral disclosure. It correctly identifies this as a read operation and lists the exact JSON fields returned. However, it omits any mention of error conditions, permissions, or potential side effects, which would be expected for full transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, focused sentence. It is front-loaded with the primary purpose and wastes no words, making it highly concise and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Although the tool is simple, the description provides enough context for a basic read operation: it states the resource type, the key input, and the format of returned data. With no output schema, listing the returned fields is helpful. It falls short only in not mentioning any edge cases or error scenarios, but given the tool's simplicity, this is acceptable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description should compensate by explaining the post_id parameter. However, it merely says 'a specific post' without explicitly stating that post_id identifies the post. The parameter name in the schema does the heavy lifting, but the description adds no semantic value beyond what is already obvious.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Read a specific post') and identifies the resource (a post). It distinguishes itself from sibling tools like discourse_read_topic by focusing on a single post. The mention of returned fields adds specificity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. It does not mention exclusions or explicitly contrast with sibling tools. The purpose implies you need a post_id, but no contextual usage hints are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

discourse_read_topicRead TopicB

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

ParametersJSON Schema
NameRequiredDescriptionDefault
topic_idYes
post_limitNoMax posts to return (default 5, max 50)
start_post_numberNoStart from this post number (1-based)

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations are absent, so the description carries full behavioral burden. It discloses the return format (JSON with specific fields) but omits handling of large topics, pagination defaults, or post array structure. Some transparency is provided, but deeper behavioral context is missing.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, direct, and front-loaded with the main purpose ('Read topic metadata and posts') followed by return details. No unnecessary words or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 3 parameters, no output schema, and no annotations, the description covers basic purpose and output fields but omits pagination behavior, post array details, and any context about topic_id. It is moderately complete but leaves gaps that could affect correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 67% (post_limit and start_post_number have descriptions), but the tool description adds no parameter semantics. It does not mention how to specify a topic or pagination behavior, leaving the agent reliant on the schema alone. Since coverage is not high, the description should compensate more.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Read') with a clear resource ('topic') and explicitly states what is returned (metadata and posts). This distinguishes it from sibling tools like discourse_read_post (which likely targets a single post) and discourse_filter_topics (which filters topics).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives like discourse_read_post or discourse_search. It does not mention prerequisites, exclusions, or typical use cases, leaving the agent without explicit decision support.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

discourse_run_queryRun Data Explorer QueryA

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesQuery ID to run
limitNoMaximum number of rows to return (default: query default, use 'ALL' for unlimited)
paramsNoQuery parameters as key-value pairs
explainNoInclude query execution plan in response

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and discloses important behavioral traits: read-only transactions, 10-second timeout, admin API key requirement, and the return fields. This adds meaningful context beyond the schema, though it stops short of describing all edge cases like error handling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded, every clause earns its place. The description efficiently covers purpose, return format, safety, timeout, and authorization without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (4 params, nested objects, no output schema), the description provides sufficient context: return shape, execution constraints, and auth. It could enumerate more behavioral details, but the schema covers parameter semantics well.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds no parameter-specific meaning beyond what the schema already provides, but it doesn't need to since all parameters are well-documented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool executes a Data Explorer query with parameters, using specific verbs and defining the resource. It distinguishes from siblings like discourse_get_query by focusing on execution, though it does not explicitly name alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit when-to-use or alternative guidance is provided. The purpose implies usage but there is no context about choosing this over other tools, prerequisites beyond admin API key, or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

discourse_select_siteSelect SiteA

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

ParametersJSON Schema
NameRequiredDescriptionDefault
siteYesBase URL of the Discourse site

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It mentions 'validate' and returning JSON, but does not explain what validation entails (e.g., network request, error behavior), what 'select' means for subsequent tools, or any side effects. This is a significant gap for a tool that likely sets the working context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise—two sentences that immediately communicate the core purpose and return format. Every word earns its place, and the front-loaded verb makes the tool's function instantly clear.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter, no output schema), the description is partially complete. It states the purpose and return format, but lacks details about validation behavior, error handling, or how this selection affects other tools. This leaves notable ambiguity for an AI agent using the tool for multi-step workflows.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already describes the only parameter ('site' as 'Base URL of the Discourse site') with 100% coverage. The description reinforces the site concept but adds no new parameter-level meaning beyond the schema, so the baseline score of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific action ('Validate and select') on a specific resource ('a Discourse site'), and distinguishes this tool from the sibling tools which all perform operations on an already-selected site. The return value ('JSON with site URL and title') further clarifies the tool's role.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage context is implied by the tool's name and sibling set (this must be called before other discourse_* tools), but the description does not explicitly state when to use it or mention alternatives. There is no direct guidance on prerequisites or sequencing, so it earns a mid-range score.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 13 tool updatesv0.1.0
    • First observeddiscourse_filter_topics
    • First observeddiscourse_get_chat_messages
    • First observeddiscourse_get_draft
    • First observeddiscourse_get_query
    • First observeddiscourse_get_user
    • First observeddiscourse_list_reviewables
    • First observeddiscourse_list_user_posts
    • First observeddiscourse_list_users
    • First observeddiscourse_read_post
    • First observeddiscourse_read_topic
    • First observeddiscourse_run_query
    • First observeddiscourse_search
    • First observeddiscourse_select_site

TDQS

A3.7/5.0

Scored across 13 tools

Disambiguation5/5

Each tool targets a distinct resource and action: filtering topics, retrieving chat messages, drafts, queries, user info, reviewables, user posts, user lists, posts, topics, executing queries, searching, and site selection. There is no ambiguity between tools.

Naming Consistency5/5

All tools follow a consistent 'discourse_verb_noun' pattern using snake_case. Verbs like 'filter', 'get', 'list', 'read', 'run', 'search', and 'select' are used logically with corresponding nouns.

Tool Count5/5

13 tools provide a well-scoped coverage for a Discourse integration, covering topics, posts, users, chat, admin queries, review queue, and site selection without being excessive.

Completeness3/5

The set covers many read operations but lacks write actions (create/update/delete for topics, posts, users) and notably omits a tool to perform reviewable actions, which is referenced in list_reviewables. This creates a gap in the review workflow.

Maintenance

ActivityStale
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    C
    quality
    A
    maintenance
    A Discord Model Context Protocol server that enables AI assistants to interact with Discord, providing functionality for sending messages, managing channels, handling forum posts, and working with reactions.
    46
    519 npm
    105
    MIT
  • A
    license
    B
    quality
    C
    maintenance
    A Discord Model Context Protocol server that enables AI assistants to interact with Discord by sending messages, managing channels, handling forum posts, managing webhooks, and processing reactions.
    22
    46 npm
    5
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    A Model Context Protocol server for reading public Reddit data and posting authenticated replies, enabling AI agents to interact with Reddit content.
    6
    MIT