CLI
The discord-mcp binary is the single entry point with ten
sub-commands routed by commander:
discord-mcp <command> [options]serve is the default sub-command - running discord-mcp with no command
boots the local stdio MCP server, equivalent to discord-mcp serve. Pass
--http to serve a bearer-protected Streamable HTTP endpoint instead. The
other nine (catalog, setup, activity, update, profile, doctor, smoke, init,
migrate) are discovery or operator tools.
Source: packages/mcp-server/src/cli.ts.
Global flags
Section titled “Global flags”| Flag | Description |
|---|---|
--version |
Print the package version and exit. |
--help |
Print the help summary for the command. |
--help works at every level - discord-mcp --help, discord-mcp doctor --help,
etc. Each sub-command has its own option list described below.
discord-mcp serve [--gateway]discord-mcp serve --http [--host <host>] [--port <port>]discord-mcp serve --profile <name>discord-mcp [--gateway] # default sub-command, stdioStart the local stdio MCP transport by default. With --http, start a
stateless Streamable HTTP endpoint at /mcp; it requires
DISCORD_MCP_ACCESS_TOKEN and is designed to sit behind an HTTPS reverse
proxy. The endpoint negotiates MCP 2026-07-28 and retains stateless 2025-era
compatibility. Both forms read configuration from process.env and wire the
audit sink. The HTTP listener also provides an authenticated GET /healthz
readiness probe; it reports startup readiness only (and is not a Discord
liveness check).
| Flag | Type | Default | Description |
|---|---|---|---|
--gateway |
boolean | false |
Enable Discord Gateway resource subscriptions for stdio only. Lazy-imports discord.js so cold-start without this flag stays minimal. |
--http |
boolean | false |
Serve Streamable HTTP MCP at /mcp. Requires DISCORD_MCP_ACCESS_TOKEN; cannot be combined with --gateway. |
--host <host> |
string | 127.0.0.1 |
HTTP listen host. Applies with --http; leave on loopback behind a TLS reverse proxy. |
--port <port> |
number | 3000 |
HTTP listen port. Applies with --http. |
--profile <name> |
string | unset | Load non-secret bot/guild/tool settings from a caller-owned profile before startup. DISCORD_TOKEN must still exist in the launch environment. |
Examples
Section titled “Examples”# Bare invocation - equivalent to `discord-mcp serve` (commander default).discord-mcp
# Explicit serve.discord-mcp serve
# With Gateway subscriptions enabled.discord-mcp serve --gateway
# Start the bot and safety boundary saved by guided setup.discord-mcp serve --profile devbot
# Bare form with the same flag (forwarded to serve through commander's# default-subcommand passthrough).discord-mcp --gateway
# Remote MCP endpoint. Publish /mcp through an HTTPS reverse proxy.DISCORD_MCP_ACCESS_TOKEN="replace-with-a-long-random-secret" \ discord-mcp serve --http --host 127.0.0.1 --port 3000Exit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
0 |
Process never returns under normal stdio or HTTP operation. The transport runs until it is stopped. |
1 |
Boot failure - typically invalid config (missing DISCORD_TOKEN, unparseable env). Error message goes to stderr. |
See also
Section titled “See also”- Get started → Tutorial - create a bot, install, connect, and verify.
- OpenAI remote MCP - HTTPS deployment, Responses API, and Codex setup.
- Architecture - what
serveactually wires up.
catalog
Section titled “catalog”discord-mcp catalogdiscord-mcp catalog --check [--json]Start a credential-free stdio MCP server for schema discovery. It exposes the
same 209 tool contracts and six static resources as an unrestricted full
server, but every tools/call—including an unknown name—fails closed with
CATALOG_ONLY before validation or dispatch.
This command does not load profiles or runtime configuration, does not require
DISCORD_TOKEN, and does not contact Discord or another network service. Use it
for MCP registry scanners, security inspection, or contract generation. It
cannot read or change a Discord server; use serve with a caller-owned
bot for operational work.
The root Dockerfile defaults to catalog for safe automated introspection.
If you build that image from source for operational use, explicitly override
the command with serve and provide the caller-owned token and safety settings.
--check runs a bounded in-process MCP handshake and exits. It requires the
packaged catalog to expose exactly 209 tools and six static resources, reads the
six Components V2 JSON resources, and proves both a listed and unknown tool call
fail with CATALOG_ONLY. It does not read DISCORD_TOKEN, contact Discord or
another network service, write a profile or activity journal, prove AI-host
connectivity, or create Activity Evidence. Add --json for the stable
discord-mcp.catalog-check.v1 result; --json without --check fails closed.
| Flag | Type | Default | Description |
|---|---|---|---|
--check |
boolean | false |
Validate the installed credential-free catalog contract and exit. |
--json |
boolean | false |
Emit a machine-readable result for --check; invalid without it. |
Exit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
0 |
The catalog transport shut down normally, or the bounded check passed. |
1 |
Long-running catalog startup or shutdown failed; the message is written to stderr. |
2 |
The bounded catalog contract failed or --json was used without --check. |
doctor
Section titled “doctor”discord-mcp doctor [--profile <name>] [--json] [--online]discord-mcp doctor --access [--guild-id <id>] [--channel-id <id>] [--profile <name>] [--json]discord-mcp doctor --profile <name> --client codex [--config <path>] [--json]discord-mcp doctor --profile <name> --client antigravity-cli [--config <path>] [--json]discord-mcp doctor --profile <name> --client cursor-cli [--config <path>] [--json]discord-mcp doctor --profile <name> --client grok-cli [--config <path>] [--json]Diagnose configuration, token, and connectivity issues. Runs a registry of
checks (token format, env-var parse, audit sink, OTel config, etc.) and
aggregates results into a single structured report. With --online --profile
for a generated Codex profile, it also checks the pinned launcher version
against npm latest.
| Flag | Type | Default | Description |
|---|---|---|---|
--json |
boolean | false |
Emit machine-readable JSON instead of pretty TTY output. Use this in CI. |
--online |
boolean | false |
Run online checks against Discord (requires a working DISCORD_TOKEN). With a generated Codex profile, also performs one read-only npm version check. Without this flag only offline checks run, so doctor stays cheap. |
--access |
boolean | false |
Run the read-only bot identity, application, guild membership, permission, and privileged-intent preflight. Implies --online; it is advisory and does not mutate Discord or block tool calls yet. |
--guild-id <id> |
string | profile/allowlist when unique | Select the guild to evaluate with --access; it must be inside the configured allowlist when one exists. |
--channel-id <id> |
string | unset | Optionally fetch one channel and evaluate its permission overwrites. Requires --access. |
--profile <name> |
string | unset | Activate a saved profile before checks, including its expected bot identity and guild allowlist. A generated Codex profile enables launcher update discovery with --online. |
--client <id> |
string | unset | Audit a saved MCP client configuration locally. Supports codex, antigravity-cli, cursor-cli, grok-cli, and gemini-cli; each requires --profile and does not call npm or Discord. Antigravity, Cursor Agent, and Grok Build reject persisted MCP credentials; Gemini rejects a materialized token. |
--config <path> |
string | selected client’s user config | Override the Codex or Grok Build config.toml, Antigravity mcp_config.json, Cursor Agent MCP JSON, or Gemini settings.json path; useful for a nonstandard client home or CI fixture. |
Examples
Section titled “Examples”# Quick offline health check (no network calls).discord-mcp doctor
# Same but JSON for CI.discord-mcp doctor --json
# Verify the token is accepted by Discord.DISCORD_TOKEN=Bot.xxx discord-mcp doctor --online
# Full online + JSON report - typical pre-deploy gate.discord-mcp doctor --online --json | jq .
# Verify a saved caller-owned bot profile, its identity lock, and (for a# generated Codex launcher) whether an explicit update is available.discord-mcp doctor --profile devbot --online
# Explain the bot's verified guild access before a planned write.discord-mcp doctor --profile devbot --access --guild-id <guild-id> --json
# Inspect the saved Codex launcher without a network call. This reports only# normalized state: launcher/version, enabled status, startup timeout,# dry-run, write-mode, and OTel enabled state.discord-mcp doctor --profile devbot --client codex --jsonExit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
0 |
All checks ok. |
1 |
At least one check returned warn, no fails (including an available launcher update). |
2 |
At least one check returned fail (e.g. invalid token, missing env). |
The exit-code policy is uniform across setup, profile, doctor, smoke, init, migrate, and update:
0 = success, 1 = success-with-work-left, 2 = couldn’t run.
The update-status check never reads or sends DISCORD_TOKEN, bot identity,
guild IDs, or profile contents to npm. It never modifies config.toml; use
update --apply only after reviewing the reported version. Custom
or ambiguous launchers are marked caller-managed and left alone.
--access is a read-only capability report. It verifies /users/@me, the
current application, guild membership, roles, and (when supplied) channel
overwrites. The JSON result keeps ready, missing_permissions,
missing_intents, bearer_required, opaque_required, consent_required,
delegated_required, conditional, and unknown distinct; unknown evidence
is never treated as permission to write. The current report covers all 208
tools and is intentionally advisory; users_create_dm is user-scoped and
still requires its separate explicit consent policy before contacting a
recipient.
--client codex does not change configuration or Discord state, but it is
deliberately local: it reads the saved generated launcher and never returns the
config text, token, other env values, OTel endpoint, or absolute config path.
Like other doctor runs, it appends only predefined outcome signals to the
privacy-safe local activity journal. It describes the configuration that Codex
will use on its next start; restart Codex before treating a launcher change as
active runtime state. Custom or ambiguous launchers remain caller-managed and
produce a warning instead of being guessed or modified.
See also
Section titled “See also”- Operations → Audit - what audit-sink check covers.
- Operations → Telemetry - what otel-config check covers.
discord-mcp smoke [--profile <name>] [--json]discord-mcp smoke --confirm-write [--profile <name>] [--guild-id <id>] [--json]discord-mcp smoke --confirm-write --confirm-template-lifecycle [--profile <name>] [--guild-id <id>] [--json]Verify the real MCP-to-Discord path without loading all 209 tool schemas into an AI model. The default run is read-only: it starts an in-memory MCP client/server pair, validates the bot identity, and lists the guilds visible to the bot.
--confirm-write opts into one bounded lifecycle through the same MCP schemas,
middleware, audit, and Discord REST path: create a uniquely named temporary text
channel, send and edit one marker message, then delete the message and channel.
The command enables destructive execution only inside its own process and still
passes __confirm:true to both delete calls. It does not change the environment
or configuration used by the long-running server.
--confirm-template-lifecycle extends the write smoke with a temporary native
Guild Template: create, inspect, introduce one temporary channel drift, detect
that drift, sync the template, prove the drift is clean, then delete the
template. It is deliberately rejected without --confirm-write; it needs
MANAGE_GUILD in addition to the normal write-smoke permissions.
| Flag | Type | Default | Description |
|---|---|---|---|
--confirm-write |
boolean | false |
Execute the self-cleaning create/send/edit/delete lifecycle. Without it, the command is read-only. |
--confirm-template-lifecycle |
boolean | false |
Extend a confirmed write smoke with a self-cleaning Guild Template create/inspect/diff/sync/delete lifecycle. Requires --confirm-write. |
--guild-id <id> |
string | sole guild | Select the write target. Required when the bot can see multiple guilds; the ID must already be visible to it. |
--json |
boolean | false |
Emit the shared machine-readable result envelope, including step and cleanup state. |
--profile <name> |
string | unset | Activate a saved profile before opening the in-memory MCP session. |
The write smoke needs View Channels, Manage Channels, and Send Messages in the
test guild. It also needs the users, channels, and messages categories when
MCP_CATEGORIES is restricted. If a step fails after channel creation, cleanup
is attempted before the command exits; a cleanup failure is reported explicitly.
Examples
Section titled “Examples”# Cheap, read-only end-to-end check.discord-mcp smoke
# Read-only verification through a saved bot/guild boundary.discord-mcp smoke --profile devbot
# The bot is installed in exactly one private test guild.discord-mcp smoke --confirm-write
# The bot can see multiple guilds - make the target explicit.discord-mcp smoke --confirm-write --guild-id 111122223333444455
# Prove the native Guild Template lifecycle on a disposable test guild.discord-mcp smoke --confirm-write --confirm-template-lifecycle --guild-id 111122223333444455
# CI or agent-readable evidence.discord-mcp smoke --confirm-write --guild-id 111122223333444455 --jsonExit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
0 |
The read-only check passed, or every write step passed and all temporary artifacts were removed. |
2 |
Startup, targeting, a tool call, or cleanup failed. No write begins when the target is ambiguous. |
See also
Section titled “See also”- Verify setup - where the smoke check fits in the tutorial.
- Safety configuration - persistent dry-run and confirmation behavior.
discord-mcp setup --profile <name> [--client <id>] [--tool-surface <full|progressive>] [--allowed-guilds <id,id,...>] [--gateway] [--categories <name,name,...>] [--write-mode <allow|preview>] [--output <path>] [--force] [--json]Recommended onboarding for one caller-owned bot. setup has no token flag: it
resolves DISCORD_TOKEN from the caller’s environment, verifies the bot through
Discord, selects or validates its guild allowlist, saves non-secret profile
metadata, and generates a client snippet that starts serve --profile <name>.
Use --categories messages,guild to persist a narrow tool-category allowlist;
category spelling is checked when the server boots. Guided setup defaults to
--write-mode preview, while --write-mode allow opts into ordinary mutation
execution explicitly.
| Flag | Type | Default | Description |
|---|---|---|---|
--profile <name> |
string | prompt if TTY; required otherwise | Stable lowercase profile name. Allows letters, digits, dots, underscores, and hyphens. |
--client <id> |
string | prompt if TTY, else generic |
One of claude-desktop, claude-code, codex, antigravity-cli, cursor-cli, gemini-cli (enterprise/API-key compatibility), cursor, deepseek-harness, generic. |
--tool-surface <mode> |
string | progressive |
Store full or progressive as the runtime presentation layer. |
--allowed-guilds <ids> |
string | sole guild or interactive choice | Verify and store an explicit comma-separated guild allowlist. Ambiguous non-interactive selection fails closed. |
--categories <names> |
string | all categories | Store comma-separated lowercase category names such as messages,guild; the running server validates names against its installed tool registry. |
--write-mode <mode> |
string | preview |
Store preview (guided setup default) or allow for ordinary mutations. Destructive tools retain their separate dry-run and confirmation gates. |
--gateway |
boolean | false |
Store Gateway subscriptions for stdio startup. |
--output <path> |
string | stdout | Write the generated client snippet. Existing files are protected. |
--force |
boolean | false |
Update metadata for the same verified bot and overwrite --output. It cannot reassign the profile to another bot ID. |
--json |
boolean | false |
Emit the shared structured result, including profile name/path and snippet content. |
export DISCORD_TOKEN="Bot YOUR_DISCORD_BOT_TOKEN"discord-mcp setup --profile devbot --client codexdiscord-mcp doctor --profile devbot --onlinediscord-mcp smoke --profile devbotProfiles store only versioned metadata and the provider reference
env:DISCORD_TOKEN; neither setup output nor the profile contains the token
value. Selected guilds with Administrator still produce exit code 1 and a
least-privilege warning.
activity
Section titled “activity”discord-mcp activity [--json] [--report]Show the local evidence journal created by setup, doctor, smoke, and
blueprint plan/apply/evidence calls through stdio or authenticated HTTP. It is
an operator-facing record, not telemetry: discord-mcp never sends it anywhere.
Each record contains only a timestamp plus predefined command or blueprint-stage,
status, outcome, transport, and signal values. It never contains bot tokens,
Discord identities, guild IDs, configuration paths, command arguments, result
payloads, or raw errors.
The journal is capped at 200 recent records and lives beside the profile folder:
%APPDATA%\discord-mcp\activity.jsonl on Windows,
~/Library/Application Support/discord-mcp/activity.jsonl on macOS, and
${XDG_CONFIG_HOME:-~/.config}/discord-mcp/activity.jsonl on Linux. Delete that
local file to erase the journal; it does not change profiles or Discord.
Set DISCORD_MCP_ACTIVITY=off for a per-run opt-out; this affects only the
local journal and never the MCP server’s Discord behavior.
# Human-readable recent outcomes.discord-mcp activity
# Use the stable summary in automation or when sharing a redacted diagnosis.discord-mcp activity --jsonOptional outcome report shortcut
Section titled “Optional outcome report shortcut”discord-mcp activity --reportdiscord-mcp activity --report --json--report prints the fixed URL for the voluntary
verified outcome form
without reading or exporting the journal. It is deliberately URL-only: the command
never opens a browser, accesses the network, pre-fills fields, creates an issue, or
submits a report. --report --json exposes the URL with
submitted: false and network_accessed: false for scripts.
The operator must review and complete the form manually. The journal cannot establish the furthest verified outcome, AI host, transport, community job, time-to-outcome, repeat use, or showcase consent, so the CLI never guesses those fields. Local records contain only timestamps plus predefined command or blueprint-stage, status, outcome, transport, and signal values. They exclude tokens, Discord IDs, names, message content, configuration paths, and raw errors. A public report is optional and is not product telemetry.
Use this before changing the onboarding flow: it distinguishes completed setup,
token/discovery failures, the safe administrator-warning least-privilege
signal, doctor check results, and whether the first smoke path reached
identity/guild reads and cleaned up its own temporary write artifacts.
update
Section titled “update”discord-mcp update --profile <name> [--check]discord-mcp update --profile <name> --applyCheck the npm latest release against the exact version pinned in one generated
Codex launcher. A normal check does not modify configuration. --apply updates
only the matching npx ... @discord-mcp/cli@<version> serve --profile <name>
array and writes the result atomically.
The command loads only the non-secret local profile to confirm that it belongs
to Codex. It never resolves or sends DISCORD_TOKEN, bot identity, guild IDs,
or profile contents to npm. Custom wrappers, multiline TOML, and multiple
matching launchers fail closed and are left untouched.
| Flag | Type | Default | Description |
|---|---|---|---|
--profile <name> |
string | required | Saved caller-owned profile generated for Codex. |
--check |
boolean | true |
Explicit spelling of the default read-only check. Cannot be combined with --apply. |
--apply |
boolean | false |
Explicitly update exactly one generated Codex launcher after a newer release is found. |
--config <path> |
string | $CODEX_HOME/config.toml or ~/.codex/config.toml |
Override the user-level Codex config location. |
--json |
boolean | false |
Emit the structured version/status result. |
# Check only. Exit 1 means an update is available, not that the bot failed.discord-mcp update --profile devbot
# Apply the already-reviewed choice, then restart Codex.discord-mcp update --profile devbot --apply
# First use from a launcher pinned before v0.14.7.npx --yes @discord-mcp/cli@0.16.1 update --profile devbot --applyupdate never uses @latest in the generated launcher and never installs a
version silently. A successful JSON --apply result includes
data.restart_required: true: the launcher is pinned, but the running Codex
stdio process cannot load that version until Codex restarts. The explicit apply
step preserves caller control over bot behavior and Discord permissions.
When an older generated launcher lacks tool_timeout_sec, --apply also adds
the recommended tool_timeout_sec = 180 and reports it in
data.settings_migrated. An existing caller-defined value is preserved; custom
or ambiguous launchers still fail closed without modification.
profile
Section titled “profile”discord-mcp profile list [--json]discord-mcp profile show <name> [--json]discord-mcp profile remove <name> [--yes] [--json]Manage local non-secret profile metadata. Profiles live under
%APPDATA%\discord-mcp\profiles on Windows,
~/Library/Application Support/discord-mcp/profiles on macOS, and
${XDG_CONFIG_HOME:-~/.config}/discord-mcp/profiles on Linux.
listreports the bot identity, guild count, client, and tool surface.showprints the complete versioned metadata and provider reference, never the resolved token.removedeletes exactly one local profile. Non-interactive use requires--yes; deleting metadata does not revoke or reset the Discord token.
Rerun setup --profile <name> --force to update a profile for the same bot.
To assign the name to a genuinely different bot, first remove the old profile
and then run setup again with that bot’s caller-owned token.
discord-mcp init [--client <id>] [--token <token>] [--gateway] [--tool-surface <full|progressive>] [--allowed-guilds <id,id,...>] [--categories <name,name,...>] [--write-mode <allow|preview>] [--discover-guilds] [--output <path>] [--force] [--json]Generate a stateless MCP client config snippet for a supported client. Either
prints to stdout or writes to --output <path>. Prefer setup when you want a
reusable bot profile and safer credential lifecycle. deepseek-harness emits a Cordis YAML patch for the official MCP client plugin, including an explicit !!js process.env.DISCORD_TOKEN reference when no token is supplied. See DeepSeek Harness client setup for loading the patch.
| Flag | Type | Default | Description |
|---|---|---|---|
--client <id> |
string | prompt if TTY, else generic |
Target client id. One of claude-desktop, claude-code, codex, antigravity-cli, cursor-cli, gemini-cli (enterprise/API-key compatibility), cursor, deepseek-harness, generic. |
--token <token> |
string | ${env:DISCORD_TOKEN} placeholder |
Legacy explicit Discord bot token. Warning: clients without inherited secret forwarding write it unredacted. Antigravity CLI and Cursor Agent CLI deliberately omit it and inherit the launch environment instead. Prefer setup, which has no token flag. |
--gateway |
boolean | false |
Append --gateway to the generated snippet so the server enables Gateway subscriptions on boot. |
--tool-surface <mode> |
string | full |
Set progressive to add MCP_TOOL_SURFACE=progressive to the generated client snippet; useful for hosts without native deferred MCP loading. |
--allowed-guilds <ids> |
string | unset | Add a normalized ALLOWED_GUILDS server-side guild allowlist to the generated client snippet. Values must be comma-separated Discord snowflake IDs. |
--discover-guilds |
boolean | false |
Use the current DISCORD_TOKEN to verify the bot and enumerate its real guilds. A sole guild is selected automatically; TTY runs require an explicit choice and default to cancel; ambiguous non-interactive runs must pass --allowed-guilds. Selected guilds with Administrator produce a warning. |
--categories <names> |
string | all categories | Add a lowercase comma-separated MCP_CATEGORIES allowlist; installed category names are validated at server boot. |
--write-mode <mode> |
string | allow |
Set MCP_WRITE_MODE=preview to make ordinary mutations return previews; allow preserves legacy execution behavior. |
--output <path> |
string | (stdout) | Write the snippet to a file instead of stdout. |
--force |
boolean | false |
Overwrite the --output path if it already exists. Required to overwrite. |
--json |
boolean | false |
Emit machine-readable JSON instead of pretty output. The snippet body is delivered under data.content. |
Examples
Section titled “Examples”# Interactive - prompts for client + gateway when stdin is a TTY.# Omitted tokens always remain an environment reference.discord-mcp init
# Non-interactive: print a Claude Desktop snippet with the token placeholder.discord-mcp init --client claude-desktop
# Non-interactive: print a Codex TOML fragment that forwards DISCORD_TOKEN.discord-mcp init --client codex
# Non-interactive: print Antigravity MCP config with inherited credentials.discord-mcp init --client antigravity-cli
# Non-interactive: print secret-free Cursor Agent MCP config.discord-mcp init --client cursor-cli
# Compatibility: print Gemini settings with an explicit, non-secret env reference.discord-mcp init --client gemini-cli
# Recommended: verify the bot and derive a progressive, guild-scoped Codex fragment.export DISCORD_TOKEN="Bot YOUR_DISCORD_BOT_TOKEN"discord-mcp init --client codex --tool-surface progressive --discover-guilds
# Non-interactive bot with multiple guilds: make the choice explicit and verify it.discord-mcp init --client codex --tool-surface progressive --discover-guilds \ --allowed-guilds 111122223333444455
# Bake a real token into the snippet (NOT recommended for committed files).discord-mcp init --client cursor --token "Bot.xxx.yyy.zzz"
# Write directly to Claude Desktop's config (force overwrite).discord-mcp init --client claude-desktop \ --output ~/Library/Application\ Support/Claude/claude_desktop_config.json \ --force
# JSON for tooling.discord-mcp init --client generic --json | jq .data.contentExit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
0 |
Snippet generated (and written, if --output was used). |
1 |
Snippet generated, but a selected guild grants the bot Administrator. |
2 |
Couldn’t run - invalid options, failed Discord verification, ambiguous guild selection, or protected output path. |
See also
Section titled “See also”- Get started → Client setup - manual client wiring guides.
- Choose a connection mode - stdio or HTTP, progressive or full, and optional Gateway notifications.
migrate
Section titled “migrate”discord-mcp migrate --list [--json]discord-mcp migrate --from <adapter> [--source <path>] [--json]Migrate from another Discord MCP setup. Four adapters ship today:
| Adapter id | Source | Upstream tool estimate |
|---|---|---|
pasympa |
PaSympa Discord MCP (TypeScript) | ~91 |
quadslab |
quadslab Discord MCP (@quadslab.io, TypeScript) |
~139 |
discord-ops |
discord-ops by bookedsolidtech (TypeScript) | ~49 |
hubdustry-go-mcp |
Hubdustry-shaped Go MCP - non-Discord reference fixture | unavailable |
The original Hubdustry upstream is no longer publicly reachable, so --list
deliberately omits its homepage and tool-count estimate instead of presenting
unverifiable metadata. The bundled synthetic fixture contains 5 tools;
running the adapter against it produces 0 mapped, 5 unmapped, and 0 manual
review by design. Use one of the other three adapters for an actual migration.
| Flag | Type | Default | Description |
|---|---|---|---|
--list |
boolean | false |
List every registered adapter with its description, languages, tool-count estimate, and homepage. Informational - always exits 0. Takes precedence over --from. |
--from <id> |
string | (none) | Source adapter id - one of the four above. Required to run a migration. |
--source <path> |
string | cwd |
Path to the source repo to migrate from. Defaults to the current working directory. |
--json |
boolean | false |
Emit machine-readable JSON instead of pretty output. |
Examples
Section titled “Examples”# Discover adapters - exits 0, safe in CI.discord-mcp migrate --list
# Same, machine-readable.discord-mcp migrate --list --json | jq '.data.adapters[].id'
# Migrate from a PaSympa checkout in the current directory.discord-mcp migrate --from pasympa
# Migrate from a sibling directory.discord-mcp migrate --from quadslab --source ../quadslab-discord-mcp
# JSON output for tooling - capture the full migration report.discord-mcp migrate --from discord-ops --json > migrate-report.jsonExit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
0 |
--list (always), OR an adapter ran AND every source tool was mapped cleanly (no unmapped, no manual review). |
1 |
Adapter ran but produced unmapped tools or items needing manual review. Successful run with work left - hand-edit the output. |
2 |
Couldn’t run - bare migrate with no flags, unknown --from, source not detected at --source, IO failure. |
See also
Section titled “See also”- Architecture - how the tool registry maps onto MCP.
Output formats
Section titled “Output formats”setup, profile, doctor, smoke, init, and migrate share the same emitResult(...) envelope.
In pretty mode you see a TTY-friendly summary. In --json mode you get a
single line of structured JSON with this shape:
{ "ok": true, "exitCode": 0, "summary": "<one-line summary>", "details": ["<line>", "..."], "warnings": [], "errors": [], "data": { /* command-specific payload */ }}This is the contract pipelines should consume. data is per-command
(setup’s data.profile, profile’s metadata collection, doctor’s
data.checks, smoke’s data.steps, init’s data.content, migrate’s
data.result)
and stable across versions within a major.

