Skip to main content
Glama
nazar256

firefox-relay-mcp

Firefox Relay MCP Gateway

CI License: MIT

Stateless Streamable HTTP MCP gateway for Firefox Relay, built for Cloudflare Workers.

Features

  • Stateless remote MCP server for Firefox Relay

  • OAuth Authorization Code + PKCE (S256) for MCP clients

  • Encrypted Firefox Relay API key envelope inside signed JWT artifacts

  • Streamable HTTP MCP endpoint at /mcp

  • Random mask list/create/update/disable operations

  • Optional custom-domain mask listing when the Relay account supports it

Requirements

  • Node.js 20+

  • npm

  • Cloudflare account with Wrangler authentication

  • A Firefox Relay account with an API key

Connector values

MCP Server URL: https://your-worker.example.com/mcp
Authorization server base URL: https://your-worker.example.com
Resource: https://your-worker.example.com/mcp

What it does

  • Exposes MCP Streamable HTTP at /mcp

  • Acts as its own OAuth Authorization Server for remote MCP clients

  • Collects a user-provided Firefox Relay API key during OAuth consent

  • Encrypts that API key into signed JWT artifacts and does not store it in a database

  • Lets MCP clients list, create, update, and disable Firefox Relay masks

Firefox Relay API key

Users can find the Firefox Relay API key in Firefox Relay under profile icon → Settings.

Supported MCP tools

  • relay_list_random_masks

  • relay_create_random_mask

  • relay_update_random_mask

  • relay_disable_random_mask

  • relay_list_domain_masks

Install

npm install

Quick start

  1. Install dependencies.

  2. Set Worker secrets.

  3. Configure non-secret vars in wrangler.toml or via deploy-time environment overrides.

  4. Run npm run dev for local testing.

  5. Run npm test and npm run typecheck.

  6. Deploy with npm run deploy.

Configure non-secret Worker vars

Update wrangler.toml or your deployment environment with:

  • OAUTH_ISSUER

  • MCP_RESOURCE

  • MCP_AUDIENCE

  • OAUTH_REDIRECT_HTTPS_HOSTS

  • RELAY_DEFAULT_BASE_URL

  • ACCESS_TOKEN_DEFAULT_TTL_DAYS

  • ACCESS_TOKEN_MAX_TTL_DAYS

  • AUTH_CODE_TTL_SECONDS

For public release, wrangler.toml intentionally uses placeholder URLs. Set these to your real deployment values before production deploys:

  • OAUTH_ISSUER=https://your-worker.example.com

  • MCP_RESOURCE=https://your-worker.example.com/mcp

  • MCP_AUDIENCE=https://your-worker.example.com/mcp

Set Worker secrets

Generate and pipe each secret directly into Wrangler:

openssl rand -base64 48 | tr -d '\n' | wrangler secret put OAUTH_JWT_SIGNING_KEY_B64
openssl rand -base64 32 | tr -d '\n' | wrangler secret put UPSTREAM_CONFIG_ENC_KEY_B64
openssl rand -base64 48 | tr -d '\n' | wrangler secret put CSRF_SIGNING_KEY_B64

Deploy sequence

If you do not know the final public Worker URL yet, use this order:

  1. Bootstrap deploy once to get the real workers.dev URL.

  2. Set the three Worker secrets.

  3. Redeploy with real OAUTH_ISSUER, MCP_RESOURCE, and MCP_AUDIENCE values.

Run locally

npm run dev

Validate

npm test
npm run typecheck

Deploy

npm run deploy

Public connector values

After deployment, configure remote MCP clients with:

MCP Server URL: https://your-worker.example.com/mcp
Authorization server base URL: https://your-worker.example.com
Resource: https://your-worker.example.com/mcp

OAuth and stateless design summary

  • /register issues deterministic public client_id values for allowlisted redirect URIs

  • /authorize validates PKCE S256, renders consent, validates the Firefox Relay API key, and issues a short-lived signed auth-code JWT

  • /token exchanges the auth code for bearer access and refresh JWTs

  • JWTs carry an AES-GCM encrypted Relay config envelope; plaintext credentials are never persisted server-side

  • /mcp verifies the access token, decrypts the Relay config, creates a fresh Worker-safe MCP server and transport, and serves the request

Stateless caveats

  • Auth codes are not one-time-use across all isolates because no server-side state is stored

  • Refresh tokens cannot be globally revoked without a stateful primitive

  • Strict global rate limiting requires Durable Objects, KV, or Cloudflare-managed rate limiting

Manual smoke test notes

  1. Register a client with an allowlisted redirect URI.

  2. Complete /authorize with a Firefox Relay API key.

  3. Exchange the returned code at /token.

  4. Call /mcp with the returned bearer token.

  5. Confirm tools list and successful mask operations.

Privacy and security notes

  • The Worker encrypts the Firefox Relay API key into MCP JWT artifacts and does not store it in a database.

  • The Worker is designed to avoid logging API keys, bearer tokens, decrypted envelopes, cookies, or CSRF tokens.

  • Upstream Relay errors are sanitized before they are returned to MCP clients.

Known limitations

  • Auth codes are not globally one-time-use without stateful storage.

  • Refresh tokens cannot be globally revoked without stateful storage.

  • Strict global rate limiting requires Durable Objects, KV, or a Cloudflare-managed alternative.

  • Domain-mask behavior depends on account capabilities and may require Relay premium/custom-domain support.

Project docs

  • docs/PRODUCT_REQUIREMENTS.md

  • docs/IMPLEMENTATION_PLAN.md

  • docs/PROJECT_STATE.md

  • docs/DECISIONS.md

  • docs/RUNBOOK.md

Contributing

See CONTRIBUTING.md.

Security

See SECURITY.md.

License

MIT

A
license - permissive license
-
quality - not tested
C
maintenance

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/nazar256/firefox-relay-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server