Configuration
Configure mock server behavior
Configure Mock Server through plugin options and environment variables.
Plugin Options
Create your mock plugin config file:
export default {
// Auto-open Stage UI in browser when starting mock mode
autoOpenStage: true,
// Default session configuration for robo mock start
defaultSessionConfig: {
botUser: {
username: 'TestBot',
discriminator: '0001'
},
guilds: [{
name: 'Test Server',
channels: [
{ name: 'general', type: 0 }, // 0 = Text
{ name: 'bot-commands', type: 0 } // 0 = Text
]
}],
users: [
{ username: 'TestUser' }
]
},
// Port for standalone mock server (default: 6625)
standalonePort: 6625,
// Data directory relative to .robo (default: 'mock')
dataDirectory: 'mock'
}export default {
// Auto-open Stage UI in browser when starting mock mode
autoOpenStage: true,
// Default session configuration for robo mock start
defaultSessionConfig: {
botUser: {
username: 'TestBot',
discriminator: '0001'
},
guilds: [{
name: 'Test Server',
channels: [
{ name: 'general', type: 0 }, // 0 = Text
{ name: 'bot-commands', type: 0 } // 0 = Text
]
}],
users: [
{ username: 'TestUser' }
]
},
// Port for standalone mock server (default: 6625)
standalonePort: 6625,
// Data directory relative to .robo (default: 'mock')
dataDirectory: 'mock'
}Editor or file tree showing the config/plugins/robojs/mock.ts file location relative to the project root, demonstrating the plugin configuration file structure
Option Reference
| Option | Type | Default | Description |
|---|---|---|---|
autoOpenStage | boolean | true | Open Stage UI in browser automatically |
defaultSessionConfig | object | - | Default config for new sessions |
standalonePort | number | 6625 | Port for standalone server |
dataDirectory | string | 'mock' | Directory for mock data |
Session Configuration
Configure session defaults for testing:
Bot User
defaultSessionConfig: {
botUser: {
username: 'MyBot',
discriminator: '1234',
avatar: null,
bot: true
}
}defaultSessionConfig: {
botUser: {
username: 'MyBot',
discriminator: '1234',
avatar: null,
bot: true
}
}Guilds
defaultSessionConfig: {
guilds: [{
name: 'Test Server',
ownerId: '123456789',
channels: [
{ name: 'general', type: 0 }, // 0 = Text
{ name: 'announcements', type: 5 }, // 5 = Announcement
{ name: 'Voice', type: 2 } // 2 = Voice
]
}]
}defaultSessionConfig: {
guilds: [{
name: 'Test Server',
ownerId: '123456789',
channels: [
{ name: 'general', type: 0 }, // 0 = Text
{ name: 'announcements', type: 5 }, // 5 = Announcement
{ name: 'Voice', type: 2 } // 2 = Voice
]
}]
}Users
defaultSessionConfig: {
users: [
{ username: 'TestUser', bot: false },
{ username: 'AnotherBot', bot: true }
]
}defaultSessionConfig: {
users: [
{ username: 'TestUser', bot: false },
{ username: 'AnotherBot', bot: true }
]
}Intents
Control which intents (event categories your bot subscribes to) are enforced:
import { GatewayIntentBits } from 'discord-api-types/v10'
defaultSessionConfig: {
enforceIntents: true,
// Approve specific privileged intents using a bigint bitmask.
// Each intent is a bit flag -- combining them with | (bitwise OR)
// produces a single number representing all approved intents.
approvedPrivilegedIntents: BigInt(
GatewayIntentBits.GuildMembers | // 1 << 1
GatewayIntentBits.GuildPresences | // 1 << 8
GatewayIntentBits.MessageContent // 1 << 15
)
}import { GatewayIntentBits } from 'discord-api-types/v10'
defaultSessionConfig: {
enforceIntents: true,
// Approve specific privileged intents using a bigint bitmask.
// Each intent is a bit flag -- combining them with | (bitwise OR)
// produces a single number representing all approved intents.
approvedPrivilegedIntents: BigInt(
GatewayIntentBits.GuildMembers | // 1 << 1
GatewayIntentBits.GuildPresences | // 1 << 8
GatewayIntentBits.MessageContent // 1 << 15
)
}approvedPrivilegedIntents uses a bigint bitmask (a single number where each bit represents one intent), not a string array. Import GatewayIntentBits from discord-api-types/v10 for readable intent values.
Permission Enforcement
Control how strictly permissions are checked:
defaultSessionConfig: {
permissionEnforcement: 'basic' // 'none' | 'basic' | 'strict'
}defaultSessionConfig: {
permissionEnforcement: 'basic' // 'none' | 'basic' | 'strict'
}| Level | Description |
|---|---|
none | All actions succeed regardless of permissions (default) |
basic | Simple permission checks (requires the permission) |
strict | Full Discord-accurate logic with hierarchy, context, and owner bypass |
DevTools Permissions tab showing strict enforcement level selected, with denied operations visible in the permission denied log
Environment Variables
Core Variables
| Variable | Description |
|---|---|
ROBO_MOCK_MODE | Set to true to enable mock mode |
ROBO_MOCK_SESSION_ID | Pre-generated session ID |
ROBO_MOCK_PORT | Override mock server port |
Testing Variables
| Variable | Description |
|---|---|
ROBO_MOCK_TEST_MODE | Set by robo mock test |
ROBO_MOCK_TEST_RUN_ID | Unique identifier for test run |
Internal Variables
| Variable | Description |
|---|---|
__ROBO_MOCK_STANDALONE | Set when running standalone server |
__ROBO_MOCK_CONNECT_EXISTING | Connect to external mock server |
Server Integration
Mock Server integrates with @robojs/server. Configure server options:
export default {
cors: true,
port: 3000,
pluginPrefixes: {
'@robojs/mock': '/mock'
}
}export default {
cors: true,
port: 3000,
pluginPrefixes: {
'@robojs/mock': '/mock'
}
}Plugin Prefix
Mock Server routes are prefixed by default:
| Route | Path |
|---|---|
| Stage UI | /mock/stage/ |
| REST API | /mock/api/v10/* |
| Control API | /mock/api/control/* |
Custom Prefix
pluginPrefixes: {
'@robojs/mock': '/test' // Stage at /test/stage/
}pluginPrefixes: {
'@robojs/mock': '/test' // Stage at /test/stage/
}Disable Prefix
pluginPrefixes: {
'@robojs/mock': {
api: false,
static: false
}
}pluginPrefixes: {
'@robojs/mock': {
api: false,
static: false
}
}Activity Configuration
Configure the Activity Proxy and Embedded App SDK simulation.
Activity Proxy
The Activity Proxy starts on port 50002 when the mock server boots. It simulates Discord's *.discordsays.com proxy infrastructure.
| Setting | Default | Description |
|---|---|---|
| Port | 50002 | Auto-increments if busy (up to 10 attempts) |
launch_url | Required | Upstream URL for the activity (e.g., http://localhost:5173) |
launch_path | / | Path appended to launch URL |
sdk_shim_enabled | true | Inject SDK origin shim into HTML responses |
csp_mode | relaxed | Content Security Policy mode (relaxed or discord_strict) |
The launch_url is provided when launching an activity (via Stage UI or the launch_activity command). Other settings are configured per-session through DevTools or Stage WS commands.
URL Mappings
URL mappings route specific URL prefixes through the Activity Proxy to different targets, matching the URL Mapping configuration in the Discord Developer Portal.
Create a discord-url-mappings.json file in your project root:
{
"version": 1,
"activities": [
{
"id": "my-activity",
"name": "My Activity",
"application_id": "1234567890",
"launch_url": "http://localhost:5173",
"url_mappings": [
{ "prefix": "/api", "target": "api.example.com" },
{ "prefix": "/cdn", "target": "cdn.example.com" }
]
}
]
}Each activity entry requires id, name, application_id, and launch_url. The url_mappings array defines prefix-to-target routing using longest prefix match. Requests to /api/users would be proxied to https://api.example.com/users.
URL mappings can also be configured at runtime through DevTools.
Auth Defaults
Activity authentication simulation supports three modes, configurable via DevTools:
| Mode | Behavior |
|---|---|
auto_approve | AUTHORIZE immediately returns a mock code (default) |
auto_deny | AUTHORIZE returns error 4003 |
manual | Shows OAuth2 consent modal in Stage UI |
Application ID
The mock server generates an application ID automatically for each session. If your activity requires a specific application ID, pass it in the session config:
defaultSessionConfig: {
applicationId: '1234567890'
}defaultSessionConfig: {
applicationId: '1234567890'
}Loop Protection
Mock Server detects infinite loops when bots trigger themselves:
// Defaults (not configurable via config file)
loopThreshold: 10, // Events per second
loopCooldown: 5000 // Milliseconds// Defaults (not configurable via config file)
loopThreshold: 10, // Events per second
loopCooldown: 5000 // MillisecondsWhen 10+ MESSAGE_CREATE events occur in 1 second, loop protection triggers a 5-second cooldown. DevTools shows when this happens.
To disable for a specific session (via code):
session.loopProtectionEnabled = falsesession.loopProtectionEnabled = falseSession Limits
Resource limits per session:
| Resource | Limit | Behavior |
|---|---|---|
| Actions | 10,000 | LRU eviction (oldest 10%) |
| Logs | 10,000 | LRU eviction |
| Stage Events | 1,000 | Buffer with replay support |
| Session TTL | 1 hour | Auto-cleanup on inactivity |
Production Considerations
Mock Server is designed for development and testing:
Do not run Mock Server in production. It has no authentication and is not designed for public exposure.
For CI environments:
# Set explicit mode
ROBO_MOCK_MODE=true npx robo mock test
# Or use the CLI flag
npx robo dev --mockYou should see the mock server start and your bot connect. If using npx robo dev --mock, Stage UI opens automatically in your browser.
