ProGear MCP Servers
ProGear MCP Servers
Один MCP-шлюз для демо-приложения ProGear (баскетбольное оборудование), обслуживающий четыре домена — Inventory, Customer, Sales и Pricing, — каждый из которых общается по настоящему протоколу MCP (транспорт Streamable HTTP) и защищён вашей собственной организацией Okta (свой Custom Authorization Server + набор scopes для каждого домена).
Это намеренно уменьшенный «младший брат» проекта ProGearSalesAI: без Auth0 FGA, без оркестратора LangGraph и без фронтенда. Сам шлюз лишь проверяет тот bearer-токен, который ему передали, — ему не важно, как вызывающая сторона его получила. packages/local-tester (только локально, не разворачивается) демонстрирует один из возможных способов: вход человека по PKCE + агент, выполняющий обмен ID-JAG для выпуска этого токена, — зеркально повторяя поток Cross-App Access из исходного приложения.
Схема развёртывания
Один процесс, один сервис Render, одна команда сборки/запуска. packages/gateway монтирует все 4 домена по разным путям за одним приложением Express:
Маршрут | Scopes | Инструменты |
|
|
|
|
|
|
|
|
|
|
|
|
Каждый маршрут проводит проверку в собственном Okta Custom Authorization Server (отдельные issuer/audience для каждого домена), хотя все они работают в одном процессе, — токен, выпущенный для auth-сервера инвентаря, нельзя использовать с /customer/mcp, а внутри маршрута каждый вызов инструмента проверяет требуемый scope на соответствие выданным scopes в токене вызывающей стороны (токен без inventory:write может вызывать check_stock, но не update_inventory_quantity).
packages/mcp-inventory, mcp-customer, mcp-sales, mcp-pricing по-прежнему работают и как автономные серверы (собственные server.ts + /mcp + /health, переменные окружения одного домена), если вы когда-нибудь захотите снова разделить их на отдельные развёртывания, — шлюз просто импортирует логику регистрации инструментов каждого из них (экспорт ./tools) и монтирует её под собственной конфигурацией аутентификации, а не вызывает .listen() сам.
Related MCP server: Meraki MCP Server
Данные
Начальные данные берутся из перенесённого снимка демо-набора данных ProGearSalesAI: 90 SKU инвентаря, 90 записей о ценах, 34 клиента, таблицы скидок по уровням/объёмам (packages/shared/src/data/initial_data.json). Заказы и коммерческие предложения хранятся только в памяти. Всё состояние сбрасывается при перезапуске процесса — это сервер инструментов, а не система учёта (system of record).
Структура проекта
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)Локальная разработка
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)Если для маршрута не заданы соответствующие переменные окружения Okta, этот маршрут возвращает 500 на каждый запрос /mcp, пока вы не установите ALLOW_INSECURE=true, которая пропускает проверку токена и выдаёт все scopes на всех маршрутах, — только для локальной разработки, никогда не задавайте её в развёрнутой среде.
Настройка Okta
Задайте OKTA_DOMAIN один раз, а для каждого домена — OKTA_<DOMAIN>_AUTH_SERVER_ID + OKTA_<DOMAIN>_AUDIENCE: это те же самые имена переменных окружения, которые уже используются в бэкенде ProGearSalesAI (OKTA_CUSTOMER_AUTH_SERVER_ID, OKTA_INVENTORY_AUDIENCE и т.д.), так что существующие значения можно скопировать как есть:
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Полный список — в .env.example, включая то, какие переменные из .env в стиле ProGearSalesAI здесь не действуют (ключ Anthropic, CORS, собственные приватный ключ/client ID AI-агента — этот шлюз проверяет входящие токены, а сам никаких не выпускает). Токены проверяются по подписи + issuer + audience через собственный JWKS-эндпоинт Okta каждого домена (createRemoteJWKSet из jose) — общий секрет с этой стороны не нужен.
Развёртывание на Render
Один сервис — либо через дашборд, либо через включённый Blueprint.
Вручную (New → Web Service):
Поле | Значение |
Language | Node |
Root Directory | (пусто — монорепозиторий npm workspaces, сборка запускается из корня репозитория) |
Build Command |
|
Start Command |
|
Health Check Path |
|
Blueprint: render.yaml в корне репозитория определяет тот же единственный сервис progear-mcp-gateway — New → Blueprint, укажите этот репозиторий, затем заполните 9 переменных окружения Okta, которые он запросит (помечены sync: false).
Подключение агента
Каждый маршрут предоставляет MCP поверх Streamable HTTP на POST/GET/DELETE <mount>/mcp (без сохранения состояния — сессии между запросами не сохраняются), плюс собственный GET <mount>/health; есть также корневой GET /health, перечисляющий все маршруты.
Получите у Okta access token для соответствующего Custom Authorization Server + scopes (например, грант client-credentials для учётной записи сервиса/агента), затем:
Claude Code CLI:
claude mcp add --transport http progear-inventory \
https://<your-render-url>/inventory/mcp \
--header "Authorization: Bearer <token>"Повторите для каждого домена (/customer/mcp, /sales/mcp, /pricing/mcp) с токеном, ограниченным audience этого домена.
Любой другой MCP-клиент / агентский SDK: направьте его на URL /mcp маршрута с заголовком Authorization: Bearer <token> в каждом запросе.
OAuth discovery (без статического токена)
Клиенты, реализующие спецификацию авторизации MCP, могут сами найти Okta, вместо того чтобы получать готовый токен. Каждый маршрут публикует метаданные защищённого ресурса по RFC 9728 в корне шлюза, привязанные к пути того эндпоинта, который он описывает:
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"
}401 от /mcp теперь тоже содержит указатель, так что клиент, обращающийся к эндпоинту без предварительной настройки, узнаёт, где пройти аутентификацию:
WWW-Authenticate: Bearer resource_metadata="https://<your-render-url>/.well-known/oauth-protected-resource/inventory/mcp"(Если токен был предъявлен, но не прошёл проверку, challenge дополнительно содержит error="invalid_token" и error_description.)
URL-адреса в этих документах формируются из входящего запроса (X-Forwarded-Proto + Host, при включённом trust proxy — корректно на Render). Устанавливайте PUBLIC_BASE_URL=https://<your-render-url> только если что-то перед шлюзом переписывает заголовок Host.
Чтобы клиент мог пройти весь поток, зарегистрируйте в своей организации Okta OIDC-публичного клиента (Authorization Code + PKCE), добавьте redirect URI клиента (Claude.ai использует https://claude.ai/api/mcp/auth_callback) и выдайте scopes домена в политике доступа этого Custom Authorization Server.
Чего всё ещё не хватает для подключения вообще без настройки: динамическая регистрация клиентов. Эндпоинт Okta /oauth2/v1/clients требует SSWS API-токен, поэтому его нельзя анонсировать для анонимной регистрации: клиентам, которым требуется DCR (сейчас это VS Code / Copilot), нужна shim-прослойка для регистрации перед ним. Клиенты, принимающие предварительно зарегистрированный client_id, могут использовать описанный выше discovery как есть.
This server cannot be installed
Maintenance
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
- FlicenseNot gradedqualityNot gradedmaintenanceAggregates 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
- FlicenseNot gradedqualityDmaintenanceExposes a curated subset of the Cisco Meraki Dashboard API to MCP-aware clients with role-based access control.3
- AlicenseBqualityCmaintenanceExposes Okta incident-support and administrative workflows to MCP-compatible clients, enabling user investigation, group management, and system log queries.2469Apache 2.0
- AlicenseNot gradedqualityBmaintenanceProvides an isolated MCP gateway for SynapXnet AIOps, DataOps, and MLOps evidence-to-remediation workflows, with OAuth validation, scoped tool discovery, persistent approvals, and audit tracking.AGPL 3.0
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…
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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