Skip to content

An MCP (Model Context Protocol) gateway for the Ragie Model Context Protocol server that implements OAuth authentication using WorkOS. This gateway enables secure access to Ragie's MCP services through OAuth 2.0 authentication flows.

License

Notifications You must be signed in to change notification settings

ragieai/mcp-gateway

Repository files navigation

Ragie MCP Gateway

A multi-tenant MCP (Model Context Protocol) gateway for the Ragie Model Context Protocol server that implements bearer token authentication using WorkOS. This gateway enables secure, organization-based access to Ragie's MCP services through JWT token validation and organization membership verification.

Overview

This gateway acts as a secure proxy between AI clients (like Claude, OpenAI, or Anthropic) and the Ragie MCP server. It provides:

  • Bearer Token Authentication: JWT token verification via WorkOS JWKS
  • Organization-Based Routing: Multi-tenant routing with organization-scoped endpoints
  • Organization Membership Validation: Verifies user membership in organizations via WorkOS
  • Optional Partition Mapping: Maps organization IDs to Ragie partitions for flexible routing with optional per-organization API keys
  • Proxy Functionality: Transparent forwarding of authenticated requests to Ragie MCP services
  • OAuth Discovery Endpoints: Well-known endpoints for OAuth metadata discovery

Features

  • 🔐 Bearer Token Authentication: JWT token verification using WorkOS JWKS
  • 🏢 Multi-Tenant Architecture: Organization-based routing and access control
  • Membership Validation: Automatic verification of user membership in organizations
  • 🗺️ Flexible Routing: Optional organization-to-partition mapping with per-organization API key support
  • 🔄 Request Proxying: Seamless forwarding to Ragie MCP services
  • 📋 OAuth Discovery: Well-known endpoints for OAuth metadata
  • 🚀 Production Ready: Graceful shutdown, error handling, and structured logging
  • 🧪 Test Coverage: Comprehensive test suite with Jest

Prerequisites

  • Node.js 18+
  • WorkOS account and application setup
  • Ragie API key and MCP server access

Installation

Using npx (Recommended)

Run the gateway directly without installing:

npx @ragieai/mcp-gateway

Global Installation

Install globally for system-wide access:

npm install -g @ragieai/mcp-gateway

Then run it from anywhere:

mcp-gateway

Local Installation

Install as a dependency in your project:

npm install @ragieai/mcp-gateway

Then run it with:

npx mcp-gateway

Or add it to your package.json scripts:

{
  "scripts": {
    "start:gateway": "mcp-gateway"
  }
}

Development Setup

If you want to contribute or customize the gateway:

# Clone the repository
git clone <repository-url>
cd mcp-gateway

# Install dependencies
npm install

# Copy the environment template
cp env.example .env

# Configure your environment variables in .env (see Configuration section)

# Build the project
npm run build

Configuration

The gateway requires several environment variables to be configured. You can set these via:

  • Environment variables in your shell
  • A .env file in the current directory (loaded automatically)
  • Your deployment platform's environment configuration

Required Variables

  • RAGIE_API_KEY: Your Ragie API key for accessing MCP services
  • WORKOS_API_KEY: Your WorkOS API key
  • WORKOS_AUTHORIZATION_SERVER_URL: Your WorkOS AuthKit authorization server URL
  • WORKOS_CLIENT_ID: Your WorkOS application client ID

