Discript
FreeMaintainedSafe Discord scripting language and CLI for developers, AI agents, and automation.
About
Safe Discord scripting language and CLI for developers, AI agents, and automation.
README
Discript is a scripting language and CLI for safe, programmatic Discord automation. It is designed for developers, AI agents, and coding harnesses that need repeatable commands, composable scripts, structured results, and explicit control over side effects.
At its core, Discript parses and runs .ds programs or commands from files, stdin, or inline CLI input. The same engine can connect directly to Discord for one-shot work, reuse a long-lived daemon connection over a local socket, or expose and consume the engine through MCP stdio and HTTP/HTTPS transports.
Requirements
- Node.js 26 or newer
- A Discord bot token in
DISCORD_TOKEN - The bot must be able to view the target guilds and channels
Setup
npm install
node -e "require('node:fs').copyFileSync('.env.example', '.env')"
# edit .env with a private Discord bot token
For local installation before the first npm release, use the Git SSH URL or build a tarball:
npm install git+ssh://[email protected]/eliware/discript.git
npm pack
npm install ./eliware-discript-*.tgz
The package is public and publishes to npm from v* Git tags through the standard Eliware release workflow. The npm package name is @eliware/discript because the unscoped discript name is unavailable for publishing.
Documentation
The full documentation map is in docs/README.md, including getting started, the language, CLI and Discord references, agent workflows, developer guides, operations, and contribution guidance.
List guilds with a direct CLI command:
npm start -- guilds list --json
Read-only commands and supported one-shot mutations can use REST without opening a Gateway session:
npm start -- --rest guilds list --json
npm start -- --rest channels list --guild <guild-id> --json
npm start -- --rest messages send --channel <channel-id> --content "hello"
npm start -- --rest channels delete --channel <channel-id> --yes
For repeated Gateway-backed commands or scripts, start the shared local broker once:
npm start -- daemon start
npm start -- --broker guilds list --json
npm start -- --broker script.ds
npm start -- daemon stop
Discover supported direct commands or generate shell completion scripts:
npm start -- commands list --json
npm start -- completion bash > discript-completion.bash
npm start -- completion zsh
npm start -- completion fish
Inspect the connected bot identity:
npm start -- bot get --json
Common singular and abbreviated resource names are accepted, such as msg send, chan list, and guild list.
Unknown commands include nearby command suggestions; JSON errors expose them under details.suggestions.
Machine-readable errors include error, code, and exitCode. Discord API failures use the stable DISCORD_API_ERROR code with exit status 5; sanitized request metadata may appear under details.
List channels in a guild:
npm start -- channels list --guild <guild-id> --json
Look up a guild or channel:
npm start -- guilds get --guild <guild-id> --json
npm start -- channels get --channel <channel-id> --json
Discover members and roles:
npm start -- members list --guild <guild-id> --json
npm start -- roles list --guild <guild-id> --json
Read guild invites, emojis, and stickers:
npm start -- invites list --guild <guild-id> --json
npm start -- emojis list --guild <guild-id> --json
npm start -- stickers list --guild <guild-id> --json
Emoji and sticker lifecycle operations require --yes and support --dry-run previews:
npm start -- emojis create --guild <guild-id> --name wave --file ./wave.png --yes --json
npm start -- emojis delete --guild <guild-id> --emoji <emoji-id> --yes --json
npm start -- stickers create --guild <guild-id> --name wave --file ./wave.png --tags wave --yes --json
npm start -- stickers delete --guild <guild-id> --sticker <sticker-id> --yes --json
Channel webhooks support guarded listing, creation, and deletion:
npm start -- webhooks list --channel <channel-id> --json
npm start -- webhooks create --channel <channel-id> --name automation --yes --json
npm start -- webhooks delete --channel <channel-id> --webhook <webhook-id> --yes --json
Channel permission overwrites can be inspected or changed with comma-separated Discord permission names:
npm start -- permissions list --channel <channel-id> --json
npm start -- permissions set --channel <channel-id> --target <role-or-user-id> --allow ViewChannel,SendMessages --deny ManageMessages --yes --json
npm start -- permissions delete --channel <channel-id> --target <role-or-user-id> --yes --json
Member voice status and guarded controls are available through voice-users:
npm start -- voice-users status --guild <guild-id> --user <user-id> --json
npm start -- voice-users mute --guild <guild-id> --user <user-id> --yes --json
npm start -- voice-users unmute --guild <guild-id> --user <user-id> --yes --json
npm start -- voice-users deafen --guild <guild-id> --user <user-id> --yes --json
npm start -- voice-users undeafen --guild <guild-id> --user <user-id> --yes --json
npm start -- voice-users move --guild <guild-id> --user <user-id> --channel <voice-channel-id> --yes --json
npm start -- voice-users disconnect --guild <guild-id> --user <user-id> --yes --json
Invite creation and deletion are guarded mutations; use --yes (or -y) and preview with --dry-run:
npm start -- invites create --guild <guild-id> --channel <channel-id> --duration 3600 --yes --json
npm start -- invites delete --guild <guild-id> --invite <invite-code> --yes --json
Scheduled events support discovery and guarded lifecycle operations:
npm start -- events list --guild <guild-id> --json
npm start -- events create --guild <guild-id> --name "Town hall" --start "2030-01-01T00:00:00Z" --yes --json
npm start -- events update --guild <guild-id> --event <event-id> --name "Updated" --yes --json
npm start -- events delete --guild <guild-id> --event <event-id> --yes --json
Voice connections support guarded join/leave and status inspection:
npm start -- voice status --guild <guild-id> --json
npm start -- voice join --channel <voice-channel-id> --yes --json
npm start -- voice leave --guild <guild-id> --yes --json
Scripts can declare event handlers. The incoming Discord payload is available as event inside the handler:
on("messageCreate") {
print(event.content)
}
When a script registers one or more handlers, it remains running until a termination signal is received; --timeout <milliseconds> can bound that lifetime for automation.
Scripts can read and modify the environment of the running Node process. Use property access or the explicit methods:
guildId = env.TEST_GUILD
tokenHint = env.get("DISCRIPT_MODE")
env.set("DISCRIPT_LAST_RUN", "agent")
env.clear("DISCRIPT_TEMP")
Environment values are strings; missing variables return null. Avoid printing secrets such as DISCORD_TOKEN.
Use bounded for-in loops to process result collections:
members = discord.guilds.get("<guild-id>").members.list()
for (member in members) {
print(member.username)
}
Scripts can schedule asynchronous work and compose concurrent operations:
every(60000) { print("heartbeat") }
after(1000) { print("started") }
values = parallel(sleep(10), sleep(10))
Arrow callbacks can transform and select collections:
names = map(members, member => member.username)
active = filter(members, member => member.roles != null)
Reusable script functions use fn and return:
fn announce(name) {
return "Hello " + name
}
print(announce("Discord"))
Reusable source files can be loaded into the current script scope:
import "./shared.discript"
print(announce("Discord"))
Threads support inspection and guarded lifecycle operations:
npm start -- threads list --channel <channel-id> --json
npm start -- threads create --channel <channel-id> --name "topic" --yes --json
npm start -- threads archive --channel <channel-id> --thread <thread-id> --yes --json
Role changes require explicit approval:
npm start -- roles add --guild <guild-id> --user <user-id> --role <role-id> --yes --json
npm start -- roles remove --guild <guild-id> --user <user-id> --role <role-id> --yes --json
npm start -- roles create --guild <guild-id> --name "Helper" --yes --json
npm start -- roles update --guild <guild-id> --role <role-id> --name "Helper" --yes --json
npm start -- roles delete --guild <guild-id> --role <role-id> --yes --json
Moderation operations also require explicit approval:
Moderation also rejects bot, owner, self, and targets at or above the bot’s role hierarchy.
npm start -- moderation timeout --guild <guild-id> --user <user-id> --duration 3600000 --reason "reason" --yes --json
npm start -- moderation kick --guild <guild-id> --user <user-id> --reason "reason" --yes --json
npm start -- moderation ban --guild <guild-id> --user <user-id> --reason "reason" --yes --json
Preview or send a message. Writes require explicit approval:
npm start -- messages send --channel <channel-id> --content "Hello" --dry-run --json
npm start -- messages send --channel <channel-id> --content "Hello" --yes --json
Create a test channel with the configured test guild:
npm start -- channels create --guild "$TEST_GUILD" --name discript-test --dry-run --json
npm start -- channels create --guild "$TEST_GUILD" --name discript-test --yes --json
Direct dry-runs validate command-specific required fields and return a structured preview without connecting to Discord:
npm start -- channels create --guild <guild-id> --name preview --dry-run --json
Add --validate to connect, resolve the target, and check permissions while still preventing the mutation:
npm start -- channels create --guild <guild-id> --name preview --dry-run --validate --json
Messages can be read or changed with explicit approval for writes:
npm start -- messages get --channel <channel-id> --message <message-id> --json
npm start -- messages edit --channel <channel-id> --message <message-id> --content "Updated" --yes --json
npm start -- messages delete --channel <channel-id> --message <message-id> --yes --json
npm start -- messages react --channel <channel-id> --message <message-id> --emoji "👍" --yes --json
npm start -- messages pin --channel <channel-id> --message <message-id> --yes --json
npm start -- messages unpin --channel <channel-id> --message <message-id> --yes --json
npm start -- messages bulk-delete --channel <channel-id> --messages <id1,id2> --yes --json
Evaluate source inline:
npm start -- --eval 'guilds = discord.guilds.list(); guilds' --json
Finite commands can be bounded for automation:
npm start -- --timeout 15000 --eval 'discord.guilds.list()' --json
Read source from standard input:
printf '%s\n' 'discord.guilds.list()' | npm start -- --json
For agent pipelines and long-running scripts, use JSONL output:
npm start -- --eval 'print({phase: "start"}); discord.guilds.list()' --output jsonl
Run a script file:
npm start -- examples/list-guilds.ds --json
More agent-oriented templates are included in examples/: safe-channel-workflow.ds demonstrates preview/force/try/exit handling, and event-monitor.ds demonstrates persistent event and timer handlers.
The language supports literals, variables, property access, function calls, sequential statements, functions, conditionals, loops, imports, environment access, async helpers, timers, event handlers, comments, dry-run/approval options, and script-level exit statuses. The CLI and language runtime use the same Discord capability layer. See docs/language/reference.md for the implemented contract.
Development
npm test
npm run lint
The tests are deterministic where possible and do not require a Discord connection. Live smoke commands require a configured DISCORD_TOKEN.
Security
Never commit .env, bot tokens, credential-bearing URLs, or raw Discord payloads containing sensitive data. Mutating operations will require explicit safeguards as the capability surface expands.
Specifications
Product and behavior requirements are maintained in SPEC.md and specs/.
Install Discript in Claude Desktop, Claude Code & Cursor
unyly install discriptInstalls into Claude Desktop, Claude Code, Cursor & VS Code — handles npx, uvx and build-from-source repos for you.
First time? Get the CLI: curl -fsSL https://unyly.org/install | sh
Or configure manually
Run in your terminal:
claude mcp add discript -- npx -y @eliware/discriptStep-by-step: how to install Discript
FAQ
Is Discript MCP free?
Yes, Discript MCP is free — one-click install via Unyly at no cost.
Does Discript need an API key?
No, Discript runs without API keys or environment variables.
Is Discript hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Discript in Claude Desktop, Claude Code or Cursor?
Open Discript on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Changes
Versions and requested access over time.
- New version published
- New version published
- New version published
- New version published
- New version published
Related MCPs
Gmail
Read, send and search emails from Claude
by GoogleSlack
Send, search and summarize Slack messages
by SlackRunbear
No-code MCP client for team chat platforms, such as Slack, Microsoft Teams, and Discord.
Discord Server
A community discord server dedicated to MCP by [Frank Fiegel](https://github.com/punkpeye)
Klavis AI
Open Source MCP Infra. Hosted MCP servers and MCP clients on Slack and Discord.
Work90210/APIFold
Turn any REST API into a hosted MCP server, with ready-made public servers for GitHub, Stripe, Slack, OpenAI, Notion and more.
by Work90210arikusi/deepseek-mcp-server
DeepSeek AI chat and reasoning with multi-turn sessions, function calling, thinking mode and cost tracking.
by arikusihashgraph-online/hashnet-mcp-js
Discover, register and chat with AI agents on the Hashgraph network via the Registry Broker.
by hashgraph-onlineprofullstack/mcp-server
Developer utilities: SEO optimization, document conversion, domain lookup, email validation, QR codes, weather data, social media posting and security scanning.
by profullstackWayStation-ai/mcp
Connect MCP hosts to apps such as Notion, Slack, Monday and Airtable.
by waystation-aiCompare Discript with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All communication MCPs
