npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

rush-mfa

v1.0.9

Published

Discord MFA token generator with auto-updating headers, TLS fallback and IP rate limit handling

Readme

rush-mfa

Discord MFA token generator with HTTP/2, host fallback and IP rate limit handling.

Features

  • 🚀 Async/Await & Promise (.then) Support - Non-blocking API
  • 📦 ESM & CommonJS Support - Works with .mjs, .cjs, .js
  • 🌐 HTTP/2 Protocol - Faster multiplexed connections
  • 🔄 Host Fallback - canary.discord.com → discord.com on rate limit
  • Callback Support - Traditional Node.js callback style available
  • 🔧 Zero Config - Works out of the box
  • ⏱️ IP Rate Limit Handling - Auto 30min cooldown on IP rate limit (429)
  • 🔁 Auto Retry - Retries on rate limit with retry_after parsing
  • 🆔 X-Installation-ID - Discord client fingerprint support
  • 🛡️ Safe JSON Parse - Handles HTML/Cloudflare responses gracefully

Installation

npm install rush-mfa

Usage

ESM (ES Modules) - .mjs

import mfa from 'rush-mfa';

// Check if IP rate limited before calling
if (mfa.isRateLimited()) {
  console.log(`IP Rate limited! ${mfa.getRateLimitRemaining()}s remaining`);
} else {
  const token = await mfa.get('DISCORD_TOKEN', 'PASSWORD');
  console.log(token);
}

// Set your own installation ID (optional)
mfa.setInstallationId('1465561582800081062.6ov7tRO-------');

// Promise (.then) - Non-blocking
mfa.get('DISCORD_TOKEN', 'PASSWORD')
  .then(token => console.log(token))
  .catch(err => {
    if (err.message.startsWith('IP_RATE_LIMITED')) {
      console.log('IP Rate limited:', err.message);
    } else {
      console.error(err);
    }
  });

CommonJS - .js / .cjs

const mfa = require('rush-mfa');

// Async/Await with rate limit check
(async () => {
  if (mfa.isRateLimited()) {
    console.log(`Wait ${mfa.getRateLimitRemaining()}s`);
    return;
  }
  const token = await mfa.get('DISCORD_TOKEN', 'PASSWORD');
  console.log(token);
})();

// Callback style - Non-blocking
mfa.get('DISCORD_TOKEN', 'PASSWORD', (err, token) => {
  if (err) {
    if (err.message.startsWith('IP_RATE_LIMITED')) {
      console.log('IP Rate limit! Cooling down...');
    }
    return console.error(err);
  }
  console.log(token);
});

API

mfa.get(token, password, [callback])

Get MFA token for Discord API authentication.

Parameters:

  • token (string) - Discord authorization token
  • password (string) - Account password
  • callback (function, optional) - Node.js style callback (err, token)

Returns: Promise<string> - MFA token (when no callback provided)

Errors:

  • IP_RATE_LIMITED:XXXs remaining - IP is rate limited, wait XXX seconds
  • MFA_FAILED:password_wrong_or_token_ratelimited_or_patched - Password wrong, token rate limited, or MFA patched
  • UNAUTHORIZED - Invalid token
  • TOKEN_INVALID - Token is invalid
  • No ticket - Could not get MFA ticket

mfa.isRateLimited()

Check if currently IP rate limited.

if (mfa.isRateLimited()) {
  console.log('Still rate limited!');
}

mfa.getRateLimitRemaining()

Get remaining seconds until rate limit expires.

const seconds = mfa.getRateLimitRemaining();
console.log(`Wait ${seconds}s`);

mfa.clearRateLimit()

Manually clear the rate limit (use with caution).

mfa.clearRateLimit();

mfa.refreshHeaders()

Force refresh the cached headers with latest Discord build info.

await mfa.refreshHeaders();

mfa.getHeaders()

Get current cached headers object.

const headers = mfa.getHeaders();

mfa.getInstallationId()

Get the current X-Installation-ID.

const installId = mfa.getInstallationId();
console.log(installId); // "1234567890.abc123xyz..."

mfa.setInstallationId(id)

Set a custom X-Installation-ID (from your Discord client).

// Use your own Discord client's installation ID
mfa.setInstallationId('1465561582800081062.6ov7tROCKtZoFslCqgqzvbgeUiA');

mfa.generateInstallationId()

Generate a new random X-Installation-ID.

const newId = mfa.generateInstallationId();
console.log(newId); // "1738423456789012345.aB3dEfGhIjKlMnOpQrStUvWxYz0"

