Skip to main content
Glama
rajeshkumar-okta

ProGear MCP Servers

ProGear MCP Servers

Un único gateway MCP para la demo de equipamiento de baloncesto ProGear, que aloja cuatro dominios (Inventory, Customer, Sales y Pricing), cada uno hablando el protocolo MCP real (transporte Streamable HTTP) y protegido por tu propia organización de Okta (su propio Custom Authorization Server + set de scopes por dominio).

Este es un hermano deliberadamente más pequeño de ProGearSalesAI: sin Auth0 FGA, sin orquestador LangGraph, sin frontend. El gateway en sí simplemente valida cualquier token bearer que reciba; no le importa cómo lo haya obtenido el llamador. packages/local-tester (solo local, no desplegado) demuestra una forma en que un llamador podría hacerlo: inicio de sesión humano con PKCE + un agente que realiza el intercambio ID-JAG para acuñar ese token, reflejando el flujo Cross-App Access de la aplicación original.

Forma de despliegue

Un solo proceso, un solo servicio de Render, un solo comando de build/start. packages/gateway monta los 4 dominios en diferentes caminos detrás de una única aplicación Express:

Mount

Scopes

Herramientas

/inventory/mcp

inventory:read, inventory:alert, inventory:write

list_products, search_inventory, check_stock, get_low_stock_alerts, get_inventory_summary, update_inventory_quantity

/customer/mcp

customer:read, customer:lookup, customer:history

get_customer, search_customers, get_customers_by_tier, get_top_customers, get_customer_summary

/sales/mcp

sales:read, sales:quote, sales:order

list_orders, get_order, get_pipeline, create_quote, create_order, cancel_order

/pricing/mcp

pricing:read, pricing:margin, pricing:discount

get_price, get_category_pricing, calculate_bulk_price, get_discount_structure

Cada mount valida contra su propio Custom Authorization Server de Okta (diferente issuer/audience por dominio), aunque todos corran en el mismo proceso: un token emitido para el auth server de inventario no se puede usar contra /customer/mcp; y dentro de un mount, cada llamada a una herramienta verifica su scope requerido contra los scopes concedidos en el token del llamador (un token que carece de inventory:write puede llamar a check_stock, pero no a update_inventory_quantity).

packages/mcp-inventory, mcp-customer, mcp-sales, mcp-pricing también siguen funcionando como servidores independientes (con su propio server.ts + /mcp + /health, variables de entorno de un solo dominio) por si alguna vez quieres separarlos en despliegues distintos; el gateway simplemente importa la lógica de registro de herramientas de cada uno (export ./tools) y lo monta bajo su propia configuración de auth en lugar de llamar a .listen() él mismo.

Related MCP server: Meraki MCP Server

Datos

Los datos se siembran desde un snapshot portado del dataset de la demo ProGearSalesAI: 90 SKUs de inventario, 90 entradas de pricing, 34 clientes, tablas de descuento por nivel/volumen (packages/shared/src/data/initial_data.json). Las órdenes/cotizaciones de ventas son solo en memoria. Todo el estado se restablece cuando el proceso se reinicia: es un servidor de herramientas, no un sistema de registro.

Estructura del proyecto

packages/
  shared/            # ported data + store, JWKS auth + scope enforcement, HTTP/MCP transport helper
  mcp-inventory/      mcp-customer/      mcp-sales/      mcp-pricing/   # tool definitions + standalone entrypoint each
  gateway/            # the actual deployment: mounts all 4 at /inventory, /customer, /sales, /pricing
  local-tester/       # local-only: PKCE login + agent ID-JAG exchange, calls the deployed gateway (see its own README)

Desarrollo local

npm install
npm run build            # builds shared + all 4 domains + gateway, in dependency order

npm run dev:gateway       # tsx watch, all 4 mounts on one port (default 3000)

Si no se setean las variables de entorno de Okta relevantes para un mount, ese mount devuelve 500 en cada request /mcp, a menos que establezcas ALLOW_INSECURE=true, que salta la validación de token y otorga todos los scopes en todos los mounts; solo para desarrollo local, no lo pongas nunca en un entorno desplegado.

Configuración de Okta

Configura OKTA_DOMAIN una vez, y además OKTA_<DOMAIN>_AUTH_SERVER_ID + OKTA_<DOMAIN>_AUDIENCE por dominio: son exactamente los mismos nombres de variables de entorno ya utilizados en el backend de ProGearSalesAI (OKTA_CUSTOMER_AUTH_SERVER_ID, OKTA_PRICING_AUTH_SERVER_ID, OKTA_INVENTORY_AUDIENCE, etc.), por lo que los valores existentes se pueden copiar tal cual:

OKTA_DOMAIN=https://your-org.okta.com

OKTA_INVENTORY_AUTH_SERVER_ID=...   OKTA_INVENTORY_AUDIENCE=api://progear-inventory
OKTA_CUSTOMER_AUTH_SERVER_ID=...    OKTA_CUSTOMER_AUDIENCE=api://progear-customer
OKTA_SALES_AUTH_SERVER_ID=...       OKTA_SALES_AUDIENCE=api://progear-sales
OKTA_PRICING_AUTH_SERVER_ID=...     OKTA_PRICING_AUDIENCE=api://progear-pricing

