Atlas / MCP servers / discourse / Discourse

DiscourseBLOCK

mcp/discourse/discourse-2

MCP client for Discourse sites

Verdict
BLOCK
Grade
D
Trust score
69 /100
Exposed tools
142 83r · 47w · 12d
Transport
stdio · streamable-http
License
MIT
Stars
77
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

Discourse MCP

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.3.1 (simplifies write opt-in so --allow_writes is sufficient and deprecates read_only=false; 0.3.0 added operator-selectable toolsets, structured directory output, and expanded opt-in administration capabilities; 0.2.x introduced breaking changes from 0.1.x, including JSON-only tool output; category/group resources remain deprecated compatibility surfaces alongside canonical list tools)

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 --auth_pairs '[{"site":"https://try.discourse.org","api_key":"'$DISCOURSE_API_KEY'","api_username":"system"}]'
  • Run with only Data Explorer built-in tools
npx -y @discourse/mcp@latest --toolsets data_explorer --tools_mode discourse_api_only

This exposes discourse_select_site plus the read-only Data Explorer tools. Add --site, authentication, and the write flags as needed; see Built-in toolsets.

  • 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. ```json { "mcpServers": { "disco
Read from source at commit 49c8468d24c1OBSERVED · 2026-10-07
Advertisement
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control.

claude-code (npm)
claude mcp add mcp -- npx -y @discourse/[email protected]
03

Exposed tools (142)

83 read · 47 write · 12 destructive. Blast radius: 12 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.

ToolRiskDescription
AgentreadDescription
TitlereadForum title
alicereadMost Recent Poster
always_firstreadAlways available.
discourse_ai_create_agentwriteCreate a typed Discourse AI agent, including an optional subagent delegation allowlist of up to 20 existing agent IDs. Requires admin credentials and write mode. Tool entries may be names or [name, options, force] tuples.
discourse_ai_create_agent_userwriteExplicitly create the bot user used by an AI agent for mention/chat entry points. Requires admin credentials and write mode.
discourse_ai_create_custom_toolwriteCreate a database-backed synchronous MiniRacer scripted tool. Call discourse_ai_get_custom_tool_guide before authoring. Never provide raw secret values. Requires admin credentials and write mode.
discourse_ai_delete_agentdestructiveDelete a non-system AI agent. Requires admin credentials and write mode.
discourse_ai_delete_custom_tooldestructiveDelete a scripted tool. Agents referencing it may stop functioning as configured. Requires admin credentials and write mode.
discourse_ai_export_agentreadExport a portable AI agent bundle. It may include referenced custom-tool definitions but excludes secret bindings. Treat prompts and scripts as sensitive.
discourse_ai_export_custom_toolreadExport portable custom-tool JSON. Discourse excludes secret bindings; MCP also strips them defensively. Treat script source as sensitive. Requires admin credentials.
discourse_ai_get_agentreadGet the full editable configuration of one Discourse AI agent. Custom tools use custom-<id>; native tools use native-<id> in tool tuples.
discourse_ai_get_custom_toolreadGet one database-backed scripted AI tool, including source and configured secret bindings. Treat the response as sensitive. Requires admin credentials.
discourse_ai_get_custom_tool_guidereadRetrieve one focused MiniRacer authoring topic. Usually pass only topic. preset_id is optional and used only with topic=presets to load one live example; extra preset_id values on other topics are ignored. Requires admin credentials.
discourse_ai_get_feature_configreadResolve a visible feature module ID and return its computed state plus editable settings from its exact ai-features/<module> area. Credential settings are omitted. Requires admin credentials.
discourse_ai_get_topic_summaryreadRetrieve an existing cached upstream Discourse AI topic summary, including algorithm and staleness evidence. Requires Discourse AI; this tool does not generate or claim complete MCP-authored output.
discourse_ai_import_agentdestructiveImport a portable AI agent bundle. The bundle may create or overwrite embedded custom tools. force requires confirm_force=true. Requires admin credentials and write mode.
discourse_ai_import_custom_tooldestructiveImport portable custom-tool JSON. force overwrites a matching tool_name and requires confirm_force=true. Secret IDs may be bound, but raw secret values are never accepted. Requires admin credentials and write mode.
discourse_ai_list_agentsreadList concise Discourse AI agent summaries and slim tool/model metadata. Defaults to slim; use discourse_ai_get_agent to load one full configuration, or view=full only when the complete index is explicitly needed. Requires admin credentials.
discourse_ai_list_custom_toolsreadList concise database-backed custom-tool summaries and compact live preset metadata. Scripts, bindings, verbose parameter descriptions, and full records are omitted; use discourse_ai_get_custom_tool or the guide
discourse_ai_list_featuresreadList visible computed Discourse AI modules, feature enabled state, assigned agents, and effective LLMs. Requires admin credentials.
discourse_ai_list_sentiment_postsreadList staff-visible posts classified positive, negative, or neutral by Discourse AI for an exact category/tag and date window. Classification is model output, not proof of tone, satisfaction, risk, or an argument.
discourse_ai_semantic_searchwriteRun Guardian-filtered Discourse AI semantic search and return bounded grouped post/topic evidence. Requires Discourse AI embeddings. Results are bounded and expose no fabricated page cursor.
discourse_ai_test_custom_toolwriteActually execute a persisted or unsaved custom-tool script. It can make external requests and cause side effects; this is not dry validation. Requires admin credentials and write mode.
discourse_ai_update_agentwritePartially update one AI agent, including enabled state, permissions, model, prompt, tools, subagent delegation, and RAG configuration. Only supplied fields are sent. Requires admin credentials and write mode.
discourse_ai_update_feature_configwriteAtomically bulk-update only non-secret settings freshly exposed by one exact AI feature area, with optional compare-before-write original_values. Refreshes effective state afterward. Production behavior changes immediately. Requires admin credentials and write mode.
discourse_create_categorywriteCreate a new category. Returns JSON with id, slug, and name.
discourse_create_groupwriteCreate a custom group with complete core settings, initial members and owners, custom fields, associations, and optional plugin fields. Requires staff group-creation permission.
discourse_create_postwriteCreate a post in a topic. author_username requires a global API key. Returns the actual upstream author so callers can verify attribution.
discourse_create_private_messagewriteCreate a private message for typed user, group, or email recipients. Unknown emails may create staged users. author_username requires a global API key; the response reports actual attribution.
discourse_create_querywriteCreate a new saved Data Explorer query. Requires admin API key and write access.
discourse_create_tag_groupwriteCreate a tag group with an explicit complete permission list such as permissions: [{group_id: 0, access: \
discourse_create_themewriteCreate a local Discourse theme or component. For textual HTML/SCSS/JS fields provide value and omit upload_id; for assets provide numeric upload_id with type=upload and omit value. Supplied code can execute or deploy for visitors; explicit confirmations and admin write access are required.
discourse_create_topicwriteCreate a new topic. author_username requires a global API key. Returns the actual upstream author so callers can verify attribution.
discourse_create_userwriteCreate a user through Discourse
discourse_create_webhookwriteCreate a guarded outbound webhook using the live event and content-type catalog. External delivery and risky options require explicit confirmation.
discourse_create_workflowwriteCreate a draft from a complete small graph or template. Prefer a complete graph over blank creation. ${authoringPlaybook}
discourse_delete_draftdestructiveDelete a draft by key. Requires current sequence number to prevent conflicts.
discourse_delete_groupdestructivePermanently delete a custom group. Automatic groups cannot be deleted. Requires staff access.
discourse_delete_querydestructiveSoft-delete a Data Explorer query. The query can be restored by an admin. Requires admin API key and write access.
discourse_delete_themedestructivePermanently delete one non-system, non-default theme/component after a fresh exact-name check. Dependencies are not detached automatically and bulk deletion is not exposed.
discourse_delete_webhookdestructiveDelete one webhook after a fresh exact destination-fingerprint precondition.
discourse_delete_workflowdestructivePermanently delete a workflow. Fails when another workflow calls it.
discourse_discard_workflow_draftreadReplace the draft with its published snapshot. Requires an existing published version.
discourse_evaluate_workflow_expressionreadEvaluate a workflow expression without mutating the forum. Interpolating expressions start with =.
discourse_get_chat_messagesreadGet messages from a chat channel. Returns JSON object with channel_id, messages array (id, username, created_at, message, edited, thread_id, in_reply_to_id), and meta.
discourse_get_draftreadRetrieve a specific draft by key. Returns JSON with draft_key, sequence, and parsed data (title, reply, categoryId, tags, action).
discourse_get_groupreadGet complete visible group details by numeric ID or name, including caller capabilities and group settings.
discourse_get_post_replieswriteRead reply relationships for a post as recursive descendant IDs, bounded rich direct replies, or the upstream-bounded ancestor history. Preserves upstream ordering and references.
discourse_get_post_revisionwriteGet a staff/Guardian-authorized post revision with bounded diffs, edit reason, actor, version, and hidden-state evidence.
discourse_get_queryreadGet full details of a Data Explorer query including SQL and parameters. Requires admin API key.
discourse_get_reportwriteExecute one discovered staff-visible Discourse report with dates, facets, typed filters, limit, and upstream caching. This exposes existing reports, not arbitrary SQL.
discourse_get_review_queue_countreadGet the authoritative count of pending reviewable records visible to the authenticated user. This counts queue items, not individual flag/score records; upstream Guardian permissions remain authoritative.
discourse_get_reviewablereadRefresh one shortlisted reviewable
discourse_get_support_dashboardreadGet the staff Solved support dashboard. Requires Discourse Solved.
discourse_get_tag_groupreadGet authoritative tag-group state by ID. Requires a locally configured API credential and upstream staff authority. The deterministic state_hash is an MCP optimistic precondition, not an upstream atomic lock; a race remains possible after preflight.
discourse_get_themereadInspect one local, ZIP-imported, or Git-backed Discourse theme/component as an administrator. Source values are bounded, opt-in, and may be unavailable for remote records; private key material is never returned.
discourse_get_topic_view_statsreadGet up to 300 ascending daily topic view counts. Views combine anonymous and logged-in views; they are not unique viewers or an engagement judgment.
discourse_get_userreadGet user info. Returns JSON with id, username, name, trust_level, created_at, bio, admin, and moderator.
discourse_get_user_moderation_summaryreadGet staff-authorized behavioral moderation counters for a user. Omits unrelated administrative capability flags; Discourse permissions remain authoritative.
discourse_get_user_summaryreadGet profile-visible aggregate user activity, top topics/replies/links, interaction partners, categories, badges, likes, visits, reading, and post/topic counts. Missing metrics remain null when hidden or unavailable.
discourse_get_webhookreadGet one fresh safe webhook configuration for inspection and mutation preconditions.
discourse_get_workflowreadGet the complete round-trippable workflow graph. GET immediately before updating it.
discourse_get_workflow_executionwritePoll an execution for status, errors, timing, trigger data, and steps.
discourse_handle_group_membership_requestreadApprove or deny one pending group membership request. Approval adds the requester to the group; denial only removes the request.
discourse_invite_group_members_by_emailwriteAdd existing accounts immediately when an address matches, and invite unknown addresses to the forum with this group preassigned. Use add_group_members_by_email when every address is known to belong to an account.
discourse_invite_to_private_messagewriteAdd a user or group to a private message, or submit an opaque email invitation. Email success does not confirm delivery or participant access. author_username requires a global API key.
discourse_join_groupreadJoin a visible group that allows public admission as the authenticated user.
discourse_leave_groupreadLeave a group that allows public exit as the authenticated user.
discourse_list_categoriesreadExhaustively list categories visible to the selected identity through bounded pagination. Returns stable IDs, slugs, hierarchy (parent_category_id; pid is a legacy alias), access flags, counts, structured completion metadata, and JSON text fallback. Opt in with the administration toolset.
discourse_list_directory_itemsreadList user-directory/cohort metrics with authoritative totals and continuation. Supports Discourse periods, ordering, visible groups, page 0-10, and the upstream maximum of 50 rows.
discourse_list_group_membersreadList a group
discourse_list_group_membership_requestsreadList pending membership requests and reasons for a group the caller can manage, with filtering and pagination.
discourse_list_group_postsreadList visible posts authored by a group using Discourse
discourse_list_groupsreadList visible groups. Empty input exhaustively traverses the bounded directory; any explicit page or filter field preserves the existing single-page query behavior. Both modes return one structured envelope with truthful completion metadata and JSON text fallback. Opt in with the groups toolset.
discourse_list_latest_postsreadList the site
discourse_list_private_messagesreadList authenticated personal or group private-message mailboxes. Returns normalized JSON messages and pagination metadata.
discourse_list_reportsreadDiscover staff-visible Discourse report identifiers and metadata. The catalog is authoritative because core and plugins can add or hide reports.
discourse_list_reviewable_topicsreadNon-exhaustive topic-level signal only: list pending topics at or above Discourse
discourse_list_site_settingsreadList admin-visible Discourse site settings with bounded metadata, optionally returning only settings whose current value differs from the default. Secret and credential-like values are always masked.
discourse_list_themesreadList admin-visible Discourse themes and components. This opt-in admin read returns bounded summaries and local pagination; it does not expose theme source code.
discourse_list_user_actionsreadList a user
discourse_list_user_postsreadGet paginated list of user posts/replies. Returns JSON object with posts array (id, topic_id, post_number, slug, title, created_at, excerpt, category_id) and meta (page, limit, has_more).
discourse_list_usersreadList users via admin API. Requires admin API key. Returns ~100 users per page (Discourse
discourse_list_webhook_eventsreadList bounded webhook delivery diagnostics. Payload and response previews are omitted unless explicitly confirmed.
discourse_list_webhooksreadList safe webhook summaries and the live authoring catalog without exposing webhook secrets or destination credentials.
discourse_list_workflow_credentialsreadList workflow credentials with secrets redacted. Credential creation remains in the admin UI.
discourse_list_workflow_executionsreadList global or per-workflow execution history.
discourse_list_workflow_node_typesreadList a slim catalog, or pass identifier for schemas, ports, and output contracts. ${authoringPlaybook}
discourse_list_workflow_templatesreadList templates or retrieve a complete template graph by id. ${authoringPlaybook}
discourse_list_workflow_versionsreadList workflow version history and UUIDs available for restore.
discourse_list_workflowsreadList compact Discourse Workflow summaries. Requires an admin API key.
discourse_manage_user_activationreadActivate, approve, activate-and-approve, or deactivate one user through Discourse
discourse_perform_reviewable_actionreadPerform one exact dynamic action after a fresh serialized preflight. Choose by the action
discourse_ping_webhookreadEnqueue one explicitly confirmed external webhook ping after a fresh destination precondition.
discourse_read_postwriteRead a specific post. Returns JSON with id, topic_id, post_number, username, created_at, and raw content.
discourse_read_private_messagereadRead an authenticated private message, its posts, and direct allowed-user and allowed-group records. Rejects public topics.
discourse_read_topicwriteRead topic metadata and posts. Large post limits can require multiple upstream requests. For moderation queues, prefer reviewable list/detail evidence instead of fanning this tool out across flagged topics.
discourse_read_topic_postswriteRead exact, earliest, latest, around-post, or username-filtered topic evidence. Selection is bounded to 50 posts and reports the visible stream size without claiming the entire topic was loaded.
discourse_redeliver_webhook_eventreadRedeliver exactly one old webhook event after destination, ownership, and status preconditions. Bulk redelivery is not exposed.
discourse_reply_private_messagereadSafely reply to an existing private message after verifying its archetype. author_username requires a global API key; the response reports actual attribution.
discourse_request_group_membershipreadRequest membership in a visible group that allows requests, sending the reason to its owners.
discourse_resolve_workflow_entityreadResolve category, tag, group, user, badge, chat channel, or data-table ids for workflow parameters.
discourse_restore_workflow_versionreadRestore a historical workflow version by UUID into the draft.
discourse_run_querywriteExecute 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.
discourse_run_workflowwriteRun the current unpublished draft asynchronously. This can create posts, send chat, or call external HTTP; poll the returned execution id.
discourse_run_workflow_stepwriteRun one non-trigger, non-waiting draft node asynchronously. Requires upstream pin-data or a prior successful run.
discourse_save_draftwriteCreate or update a draft. Returns JSON with draft_key and new sequence number.
discourse_searchreadSearch site content. Returns JSON object with results array of matching topics (id, slug, title) and meta (total, has_more).
discourse_search_postswriteSearch post-level evidence with Discourse query syntax. Unlike discourse_search, this preserves matched posts, highlighted blurbs, authors, topics, categories, and truthful bounded continuation. This is keyword search, not Discourse AI semantic search.
discourse_select_sitereadValidate and select a Discourse site. Returns JSON with site URL and title.
discourse_sync_remote_themewriteCheck or install updates for an existing Git-backed theme. Both actions clone external code and persist state; update deploys code and runs settings migrations, requiring explicit confirmations.
discourse_update_groupwriteUpdate all core group profile, visibility, admission, notification-default, association, email, SMTP, custom, and plugin settings supported by the caller and group type.
discourse_update_postwriteUpdate the content of an existing post. Returns JSON with updated post details.
discourse_update_querywriteUpdate an existing Data Explorer query. Only provided fields are updated. Requires admin API key and write access.
discourse_update_site_settingdestructiveSet or reset one ordinary admin-visible Discourse site setting after a fresh optimistic-concurrency check. Secret and structured settings are excluded.
discourse_update_themewriteUpdate bounded metadata, default status, or complete theme-component relationships. Relationship arrays replace the entire graph side; source, settings, translations, and remote refresh are intentionally excluded.
discourse_update_theme_fieldsdestructiveReplace or explicitly delete selected fields on a local or ZIP-imported theme. Text replacements require value and prohibit upload_id; asset replacements require numeric upload_id with type=upload and prohibit value. This can deploy executable code; Git-backed and system themes are rejected.
discourse_update_theme_settingwriteSet or explicitly revert one declared setting owned by a theme/component. This does not mutate themeable global site settings; object values are validated upstream against the declared schema.
discourse_update_theme_translationswriteReplace values for explicit translation keys declared by a theme, after a fresh locale read. Unknown keys are rejected; deletion/revert is not supported in this release.
discourse_update_topicwriteUpdate an existing topic (title, category, tags, featured_link). Returns JSON with updated topic details.
discourse_update_userwriteUpdate user profile fields. If upload_id is provided, also sets the user
discourse_update_webhookwritePartially update a webhook after fresh destination and active-state preconditions. Relationship arrays are complete replacements.
discourse_update_workflowwriteGET first. A replace PUT replaces the whole draft graph; omitted nodes are deleted. Use complete nodes+connections or operations[], never both. ${authoringPlaybook}
discourse_update_workflow_pin_datawritePin test items to a node name, or omit items to unpin it.
discourse_upload_filewriteUpload an image or file to Discourse. Provide either: image_data (base64 with filename), a remote HTTP(S) URL, or an absolute local file path. user_id is required for avatar/background uploads. Returns upload_id for use in avatar/profile updates. Use short_url to embed images in posts.
discourse_upload_theme_assetwriteUpload a bounded local/base64 asset for later attachment to a theme field. No remote URL fetch is supported; upload alone does not attach or deploy the asset.
fixture.remotereadRemote fixture
fixture_empty_toolsetsreadProves every definition belongs to at least one toolset.
fixture_inferredreadExercises inferred handler input.
fixture_invalid_structuredreadProves incorrect structured output fails project typecheck.
fixture_invalid_toolsetreadProves toolset names are checked while authoring.
fixture_otherreadHas a heterogeneous schema.
fixture_structuredreadChecks schema-linked structured output typing.
forwarding_fixturereadForwards registration and invocation values unchanged.
plain_registration_fixturereadDoes not advertise an output schema.
selection_thirdreadSite-selection gated.
sensitivereadD
structured_registration_fixturereadAdvertises an output schema.
treadD
toolreadDescription
write_secondwriteWrite gated.
04

Trust audit

BLOCKgrade D · trust 69/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeWARN
L2Instruction surface (what it tells the agent)FAIL
L3Class-specific surfaceWARN
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (1 observation(s))
Network
declared (4 observation(s))
Shell
none-observed
Dependencies
not all pinned
Secrets in source
none-found

Findings (13)

HIGHPrompt injection · prompt.override · CWE-94, CWE-1427
README.md:81
- Toolset selection does not bypass write safety. A selected write tool remains absent unless writes are enabled.
Why it matters. asks the agent to drop prior instructions or safety
Fix. remove the instruction
MEDIUMNetwork egress · net.beacon_words · CWE-200, CWE-319
src/tools/builtin/ai_custom_tools/guide_data.ts:29
http: section("Synchronous backend-proxied HTTP requests", ["http.get(url, options?)", "http.post(url, options?)", "http.put(url, options?)", "http.patch(url, options?)", "http.delete(url, options?)",
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
src/index.ts:87
return [`http://localhost:${port}`, `http://127.0.0.1:${port}`, `http://[::1]:${port}`];
MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
discourse_ai_delete_agent, discourse_ai_delete_custom_tool, discourse_ai_import_agent, discourse_ai_import_custom_tool, discourse_delete_draft, discourse_delete_group, discourse_delete_query, discours
Why it matters. 12 tool(s) can delete or overwrite
Fix. prefer a read-only mode or scoped tokens; the page states the blast radius
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/test/cli_info.test.ts:10
const indexPath = path.resolve(__dirname, "../../dist/index.js");
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/test/cli_info.test.ts:11
const packagePath = path.resolve(__dirname, "../../package.json");
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/test/tools.test.ts:91
const p = path.resolve(__dirname, '../../fixtures/try', name);
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/test/transport.test.ts:105
const indexPath = path.resolve(__dirname, '../../dist/index.js');
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/test/transport.test.ts:149
const indexPath = path.resolve(__dirname, '../../dist/index.js');
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
src/test/transport.test.ts:514
const closed = await fetch(`http://127.0.0.1:${port}/mcp`, {
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
src/test/transport.test.ts:524
const health = await fetch(`http://127.0.0.1:${port}/health`);
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
src/test/transport.test.ts:553
const health = await fetch(`http://127.0.0.1:${port}/health`);
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
package.json
zod, @eslint/js, @types/node, eslint, typescript, typescript-eslint
Why it matters. 6 dependency range(s) float
Fix. pin exact versions or ship a lockfile

Gates applied: instruction_override, no_behavioural_pass.

Audited 2026-10-07 · audit v0.4.1 · source sha 49c8468d24c1full audit observations/trust-audit/mcp-server/discourse__discourse-2.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-0749c8468d24c1BLOCKD69first audit
06

Questions

What is the Discourse MCP server?

MCP client for Discourse sites

What tools does Discourse expose?

142 in total: 83 read-only, 47 that write, and 12 that can delete or overwrite (discourse_ai_delete_agent, discourse_ai_delete_custom_tool, discourse_ai_import_agent, discourse_ai_import_custom_tool, discourse_delete_draft). Every one is listed on this page with its risk.

Is Discourse safe to connect to an agent?

No — not without reading the findings first. The audit graded it D (69/100) and found 1 critical or high issue in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 12 of its tools can destroy data, so scope the token you give it to what you actually need.

What credentials does Discourse need?

No credential environment variables were found in its source, so it appears to need none.

How does Discourse run?

It speaks stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as @discourse/mcp at 0.3.1.

How current is this page?

The grade is for one exact copy of the source (49c8468d24c1), read on 2026-10-07. The repository is watched and re-audited when it changes.

Advertisement