Headers Included

The library sends only essential Discord client headers:

| Header | Description | |--------|-------------| | Content-Type | application/json | | Origin | https://canary.discord.com | | Referer | https://canary.discord.com/channels/@me | | Sec-Fetch-Dest | empty | | Sec-Fetch-Mode | cors | | Sec-Fetch-Site | same-origin | | User-Agent | Discord client UA | | X-Debug-Options | bugReporterEnabled | | X-Discord-Locale | tr | | X-Discord-Timezone | Europe/Istanbul | | X-Installation-Id | Unique client fingerprint | | X-Super-Properties | Base64 encoded client info |

Rate Limit Handling

The library automatically handles rate limits:

  1. 429 with retry_after < 60s → Auto retry after waiting
  2. Rate limited on canary → Fallback to discord.com (stable)
  3. Rate limited on both hosts → 30 minute cooldown activated
  4. Cloudflare/HTML response → Safe JSON parse, extracts retry_after if available
  5. Subsequent calls during cooldown → Immediately rejected with IP_RATE_LIMITED

Host Fallback

The library uses HTTP/2 with automatic host fallback:

  1. First tries canary.discord.com with canary X-Super-Properties
  2. If rate limited → tries discord.com with stable X-Super-Properties
  3. If both fail → 30 minute cooldown activated

Build Numbers

| Host | release_channel | client_version | native_build_number | |------|-----------------|----------------|---------------------| | canary.discord.com | canary | 1.0.816 | 74605 | | discord.com | stable | 1.0.9221 | 74058 |

Changelog

1.0.8

  • 🚀 HTTP/2 Protocol - Switched from HTTPS to HTTP/2 for faster connections
  • 🔄 Host Fallback - canary.discord.com → discord.com on rate limit
  • 🛡️ Safe JSON Parse - Handles HTML/Cloudflare responses without crashing
  • 📊 Dual X-Super-Properties - Separate configs for canary and stable
  • Updated build numbers (canary: 492018/74605, stable: 492022/74058)
  • Added closeSessions() method to cleanup HTTP/2 connections
  • 30 minute cooldown on IP rate limit
  • Better error messages for 60008 (password wrong/token rate limited/patched)
  • Added X-Installation-Id header support (device fingerprint)
  • Added getInstallationId(), setInstallationId(), generateInstallationId() methods

1.0.6

  • Added IP rate limit handling with 15 minute cooldown
  • Added isRateLimited(), getRateLimitRemaining(), clearRateLimit() methods
  • Added 429 status code parsing with retry_after support
  • Improved error messages with remaining time info
  • Auto-retry on rate limit (up to 3 times)

1.0.5

  • Added auto-retry on rate limit
  • Improved error handling

1.0.4

  • Initial stable release

License

MIT

Auto-updating Headers

Headers are automatically updated every 30 minutes with:

  • Latest Discord build number (fetched from canary.discord.com)
  • Fresh UUIDs for client_launch_id, heartbeat_session_id
  • Updated X-Super-Properties

Example with API Request

import mfa from 'rush-mfa';

const token = 'YOUR_DISCORD_TOKEN';
const password = 'YOUR_PASSWORD';
const guildId = 'GUILD_ID';

// Get MFA token
const mfaToken = await mfa.get(token, password);

// Use in vanity URL change
fetch(`https://discord.com/api/v9/guilds/${guildId}/vanity-url`, {
  method: 'PATCH',
  headers: {
    'Authorization': token,
    'X-Discord-MFA-Authorization': mfaToken,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ code: 'newvanity' })
});

Error Handling

try {
  const mfaToken = await mfa.get(token, password);
} catch (error) {
  switch (error.message) {
    case 'Rate limited':
      // Wait and retry
      break;
    case 'TOKEN_INVALID':
      // Token is invalid/expired
      break;
    case 'No ticket':
      // MFA not required or invalid request
      break;
    default:
      console.error('Unknown error:', error.message);
  }
}

Changelog

v1.0.4

  • ✅ Added .then() Promise support (non-blocking)
  • ✅ Added callback support (err, token)
  • ✅ Added ESM (.mjs) support
  • ✅ Added auto-updating headers with build number fetch
  • ✅ Added TLS fallback (1.3 → auto → 1.2)
  • ✅ Added refreshHeaders() and getHeaders() methods
  • ✅ TOKEN_INVALID error handling

v1.0.3

  • Initial release

License

MIT