Consulta .env.example para la lista completa, incluyendo qué variables de un .env al estilo ProGearSalesAI no aplican aquí (clave de Anthropic, CORS, la propia private key/client ID del Agente IA, porque este gateway solo valida tokens entrantes, no emite ninguno). Los tokens se validan por firma + issuer + audience contra el endpoint Okta JWKS de cada dominio ( createRemoteJWKSet de jose); de este lado no se necesita secreto compartido.

Despliegue en Render

Un solo servicio, ya sea a través del dashboard o del Blueprint incluido.

Manual (New → Web Service):

Campo

Valor

Language

Node

Root Directory

(blanco — monorepo de workspaces de npm, el build corre desde la raíz del repo)

Build Command

npm install && npm run build

Start Command

node packages/gateway/dist/server.js

Health Check Path

/health

Blueprint: render.yaml en la raíz del repo define el mismo servicio único progear-mcp-gateway — New → Blueprint, apunta a este repo y completa las 9 variables de Okta que pide (marcadas sync: false).

Conexión de un agente

Cada mount expone MCP sobre Streamable HTTP en POST/GET/DELETE <mount>/mcp (stateless — sin persistencia de sesión entre solicitudes), además de su propio GET <mount>/health; también existe un GET /health de nivel superior lo monta todo.

Obtén un access token de Okta para el Custom Authorization Server y los scopes relevantes (p. ej., nonces de credentials de cliente para una identidad (service account) ), y luego:

Claude Code CLI:

claude mcp add --transport http progear-inventory \
  https://<your-render-url>/inventory/mcp \
  --header "Authorization: Bearer <token>"

Repite para cada dominio (/customer/mcp, /sales/mcp, /pricing/mcp) con un token dirigido a la audiencia de ese dominio.

Cualquier otro cliente MCP / SDK de agente: apúntalo a la URL /mcp del puerto con un header Authorization: Bearer <token> en cada solicitud.

Descubrimiento por privileges OAuth (sin token estático)

Los clientes que implementan la especificación de autorización de MCP pueden encontrar Okta por su cuenta en lugar de recibir un token prefijado. Cada mount publica una metadata de recurso protegido RFC 9728 en la raíz de la puerta de enlace, con el path del endpoint que describe:

GET /.well-known/oauth-protected-resource/inventory/mcp
GET /.well-known/oauth-protected-resource/customer/mcp
GET /.well-known/oauth-protected-resource/sales/mcp
GET /.well-known/oauth-protected-resource/pricing/mcp
{
  "resource": "https://<your-render-url>/inventory/mcp",
  "authorization_servers": ["https://your-org.okta.com/oauth2/<inventory-auth-server-id>"],
  "scopes_supported": ["inventory:read", "inventory:write", "inventory:alert"],
  "bearer_methods_supported": ["header"],
  "resource_name": "ProGear Inventory MCP"
}

Un 401 procedente de /mcp ahora también incluye el puntero, de modo que un cliente que llama al endpoint en frío aprende dónde autenticarse:

WWW-Authenticate: Bearer resource_metadata="https://<your-render-url>/.well-known/oauth-protected-resource/inventory/mcp"

(Cuando se presenta un token se presentó, pero falla la validación, el desafío incluye además error="invalid_token" y error_description.)

Las URLs en estos documentos se derivan de la solicitud entrante (X-Forwarded-Proto + Host, con trust proxy activado — lo correcto en Render). Configura PUBLIC_BASE_URL=https://<tu-url-render> solo si algo de adelante del gateway reescribe el header Host.

Para permitir que un cliente complete el flujo, registra un cliente OIDC público (Authorization Code + PKCE) en tu org de Okta, añade su redirect URI (Claude.ai usa https://claude.ai/api/mcp/auth_callback) y concede los scopes de ese dominio al acceso del Custom Authorization Server correspondiente.

Aún falta para una conexión completamente sin configuración: dynamic client registration. El endpoint /oauth2/v1/clients de Okta requiere un token SSWS, por lo que no puede anunciarse para registro anónimo — los clientes que insisten en DCR (VS Code / Copilot hoy) necesitan un shinner de registro delante. Los que aceptan un client_id pre-registrado pueden usar el descubrimiento anterior tal cual.

F
license - not found
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    Aggregates multiple MCP servers behind a single, secure endpoint with unified tool/resource discovery, OAuth authentication, and resilient request routing. Enables users to manage and interact with multiple MCP backends through one centralized interface with load balancing and circuit breakers.
    2
  • A
    license
    B
    quality
    C
    maintenance
    Exposes Okta incident-support and administrative workflows to MCP-compatible clients, enabling user investigation, group management, and system log queries.
    24
    69
    Apache 2.0

View all related MCP servers

Related MCP Connectors

  • 34 production API tools over one hosted MCP endpoint.

  • Search, document and execute authenticated API calls across 700+ apps via one MCP server

  • Provide seamless access to Appfolio Property Manager Reporting API through a standardized MCP serv…

View all MCP Connectors

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/rajeshkumar-okta/progear-mcp-servers'

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