modelcontextprotocol/servers · error · Error

Domain ${domain} is not in the allowed domains list.

Error message

Domain ${domain} is not in the allowed domains list.

What it means

Thrown by `validateDataURI` when the `GZIP_ALLOWED_DOMAINS` env var is set (non-empty) and the http/https URL's hostname is neither an exact match nor a subdomain of any allowed domain. This is an SSRF-control allowlist; an empty env disables the check entirely.

Source

Thrown at src/everything/tools/gzip-file-as-resource.ts:157

    if (
      url.protocol !== "http:" &&
      url.protocol !== "https:" &&
      url.protocol !== "data:"
    ) {
      throw new Error(
        `Unsupported URL protocol for ${dataUri}. Only http, https, and data URLs are supported.`
      );
    }
    if (
      GZIP_ALLOWED_DOMAINS.length > 0 &&
      (url.protocol === "http:" || url.protocol === "https:")
    ) {
      const domain = url.hostname;
      const domainAllowed = GZIP_ALLOWED_DOMAINS.some((allowedDomain) => {
        return domain === allowedDomain || domain.endsWith(`.${allowedDomain}`);
      });
      if (!domainAllowed) {
        throw new Error(`Domain ${domain} is not in the allowed domains list.`);
      }
    }
  } catch (error) {
    throw new Error(
      `Error processing file ${dataUri}: ${
        error instanceof Error ? error.message : String(error)
      }`
    );
  }
  return url;
}

/**
 * Fetches data safely from a given URL while ensuring constraints on maximum byte size and timeout duration.
 *
 * @param {URL} url The URL to fetch data from.
 * @param {Object} options An object containing options for the fetch operation.
 * @param {number} options.maxBytes The maximum allowed size (in bytes) of the response. If the response exceeds this size, the operation will be aborted.

View on GitHub (pinned to 76d64c822f)

Solutions

  1. Add the exact hostname (and any subdomain-bearing parent) to `GZIP_ALLOWED_DOMAINS`, e.g. `example.com,raw.githubusercontent.com`.
  2. Use a URL whose host is already in the allowlist or a subdomain of one.
  3. To disable domain filtering entirely, leave `GZIP_ALLOWED_DOMAINS` unset/empty (recognize the security trade-off).

Example fix

# before
GZIP_ALLOWED_DOMAINS=example.com
toolHandler({ data: 'https://raw.githubusercontent.com/x/y/z.md' })
# after
GZIP_ALLOWED_DOMAINS=example.com,raw.githubusercontent.com
toolHandler({ data: 'https://raw.githubusercontent.com/x/y/z.md' })
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED = (process.env.GZIP_ALLOWED_DOMAINS ?? '').split(',').map(d=>d.trim().toLowerCase()).filter(Boolean);
function domainAllowed(url: string): boolean {
  if (ALLOWED.length === 0) return true;
  const h = new URL(url).hostname.toLowerCase();
  return ALLOWED.some(a => h === a || h.endsWith('.' + a));
}
if (!domainAllowed(args.data)) { /* surface error */ }

Prevention

When it happens

Trigger: Operator set `GZIP_ALLOWED_DOMAINS=example.com,github.com` and the tool is called with a URL whose host is e.g. `evil.com` or `notgithub.com` (which is not a subdomain match). The check uses exact hostname match or `.endsWith('.' + allowed)`.

Common situations: Misconfigured allowlist (forgot a domain), URL using a bare host vs `www.` variant that isn't covered, or a CDN/redirect domain not in the list. Note: only `endsWith("." + allowed)` — so `evil-example.com` is correctly rejected, but operators must list every domain they intend to permit.

Related errors


AI-assisted analysis of modelcontextprotocol/servers@76d64c822f (2026-08-12). Data as JSON: /api/errors/1cd16567103d87a4. Report an issue: GitHub.