Optional Variables

  • BASE_URL: The public URL of your gateway server (defaults to http://localhost:{PORT} where {PORT} is the configured port)
  • PORT: Server port (defaults to 3000)
  • LOG_LEVEL: Logging level - debug, info, warn, or error (defaults to info)
  • LOG_FORMAT: Log format - json or pretty (defaults to pretty)
  • NODE_ENV: Environment mode (development, production, etc.)
  • RAGIE_BASE_URL: Ragie API base URL (defaults to https://api.ragie.ai/)
  • MAPPING_FILE: Path to a JSON file mapping organization IDs to Ragie partitions (optional)
  • STRICT_MAPPING: Enable strict mapping mode - only organizations in the mapping file are allowed (defaults to false, requires MAPPING_FILE)
  • STRICT_API_KEYS: Enable strict API key handling - requires all mappings to have an apiKey field (defaults to false, see Per-Organization API Keys section for details)

Example .env File

RAGIE_API_KEY=your_ragie_api_key_here
WORKOS_API_KEY=your_workos_api_key_here
WORKOS_AUTHORIZATION_SERVER_URL=https://api.workos.com/auth/v1
WORKOS_CLIENT_ID=your_workos_client_id_here

# Optional: Base URL (defaults to http://localhost:{PORT} where {PORT} is the configured port)
# BASE_URL=http://localhost:3000

PORT=3000
LOG_LEVEL=info
LOG_FORMAT=pretty
NODE_ENV=production
# Optional: Ragie API base URL (defaults to https://api.ragie.ai/)
# RAGIE_BASE_URL=https://api.ragie.ai/
# Optional: Organization mapping
# MAPPING_FILE=mapping.json
# STRICT_MAPPING=false
# STRICT_API_KEYS=false

Usage

Basic Usage

Run the gateway with default settings:

npx @ragieai/mcp-gateway

The gateway will start on port 3000 (or the port specified in PORT environment variable).

Organization Mapping

The gateway supports optional organization-to-partition mapping for flexible routing. Create a JSON mapping file:

{
  "org_A1A1A1A1A1A1A1A1A1A1A1A1A1": {
    "partition": "soc2"
  },
  "org_B2B2B2B2B2B2B2B2B2B2B2B2B2": {
    "partition": "custom-partition",
    "apiKey": "optional_ragie_api_key_for_this_org"
  }
}

Each organization mapping can include:

  • partition (required): The Ragie partition name to route to
  • apiKey (optional): A custom Ragie API key for this organization. If not provided, the default RAGIE_API_KEY will be used.

Set the MAPPING_FILE environment variable to enable mapping. The path can be absolute or relative to the current working directory:

MAPPING_FILE=mapping.json npx @ragieai/mcp-gateway

Or in your .env file:

MAPPING_FILE=mapping.json

Note: The mapping file is loaded once at startup. If the file cannot be read or contains invalid JSON, the gateway will fail to start with an error. Changes to the mapping file require restarting the gateway to take effect.

Strict Mapping Mode

When strict mapping is enabled, only organizations defined in the mapping file are allowed. Requests to unmapped organizations will return a 404 error. Set STRICT_MAPPING=true:

MAPPING_FILE=mapping.json STRICT_MAPPING=true npx @ragieai/mcp-gateway

Or in your .env file:

MAPPING_FILE=mapping.json
STRICT_MAPPING=true

Example: Running with Environment Variables

BASE_URL=https://gateway.example.com \
RAGIE_API_KEY=your_key \
WORKOS_API_KEY=your_workos_key \
WORKOS_AUTHORIZATION_SERVER_URL=https://api.workos.com/auth/v1 \
WORKOS_CLIENT_ID=your_client_id \
LOG_FORMAT=json \
MAPPING_FILE=mapping.json \
STRICT_MAPPING=false \
STRICT_API_KEYS=false \
npx @ragieai/mcp-gateway

API Endpoints

OAuth Discovery Endpoints

  • GET /.well-known/oauth-protected-resource - Returns OAuth protected resource metadata
  • GET /.well-known/oauth-authorization-server - Returns OAuth authorization server metadata (proxied from WorkOS)

Protected Endpoints

  • POST /:organizationId/mcp - Proxies requests to Ragie MCP server (requires bearer token)

Path Rewriting

The gateway rewrites paths when proxying to the Ragie MCP server:

  • Without mapping: POST /org_123/mcpPOST /mcp/org_123/ (organization ID is lowercased, trailing slash added)
  • With mapping: POST /org_123/mcpPOST /mcp/soc2/ (if org_123 maps to partition soc2, trailing slash added)

The gateway constructs the target URL by combining RAGIE_BASE_URL with the rewritten path. For example, if RAGIE_BASE_URL is https://api.ragie.ai/ and the path is rewritten to /mcp/soc2/, the final URL will be https://api.ragie.ai/mcp/soc2/.

Per-Organization API Keys

When using organization mapping, you can optionally specify a custom Ragie API key for each organization. This allows different organizations to use different Ragie API keys:

{
  "org_A1A1A1A1A1A1A1A1A1A1A1A1A1": {
    "partition": "soc2",
    "apiKey": "ragie_api_key_for_org_1"
  },
  "org_B2B2B2B2B2B2B2B2B2B2B2B2B2": {
    "partition": "custom-partition"
  }
}

Default Behavior (STRICT_API_KEYS=false):

  • Organizations with an apiKey in the mapping will use that key
  • Organizations without an apiKey in the mapping will fall back to the default RAGIE_API_KEY from environment variables
  • In the example above:
    • org_A1A1A1A1A1A1A1A1A1A1A1A1A1 will use its custom API key
    • org_B2B2B2B2B2B2B2B2B2B2B2B2B2 will use the default RAGIE_API_KEY from environment variables

Strict API Key Mode (STRICT_API_KEYS=true): When strict API key mode is enabled, all organization mappings must include an apiKey field:

  • With STRICT_MAPPING=true: All mappings must have apiKey, and RAGIE_API_KEY is not used (can be omitted)
  • With STRICT_MAPPING=false: All mappings in the file must have apiKey, but RAGIE_API_KEY can still be set for fallback when an organization is not found in the mapping file

If a mapping entry is missing an apiKey when STRICT_API_KEYS=true, the gateway will fail to start with a validation error.

Example with strict API keys:

{
  "org_A1A1A1A1A1A1A1A1A1A1A1A1A1": {
    "partition": "soc2",
    "apiKey": "ragie_api_key_for_org_1"
  },
  "org_B2B2B2B2B2B2B2B2B2B2B2B2B2": {
    "partition": "custom-partition",
    "apiKey": "ragie_api_key_for_org_2"
  }
}

Enable strict API keys in your .env file:

MAPPING_FILE=mapping.json
STRICT_API_KEYS=true

Authentication Flow

  1. Client obtains JWT: Clients authenticate with WorkOS and receive a JWT bearer token
  2. Bearer Token: Clients include the token in the Authorization: Bearer <token> header
  3. Token Verification: The gateway verifies the JWT signature using WorkOS JWKS
  4. Membership Validation: The gateway verifies the user is an active member of the requested organization
  5. Request Proxying: Authenticated requests are proxied to the Ragie MCP server with the Ragie API key

Security Features

  • JWT Verification: All bearer tokens are cryptographically verified using WorkOS JWKS
  • Organization Membership: Users must be active members of the organization they're accessing
  • API Key Injection: Ragie API key is automatically injected in proxied requests (default or per-organization)
  • Error Handling: Proper HTTP status codes and WWW-Authenticate headers for auth failures
  • Strict Mapping: Optional strict mode restricts access to only mapped organizations

Development

Project Structure

  • Gateway Class: Main application logic and Express server setup
  • Configuration: Environment-based configuration management with Zod validation
  • Logger: Structured logging with configurable levels and formats (JSON or pretty)
  • Tests: Comprehensive test coverage with mocked dependencies

Available Scripts

  • npm run build - Compile TypeScript to JavaScript
  • npm run dev - Start development server with hot reloading
  • npm start - Start production server (after build)
  • npm run clean - Clean build artifacts
  • npm run typecheck - Run typecheck
  • npm run lint - Run ESLint
  • npm run lint:fix - Fix ESLint issues
  • npm run format - Format code with Prettier
  • npm test - Run test suite
  • npm run test:watch - Run tests in watch mode
  • npm run test:coverage - Run tests with coverage report

Integration with AI Clients

This gateway is designed to work with AI clients that support bearer token authentication. Clients should:

  1. Authenticate users with WorkOS to obtain JWT tokens
  2. Include bearer tokens in the Authorization header for all requests
  3. Specify the organization ID in the URL path: POST /{organizationId}/mcp
  4. Handle 401 responses with WWW-Authenticate headers for authentication errors
  5. Discover OAuth endpoints via /.well-known/oauth-protected-resource if needed

Example Request

curl -X POST \
  -H "Authorization: Bearer <workos-jwt-token>" \
  -H "Content-Type: application/json" \
  -d '{"query": "example query"}' \
  https://gateway.example.com/org_123/mcp

Multi-Tenant Architecture

The gateway supports multi-tenant access through organization-based routing:

  • Each organization has its own endpoint path
  • Users must be members of the organization to access its endpoints
  • Optional mapping allows organizations to share Ragie partitions
  • Strict mapping mode restricts access to only mapped organizations

Deployment

The gateway can be deployed to any platform that supports Node.js:

Docker Deployment

The project includes a production-ready Dockerfile with multi-stage builds for optimal image size and security.

Building the Docker Image

Build the Docker image from the project root:

docker build -t mcp-gateway .

You can also specify a tag with version:

docker build -t mcp-gateway:latest -t mcp-gateway:0.0.2 .

Running the Container

Run the container with required environment variables:

docker run -d \
  --name mcp-gateway \
  -p 3000:3000 \
  -e RAGIE_API_KEY=your_ragie_api_key_here \
  -e WORKOS_API_KEY=your_workos_api_key_here \
  -e WORKOS_AUTHORIZATION_SERVER_URL=https://api.workos.com/auth/v1 \
  -e WORKOS_CLIENT_ID=your_workos_client_id_here \
  mcp-gateway

Using Environment File

For easier management, you can use a .env file with Docker:

docker run -d \
  --name mcp-gateway \
  -p 3000:3000 \
  --env-file .env \
  mcp-gateway

Optional Configuration

Include optional environment variables as needed:

docker run -d \
  --name mcp-gateway \
  -p 3000:3000 \
  -e RAGIE_API_KEY=your_ragie_api_key_here \
  -e WORKOS_API_KEY=your_workos_api_key_here \
  -e WORKOS_AUTHORIZATION_SERVER_URL=https://api.workos.com/auth/v1 \
  -e WORKOS_CLIENT_ID=your_workos_client_id_here \
  -e BASE_URL=https://gateway.example.com \
  -e PORT=3000 \
  -e LOG_LEVEL=info \
  -e LOG_FORMAT=json \
  -e MAPPING_FILE=/app/mapping.json \
  -e STRICT_MAPPING=false \
  -e STRICT_API_KEYS=false \
  -v $(pwd)/mapping.json:/app/mapping.json:ro \
  mcp-gateway

Docker Compose

For easier deployment, you can use Docker Compose. Create a docker-compose.yml:

version: '3.8'

services:
  mcp-gateway:
    build: .
    container_name: mcp-gateway
    ports:
      - "3000:3000"
    environment:
      - RAGIE_API_KEY=${RAGIE_API_KEY}
      - WORKOS_API_KEY=${WORKOS_API_KEY}
      - WORKOS_AUTHORIZATION_SERVER_URL=${WORKOS_AUTHORIZATION_SERVER_URL}
      - WORKOS_CLIENT_ID=${WORKOS_CLIENT_ID}
      - BASE_URL=${BASE_URL:-http://localhost:3000}
      - PORT=3000
      - LOG_LEVEL=${LOG_LEVEL:-info}
      - LOG_FORMAT=${LOG_FORMAT:-pretty}
      - MAPPING_FILE=${MAPPING_FILE:-}
      - STRICT_MAPPING=${STRICT_MAPPING:-false}
      - STRICT_API_KEYS=${STRICT_API_KEYS:-false}
    volumes:
      - ./mapping.json:/app/mapping.json:ro
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/.well-known/oauth-protected-resource"]
      interval: 30s
      timeout: 3s
      retries: 3
      start_period: 5s

Then run:

docker-compose up -d

License

MIT License - see LICENSE file for details.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Ensure all tests pass
  6. Submit a pull request

Support

For issues and questions, please refer to the project's issue tracker or documentation.

About

An MCP (Model Context Protocol) gateway for the Ragie Model Context Protocol server that implements OAuth authentication using WorkOS. This gateway enables secure access to Ragie's MCP services through OAuth 2.0 authentication flows.

Resources

License

Stars

Watchers

Forks

Packages