discourse-mcp-extended
Provides tools and resources for interacting with a Discourse forum, including searching, reading topics and posts, managing categories, tags, groups, chat channels, drafts, and the review queue (listing, approving, rejecting items). Supports read-only and write operations with authentication.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@discourse-mcp-extendedlist pending posts in the review queue"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 todist/index.js(binary name:discourse-mcp)SDK:
@modelcontextprotocol/sdkNode: >= 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@latestThen, in your MCP client, either:
Call the
discourse_select_sitetool with{ "site": "https://try.discourse.org" }to choose a site, orStart the server tethered to a site using
--site https://try.discourse.org(in which casediscourse_select_siteis 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_sitetool at runtime (validates via/about.json), orSupplying
--site <url>to tether the server to a single site at startup (validates via/about.jsonand hidesdiscourse_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_userandhttp_basic_passto anyauth_pairsentry. 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 bothuser_api_keyandapi_keyare provided for the same site,user_api_keytakes 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_writesAND not--read_only.Write tools require a matching
auth_pairsentry 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 informationinfo: Shows retry attempts and general operational messageserror: Shows only errorssilent: 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 hidediscourse_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 todiscourse_read_postand per-post content indiscourse_read_topic. The tools preferrawcontent by requestinginclude_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 indiscourse_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. Usestdiofor standard input/output (default), orhttpfor 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.jsonFlags still override values from the profile.
Remote Tool Execution API (optional)
With
tools_mode=auto(default) ortool_exec_api, the server discovers remote tools via GET/ai/toolsafter you select a site (or immediately at startup if--siteis provided) and registers them dynamically. Set--tools_mode=discourse_api_onlyto 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} }permsis array of{gid, perm}where perm: 1=full, 2=create_post, 3=readonlyNote:
permsis only populated with admin/moderator auth. Without admin auth, onlyread_restrictedboolean 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
gidvalues 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_searchInput:
{ query: string; max_results?: number (1–50, default 10) }Output:
{ results: [{id, slug, title}], meta: {total, has_more} }
discourse_read_topicInput:
{ 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_postInput:
{ post_id: number }Output:
{ id, topic_id, topic_slug, post_number, username, created_at, raw, truncated }
discourse_get_userInput:
{ username: string }Output:
{ id, username, name, trust_level, created_at, bio, admin, moderator }
discourse_list_user_postsInput:
{ 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_topicsInput:
{ 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); personalin:(bookmarked|watching|tracking|muted|pinned); dates: created/activity/latest-post-(before|after) withYYYY-MM-DDor relative daysN; 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_messagesInput:
{ 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_draftInput:
{ 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.actionsis the list of valid action ids for that item (e.g.approve_post,reject_post,agree_and_hide,disagree,delete) to pass todiscourse_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_reviewablesfirst to get thereviewable_id, currentversion, and validaction_idvalues 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_templatecontains{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_idis provided but avatar update fails,avatar_errorcontains 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_idis provided but avatar update fails,avatar_errorcontains 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(requiresfilename), remote HTTP(S) URL, or absolute local file pathuser_idis required for avatar/profile_background/card_background uploadsLocal file uploads require
--allowed_upload_pathsconfiguration (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--siteis provided)Input:
{ site: string }Output:
{ site, title }
Development
Requirements: Node >= 24,
pnpm.Install / Build / Typecheck / Test
pnpm install
pnpm typecheck
pnpm build
pnpm testRun locally (with source maps)
pnpm build && pnpm devProject layout
Server & CLI:
src/index.tsHTTP client:
src/http/client.tsTool registry:
src/tools/registry.tsResource registry:
src/resources/registry.tsBuilt‑in tools:
src/tools/builtin/*Remote tools:
src/tools/remote/tool_exec_api.tsJSON helpers:
src/util/json_response.tsLogging/redaction:
src/util/logger.ts,src/util/redact.ts
Testing notes
Tests run with Node’s test runner against compiled artifacts (
dist/test/**/*.js). Ensurepnpm buildbeforepnpm testif invoking scripts individually.
Publishing (optional)
The package is published as
@discourse/mcpand exposes abinnameddiscourse-mcp. Prefernpx @discourse/mcp@latestfor 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=falseOther 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.orgCreate 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/mcpConnect 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.comAuthentication
Admin API Keys vs User API Keys
This MCP server supports two types of Discourse API authentication:
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-KeyandApi-Username
User API Keys (
user_api_key+ optionaluser_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-KeyandUser-Api-Client-IdAuto-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
Easy Method: Built-in Generator (Recommended)
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 --helpThe command will:
Generate an RSA key pair
Display an authorization URL for you to visit
Prompt you to paste the encrypted payload after authorization
Decrypt and display your User API Key
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:
Generate a public/private key pair
Request authorization via
/user-api-key/newwith your public key, application name, client ID, and requested scopesUser approves the request (after login if needed)
Discourse returns an encrypted payload with the User API Key
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_postmissing? 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 debugto 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 toolsdiscourse_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.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (0-based, default: 0) | |
| filter | Yes | Filter query, e.g. 'category:support status:open created-after:30 order:activity' | |
| per_page | No | Items per page (max 50) |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| direction | No | Pagination direction: 'past' for older messages, 'future' for newer | |
| page_size | No | Number of messages to return (default: 50, max: 50) | |
| channel_id | Yes | The chat channel ID | |
| target_date | No | ISO 8601 date string to query messages around | |
| target_message_id | No | Message ID to query around or paginate from |
TDQS
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.
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.
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.
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.
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.
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).
| Name | Required | Description | Default |
|---|---|---|---|
| sequence | No | Expected sequence number (optional) | |
| draft_key | Yes | Draft key (e.g., "new_topic", "topic_123", "new_private_message") |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Query ID |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| username | Yes |
TDQS
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.
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.
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.
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.
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.
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).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (0-based, 10 items per page - Discourse's fixed page size) | |
| type | No | Filter by reviewable type, e.g. ReviewableQueuedPost, ReviewableFlaggedPost, ReviewableUser | |
| status | No | Filter by status (default: pending) | |
| priority | No | Minimum priority filter | |
| topic_id | No | ||
| sort_order | No | Sort order (default: score, matching /review?sort_order=score) | |
| category_id | No |
TDQS
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.
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.
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.
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.
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.
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).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| limit | No | Posts per page (max 50, default 30) | |
| username | Yes |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| asc | No | Sort ascending (default: false/descending) | |
| page | No | Page number (0-indexed) | |
| order | No | Sort order field | |
| query | No | User query type | active |
| filter | No | Search by username, email, or IP address |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| topic_id | Yes | ||
| post_limit | No | Max posts to return (default 5, max 50) | |
| start_post_number | No | Start from this post number (1-based) |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Query ID to run | |
| limit | No | Maximum number of rows to return (default: query default, use 'ALL' for unlimited) | |
| params | No | Query parameters as key-value pairs | |
| explain | No | Include query execution plan in response |
TDQS
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.
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.
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.
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.
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.
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_searchDiscourse SearchB
Search site content. Returns JSON object with results array of matching topics (id, slug, title) and meta (total, has_more).
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Search query | |
| max_results | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses the return structure (results array and meta fields), giving useful insight into output shape. However, it does not mention potential side effects, rate limits, authentication requirements, or pagination semantics beyond the presence of 'has_more', leaving some behavioral ambiguity.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is highly concise, consisting of two short sentences that front-load the core purpose and immediately describe the return format. No unnecessary words or repetition, making it easily scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with only two parameters, and the return format is described, which covers basic usage. However, it omits contextual details such as whether a site must be selected first (given the sibling discourse_select_site), how to handle pagination beyond 'has_more', and any error conditions, leaving some gaps for full contextual understanding.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description does not elaborate on the parameters, leaving max_results without explanation. The schema only describes 'query', providing 50% coverage, and the description adds no semantic value beyond what the schema already states, failing to clarify how max_results behaves.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool 'Search site content' and specifies the return format with 'matching topics' and metadata, indicating a search operation. However, it does not explicitly differentiate itself from sibling tools like discourse_filter_topics or discourse_get_query, so it lacks a bit of sibling distinction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
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. It does not mention any prerequisites (e.g., site selection) or scenarios where a different sibling tool would be more appropriate, such as filtering topics or running queries.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| site | Yes | Base URL of the Discourse site |
TDQS
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.
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.
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.
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.
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.
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.
13 tool updates
v0.1.0- First observed
discourse_filter_topics - First observed
discourse_get_chat_messages - First observed
discourse_get_draft - First observed
discourse_get_query - First observed
discourse_get_user - First observed
discourse_list_reviewables - First observed
discourse_list_user_posts - First observed
discourse_list_users - First observed
discourse_read_post - First observed
discourse_read_topic - First observed
discourse_run_query - First observed
discourse_search - First observed
discourse_select_site
TDQS
Scored across 13 tools
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.
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.
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.
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
Related MCP Connectors
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
A Model Context Protocol server for Wix AI tools
The Mercado Pago MCP Server implements the Model Context Protocol to provide AI agents and LLMs with access to Mercado Pago's APIs and tools within compatible development environments. It acts as an intermediary that translates Mercado Pago resources into executable functions (tools) that AI applications can invoke to perform actions and automate flows. The server simplifies integration, enables using documentation to implement or improve code, and optimizes operations through natural language interactions without manual implementations.
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceNode.js server that allows searching Discourse forum posts through the Model Context Protocol (MCP), enabling AI assistants to retrieve content from Discourse forums.14 npm5MIT
- AlicenseCqualityAmaintenanceA 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.46519 npm105MIT
- AlicenseBqualityCmaintenanceA 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.2246 npm5MIT
- AlicenseAqualityDmaintenanceA Model Context Protocol server for reading public Reddit data and posting authenticated replies, enabling AI agents to interact with Reddit content.6MIT