Skip to main content
Glama
izambasiron

outsystems-mcp-relay

by izambasiron

outsystems-mcp-relay

Легковесный универсальный ретранслятор stdio → remote MCP с OAuth, а также переопределение издателя RFC 9207 для удаленных серверов, чьи опубликованные метаданные OAuth не соответствуют ответу авторизации. Ноль зависимостей во время выполнения. Один файл.

stdio (your MCP client)  ⇄  outsystems-mcp-relay  ⇄  remote MCP server (Streamable HTTP)

Зачем это существует

Некоторые удаленные развертывания MCP представляют собой обратный прокси перед Keycloak (шлюз MCP OutSystems Developer Cloud — один из них). Они публикуют метаданные OAuth, чей issuer — это URL прокси (например, https://<tenant>/mcp), но сервер авторизации указывает свой настоящий издатель в параметре iss ответа авторизации (например, https://<tenant>/auth/realms/<realm>).

Клиенты, соответствующие RFC 9207, обязаны отклонять такое несоответствие, поэтому вход через OAuth не работает ни в одной среде — Claude Code, pi, Cursor, Codex, да что угодно. Этот ретранслятор позволяет проверять iss по настоящему издателю бэкенда, сохраняя все остальные проверки OAuth строгими. Для обычных серверов он работает как обычный ретранслятор.

Related MCP server: mcp-auth-proxy

Когда это использовать

Сначала попробуйте официальное прямое подключение — направьте свою среду прямо на удаленный URL MCP, без ретранслятора. Обращайтесь к этому ретранслятору только в том случае, если это не удается из-за ошибки несоответствия издателя RFC 9207, описанной выше.

Он существует исключительно для обхода этой одной серверной ошибки. Он не делает ничего лучше официального пути, когда ошибки нет — так что если OutSystems исправит её для всего тенанта, или ваш тенант вообще с ней не сталкивался, откажитесь от ретранслятора и подключайтесь напрямую. Ретранслятор сообщает вам, когда это так: при успешном входе он проверяет, действительно ли потребовалась какая-либо коррекция издателя, и если нет, выводит в stderr заметку об этом. Не ждите проверки «нужно ли это ещё» — если вы видите эту заметку, немедленно возвращайтесь к официальному прямому подключению.

Установка

Требуется Node.js ≥ 20. Без зависимостей — просто файл.

npm install -g outsystems-mcp-relay      # recommended
# or, without a global install:
npx outsystems-mcp-relay <remote-url> ...

Вам не нужно клонировать этот репозиторий, чтобы использовать ретранслятор. Установите из npm (или используйте npx) — и готово. Клонируйте его только для аудита исходного кода (один файл размером ~500 строк) или для внесения вклада.

Использование

outsystems-mcp-relay <remote-url> [options]

  --as-metadata-url <url>   OAuth AS metadata URL (default: discover from remote-url)
  --expected-issuer <url>   Override the RFC 9207 expected issuer (the proxy fix)
  --client-id <id>          Pre-registered client id (skips dynamic registration)
  --bearer <token>          Static bearer token mode (skips OAuth entirely)
  --force                   Ignore cached tokens and re-authenticate
  --no-open                 Print the authorization URL instead of opening a browser
  --help                    Show help

Общий пример (обычный удаленный сервер)

// mcp.json
{
  "mcpServers": {
    "my-remote": {
      "command": "outsystems-mcp-relay",
      "args": ["https://api.example.com/mcp"]
    }
  }
}

Пример OutSystems (несоответствие издателя)

{
  "mcpServers": {
    "outsystems": {
      "command": "outsystems-mcp-relay",
      "args": ["https://<tenant>.outsystems.dev/mcp"]
    }
  }
}

Флаг --expected-issuer не нужен — ретранслятор автоматически определяет реального издателя сервера авторизации из редиректа авторизации (настройки realm Keycloak). Добавляйте --expected-issuer https://<tenant>.outsystems.dev/auth/realms/<realm-id> только если автоопределение не сработало (не-Keycloak сервер): сообщение об ошибке OAuth выводит realm — его полученное значение и есть то, которое нужно использовать. Автоопределение принимает кросс-доменного кандидата только тогда, когда его издатель подтверждён собственными метаданными realm (доступными через список разрешённых источников); для действительно отдельного IdP-хоста передайте --expected-issuer (или --as-metadata-url, чтобы заранее добавить его в список разрешённых).

При первом вызове ретранслятор открывает браузер для входа (или выводит URL с флагом --no-open). Токены кэшируются и обновляются автоматически.

Установка через ИИ-ассистента (вставьте это)

Install the OutSystems MCP fix (outsystems-mcp-relay). The official OutSystems
MCP fails OAuth on every AI harness with an RFC 9207 issuer mismatch — a
server-side bug in the gateway's Keycloak setup.
Step 1: run `npm install -g outsystems-mcp-relay`.
Step 2: ask me for my OutSystems tenant hostname (something like
`mycompany.outsystems.dev`).
Step 3: when I tell you, replace the broken server:
  `claude mcp remove outsystems`
  `claude mcp add -s user --transport stdio outsystems -- outsystems-mcp-relay https://<my-tenant>/mcp`
  (substitute my actual tenant. No other flags needed — the relay auto-detects
  the real authorization-server issuer; if auto-detection can't, ask me to paste
  the OAuth error and use its "received" URL as `--expected-issuer`.)
Step 4: tell me to restart Claude Code, then ask anything OutSystems-related.
The first tool call opens a browser for sign-in (or prints the URL with
`--no-open`).

Быстрый старт Claude Code (несоответствие издателя OutSystems)

Ошибка, которую вы видите, выглядит так:

Issuer mismatch in authorization response (RFC 9207):
expected "https://<tenant>.outsystems.dev/mcp",
received "https://<tenant>.outsystems.dev/auth/realms/<realm-id>"

В терминале (не внутри Claude Code):

npm install -g outsystems-mcp-relay

# 1. remove the broken HTTP entry
claude mcp remove outsystems

# 2. add the relay as a local stdio server — no other flags needed: it
#    auto-detects the real authorization-server issuer
claude mcp add -s user --transport stdio outsystems -- \
  outsystems-mcp-relay \
  https://<tenant>.outsystems.dev/mcp

Затем перезапустите Claude Code. При первом вызове инструмента OutSystems ретранслятор откроет браузер для входа (добавьте --no-open, если предпочитаете вставить URL). Токены кэшируются, поэтому последующие сеансы пропускают вход. Проверьте с помощью /mcp (сервер должен быть подключён) и простой команды «список моих сред».

Вам не нужно искать издателя realm. Ретранслятор автоматически определяет его из редиректа авторизации. Если автоопределение не может (не-Keycloak сервер), сообщение об ошибке выводит его: полученное значение в ошибке И ЕСТЬ значение --expected-issuer.

Как это работает

  • Протокол-агностический пропуск: читает JSON-RPC с разделителями строк из stdin, отправляет каждый кадр дословно на удалённый сервер, записывает ответ JSON-RPC обратно в stdout. Здесь нет семантики инструментов — работает для инструментов, ресурсов, подсказок и всего остального.

  • Обрабатывает детали Streamable HTTP: эхо Mcp-Session-Id, прямые JSON-ответы и ответы 202/text/event-stream (сборка SSE).

  • OAuth: обнаруживает метаданные сервера авторизации, динамически регистрирует публичного клиента (PKCE S256), открывает браузер, проверяет state и iss, обменивает код, обновляет токены при 401. --expected-issuer задаёт издателя, с которым сверяется iss — исправление для несоответствий прокси/Keycloak.

  • Запросы сериализуются (без чередующихся ответов в stdout).

Безопасность

  • RFC 9207 соблюдается: iss проверяется только тогда, когда сервер авторизации действительно его отправляет (отсутствует = AS не реализует RFC 9207, проверки нет; присутствует = строгое строковое совпадение с ожидаемым издателем). --expected-issuer задаёт другое ожидаемое значение — он никогда не отключает проверку.

  • Список разрешённых источников: ретранслятор связывается только с настроенным удалённым источником (и явно указанным --as-metadata-url). Редиректы обрабатываются вручную, и каждый переход проверяется по списку (307/308 сохраняют тело запроса; 301/302/303 переходят на GET в соответствии с семантикой HTTP), а Authorization/Cookie удаляются при смене источника при редиректе (как в нативном fetch). Никакого SSRF.

  • PKCE S256 + случайный state (проверяется) + сервер обратного вызова только на localhost с эфемерным портом.

  • Никогда не логирует секреты: токены и коды авторизации никогда не появляются в выводе (вся диагностика идёт в stderr; stdout содержит только сообщения протокола).

  • Токены хранятся в ~/.mcp-auth/outsystems-mcp-relay-<sha1(url)>.json с правами 0600 — это соглашение экосистемы (та же структура хранилища, что и у mcp-remote). Хранение в связке ключей ОС — запланированное улучшение; см. Не-цели.

Тестирование

npm test                # mock-server protocol test (passthrough, session-id, SSE, 401)
npm run test:e2e -- <remote-url> --expected-issuer <issuer>   # real-tenant round trip

Устранение неполадок

Симптом

Лечение

Issuer mismatch ... expected "…/mcp", received "…/auth/realms/…"

Обычно автоопределение справляется с этим без флагов. Если не может, передайте полученный URL как --expected-issuer — ошибка выведет его для вас

authentication failed после долгого простоя

Кэшированный токен истёк, и обновление не удалось. Повторите с --force (или удалите файл ретранслятора в ~/.mcp-auth/), чтобы пройти аутентификацию заново

Браузер не открывается

Добавьте --no-open — ретранслятор выведет URL авторизации для вставки в браузер

Не удаётся динамическая регистрация клиента

Конечная точка регистрации сервера ограничена (например, политика Trusted-Hosts в Keycloak). Если это прокси OutSystems, такого быть не должно; в противном случае зарегистрируйте клиента самостоятельно и передайте --client-id

Что-то ещё

Откройте issue с полным текстом ошибки (вся диагностика идёт в stderr — отредактируйте любые токены)

Не-цели (v1)

  • Хранение токенов в связке ключей ОС (пока файл с правами 0600)

  • Агрегация/управление несколькими серверами (используйте для этого шлюз)

  • Потоковая передача уведомлений, инициируемых сервером, помимо пропуска

  • Пользовательские флаги CA

Лицензия

MIT

A
license - permissive license
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

  • A
    license
    Not graded
    quality
    D
    maintenance
    Local stdio proxy for Uno MCP Gateway that enables MCP clients without OAuth support to securely connect to authenticated remote servers.
    1
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Bridges stdio-based LLM harnesses to OAuth-protected remote MCP servers via Streamable HTTP, handling PKCE browser login and token refresh automatically.
    9
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI clients like Claude to interact with Cartena tools via MCP, supporting remote OAuth or local stdio authentication.

View all related MCP servers

Related MCP Connectors

  • Access Kernel's cloud-based browsers and app actions via MCP (remote HTTP + OAuth).

  • StremAI MCP: shared memory for AI coding agents. Connected agents can recall. OAuth + local stdio.

  • Browser MCP for logged-in tasks. Uses your Chrome — credentials stay local. Zero-token replay.

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/izambasiron/outsystems-mcp-relay'

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