KPN Grexx

io.github.WYRE-AI由 GitHub 帳號 WYRE-AI 發布v2.3.1更新於 Oct 30, 2026

KPN IRMA on Grexx: address checks, prequalification, customers, orders, mobile and line tools.

已驗證STDIO僅桌面溝通與協作商業與電商

概覽

AI 產生的概覽

針對 Grexx 上 KPN IRMA 電信 API 的 MCP 伺服器,讓助理查詢荷蘭地址、產品預資格、訂單、客戶、SIM 與行動數據。

可以做什麼
  • 查詢地址可用技術與速率,並依供應商判斷產品預資格
  • 查詢訂單資料、訂單摘要與客戶資料
  • 查看 SIM、行動設定、行動用量、行動訂單與可攜號碼
  • 執行電信商、Radius 與 RAS 檢查,並在 KPN 端啟動線路診斷
  • 以公開參考地址測試連線是否可用
  • 啟用後可額外提供舊版 developer.kpn.com 工具(障礙、可用性、SIM 換卡、MSM)
適用情境
適合 MSP 服務台與電信支援人員在處理客戶事務時,讓助理查詢荷蘭地址、訂單與行動線路相關的 KPN IRMA 資料。若工作已透過 Grexx 代管的 KPN 介面進行,並希望把這些查詢放進助理裡,就值得加入。
執行需求
以本機 stdio 程序執行,來自 GHCR 容器映像(linux/amd64)。需要 Grexx API 憑證:KPN_GREXX_USERNAME 與 KPN_GREXX_PASSWORD,以及 KPN_GREXX_BASE_URL(無預設值,驗收與生產環境不同),可選 KPN_GREXX_TOKEN_URL。閘道模式下憑證透過 X-KPN-Grexx-Username 與 X-KPN-Grexx-Password 標頭傳入,HTTP 傳輸還需要 CONDUIT_S2S_SECRET。舊版工具需要 KPN_CLIENT_ID、KPN_CLIENT_SECRET,可選 MSM 憑證組。
安裝前請注意
需要真實的 KPN 合作夥伴憑證;Grexx 密碼會當作 scope=all 的 OAuth 用戶端密鑰使用,應視為敏感資訊。部分工具會變更 KPN 系統:啟動線路診斷會在 KPN 端觸發測試,舊版 MSM 寫入會建立訂單並要求確認。輸出中的 SIM 碼與 PPP 密碼會被遮蔽。HTTP 模式需要夠強的 CONDUIT_S2S_SECRET 並應綁定回送位址;容器預設監聽 0.0.0.0。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 KPN Grexx,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

kpn-mcp

MCP server for KPN IRMA APIs hosted by Grexx (acceptatie: service-accept.grexx.today), aimed at MSP helpdesks. The default surface is realtime XML over OAuth 2.0 client credentials. The SDK sends HTTP Basic to the token endpoint. POST /realtime uses the Bearer token.

Built on the MCP 2026-07-28 spec via the split v2 SDK (@modelcontextprotocol/server / /node / /client ^2.0.0-beta.5) with dual-era serving: one shared McpServerFactory behind createMcpHandler({ legacy: 'stateless' }) answers both 2025-era initialize-handshake clients and modern 2026-07-28 envelope clients, with the same tool list for every caller. Ships as a GHCR container only (no MCPB bundle). The client is @wyre-ai/node-kpn (Grexx export). Contract: docs/GREXX.md.

Tools (15, flat)

  • kpn_grexx_test_connection: the SDK mints an OAuth client-credentials token and posts a ZipCodeCheckRequest_V6 probe for the public reference address 1012JS 1 (portfolio All). Success means the token endpoint and POST /realtime accepted the Bearer token.

  • kpn_grexx_zipcode_check: technology and speeds at a Dutch address (ZipCodeCheckRequest_V6 → ZipCodeCheckResponse_V5).

  • kpn_grexx_prequalification: address and product-type availability per supplier (PrequalificationRequest_V2 → PrequalificationResponse_V1). When hasBroadband is true, serviceId or referencePhoneNumber is required.

  • kpn_grexx_order_data: customer id, product code, and quantity for an order id (OrderDataRequest_V1 → OrderDataResponse_V1).

  • 11 more realtime tools built from the portal request XSDs (see docs/GREXX.md): kpn_grexx_carrier_info, kpn_grexx_radius_check, kpn_grexx_ras_check, kpn_grexx_start_line_diagnose, kpn_grexx_customer_data, kpn_grexx_order_summary, kpn_grexx_get_sim, kpn_grexx_mobile_settings, kpn_grexx_mobile_usage, kpn_grexx_mobile_orders, kpn_grexx_available_portings. start_line_diagnose starts a test at KPN, so it is not read-only and is never retried. SIM codes and the RadiusCheck PPP password are masked.

IRMA enforces XSD element order and rejects a bad request with an HTTP 200 NinaResponse; both are handled by the server. Queued writes and Proxymodule notifications are not exposed.

Set KPN_LEGACY_DEVELOPER_API=1 to also serve the previous 23 developer.kpn.com tools (disturbances, availability, SIM swap, MSM). They are absent from the default list. See docs/DESIGN.md for that catalog. Gated MSM writes still require confirmation.

Credentials

Grexx username and password are the OAuth client_id and client_secret (scope=all). Copy the interface root from the partner portal (API Gegevens). There is no default base URL: acceptatie and production differ.

Env var (env mode)Gateway header (AUTH_MODE=gateway)Required
KPN_GREXX_USERNAMEX-KPN-Grexx-Usernameyes
KPN_GREXX_PASSWORDX-KPN-Grexx-Passwordyes
KPN_GREXX_BASE_URLX-Grexx-Api-Url (optional, per connection)yes, unless the request sends X-Grexx-Api-Url + X-Grexx-Token-Url. No default. Interface root, without /realtime
KPN_GREXX_TOKEN_URLX-Grexx-Token-Url (optional, per connection)no. Default https://service-accept.grexx.today/oauth/access_token

Example (acceptatie shape — replace the interface id from API Gegevens):

bash
export KPN_GREXX_USERNAME="..."export KPN_GREXX_PASSWORD="..."export KPN_GREXX_BASE_URL="https://service-accept.grexx.today/interfaces/kpn/kpn_partners_acceptatieomgeving/<interface-id>/"# export KPN_GREXX_TOKEN_URL="https://service-accept.grexx.today/oauth/access_token"

See env.example. Token mint, cache, and Bearer retry live in @wyre-ai/node-kpn. Base or token URLs under any other header name (X-KPN-Grexx-Base-Url, ...) are rejected (HTTP 400).

In gateway mode a request missing X-KPN-Grexx-Username or X-KPN-Grexx-Password is answered 401 (JSON-RPC error -32001) before the MCP handler runs. It never falls through to env credentials.

Per-connection Grexx environment (WYREAI-525)

In gateway mode Conduit may send two headers on every call to point that connection at another Grexx environment, such as production:

HeaderValueExample
X-Grexx-Api-UrlInterface root from the portal (API Gegevens), without /realtimehttps://service.grexx.today/interfaces/kpn/<interface-name>/<interface-id>
X-Grexx-Token-UrlOAuth token endpointhttps://service.grexx.today/oauth/access_token
  • Both or neither. When both are absent or empty, the sidecar uses KPN_GREXX_BASE_URL and KPN_GREXX_TOKEN_URL, also when the credential headers are sent without the URL headers. KPN_GREXX_BASE_URL has no default and is then required; KPN_GREXX_TOKEN_URL is optional and defaults to the acceptatie token endpoint (https://service-accept.grexx.today/oauth/access_token). Exactly one URL header is HTTP 400.
  • Honoured only with X-KPN-Grexx-Username / X-KPN-Grexx-Password; without them the request is 401.
  • Scheme and authority: https: only, port 443 only, no userinfo, no query string, no fragment.
  • Exact-host allowlist (GREXX_ALLOWED_HOSTS in @wyre-ai/node-kpn): service.grexx.today and service-accept.grexx.today. No *.grexx.today wildcard; IP literals never match.
  • Paths: token URL path exactly /oauth/access_token; API URL path must start with /interfaces/kpn/ and is the interface root without /realtime (the SDK appends it).
  • Any violation is HTTP 400 (JSON-RPC -32600), and the message never echoes the URL.
  • Private-IP blocking: with header URLs the SDK resolves the host before every token mint and /realtime post, and again at socket connect (undici fetch with a guarded Agent), and refuses private, loopback, link-local (incl. 169.254.169.254), CGNAT, reserved/benchmark, ULA and metadata addresses.
  • Redirects are refused: any 3xx fails the call.
  • Every other URL header name (X-KPN-Grexx-Base-Url, ...) is still rejected with HTTP 400.

HTTP authentication

CONDUIT_S2S_SECRET is required when MCP_TRANSPORT=http. If it is empty, the process logs an error and exits non-zero. It never prints the secret. Known placeholders (changeme, change-me, secret, placeholder, example, your-secret, your-s2s-secret, s2s-secret, replace-me, replace-with-a-real-secret) are rejected the same way, including when MCP_ALLOW_INSECURE_DEV=1 is set.

MCP_ALLOW_INSECURE_DEV=1 is local development only. The process logs a warning, does not check X-Gateway-S2S, and listens on 127.0.0.1 only. A non-loopback MCP_HTTP_HOST (including 0.0.0.0) is ignored in that mode and the override is logged.

MCP_HTTP_HOST is honored when a real secret is set. Unset, that bind stays 0.0.0.0. Set 127.0.0.1 to keep a secret-backed process on loopback. The container image sets 0.0.0.0 and AUTH_MODE=gateway.

With a real secret, every request except /health and /healthz must include:

X-Gateway-S2S: t=<unix seconds>,v1=<hex hmac-sha256>

v1 is HMAC-SHA256 of the exact string t=<unix seconds> (the same t= prefix that starts the header), keyed with CONDUIT_S2S_SECRET, hex-encoded. The timestamp must be within 300 seconds of the server clock. A missing or invalid header is 401. /health and /healthz stay unauthenticated and do not read credentials. The stdio transport does not use CONDUIT_S2S_SECRET.

bash
# sign "t=$NOW" with the gateway-provisioned secretNOW=$(date +%s)SIG=$(printf 't=%s' "$NOW" | openssl dgst -sha256 -hmac "$CONDUIT_S2S_SECRET" | awk '{print $NF}')curl -sS -D- http://127.0.0.1:8080/mcp \  -H "X-Gateway-S2S: t=${NOW},v1=${SIG}" \  -H "X-KPN-Grexx-Username: ..." \  -H "X-KPN-Grexx-Password: ..." \  -H 'Content-Type: application/json' \  -H 'Accept: application/json, text/event-stream' \  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

SDK dependency

Import the Grexx client from @wyre-ai/node-kpn (package root), not /legacy.

The dependency is the published range ^2.2.0 (per-connection URLs + SSRF guard from node-kpn#6; Prequalification and OrderData from node-kpn#5, tag v2.1.0). Token minting is the HTTP Basic behavior from node-kpn#4. /legacy remains the developer.kpn.com client for KPN_LEGACY_DEVELOPER_API=1 only. This server does not mint the Grexx token.

Running

bash
export NODE_AUTH_TOKEN=$(gh auth token)   # GitHub Packages auth for @wyre-ai/*npm installnpm run buildnode dist/index.js                        # stdio (default)# HTTP refuses to start until CONDUIT_S2S_SECRET is a real secretCONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" MCP_TRANSPORT=http node dist/index.js# Local HTTP only, without a service-to-service secret (always binds 127.0.0.1)MCP_ALLOW_INSECURE_DEV=1 MCP_TRANSPORT=http node dist/index.jsnpm run smoke                             # both protocol eras serve the same Grexx tools

Docker (linux/amd64 per fleet law). The image listens on 0.0.0.0 inside the container and defaults to AUTH_MODE=gateway. Publish the port on loopback and pass the S2S secret. Grexx username and password arrive on each request as headers. KPN_GREXX_BASE_URL stays in the environment because a caller-supplied URL is rejected.

bash
docker build --platform linux/amd64 --build-arg GITHUB_TOKEN=$(gh auth token) -t kpn-mcp .docker run \  -e CONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" \  -e KPN_GREXX_BASE_URL="https://service-accept.grexx.today/interfaces/kpn/kpn_partners_acceptatieomgeving/<interface-id>/" \  -p 127.0.0.1:8080:8080 \  kpn-mcp

Compose refuses to start when CONDUIT_S2S_SECRET is unset, publishes 127.0.0.1:8080:8080, and does not inject KPN_GREXX_USERNAME or KPN_GREXX_PASSWORD:

bash
CONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" \KPN_GREXX_BASE_URL="https://service-accept.grexx.today/interfaces/kpn/kpn_partners_acceptatieomgeving/<interface-id>/" \GITHUB_TOKEN=$(gh auth token) \docker compose up --build

Single-tenant HTTP (AUTH_MODE=env) still requires the S2S secret, then uses KPN_GREXX_USERNAME and KPN_GREXX_PASSWORD:

bash
docker run \  -e CONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" \  -e AUTH_MODE=env \  -e KPN_GREXX_USERNAME=... \  -e KPN_GREXX_PASSWORD=... \  -e KPN_GREXX_BASE_URL=... \  -p 127.0.0.1:8080:8080 \  kpn-mcp

/health is a shallow liveness probe. It does not call Grexx and does not read credentials.

Legacy developer.kpn.com tools

With KPN_LEGACY_DEVELOPER_API=1 the process also registers kpn_test_connection, kpn_disturbances_check, kpn_availability_check, kpn_sim_swap_get_date, and the MSM read/write tools. Credentials are KPN_CLIENT_ID / KPN_CLIENT_SECRET (gateway: X-KPN-Client-Id / X-KPN-Client-Secret), plus an optional MSM pair. KPN_BASE_URL stays env-only. A half MSM pair is rejected. MSM writes still create orders, are not retried, and require confirmation (confirm_destructive_action when the client cannot be prompted).

Vendor quirks encoded here

  • OAuth client_credentials, scope=all. The SDK sends HTTP Basic to the token endpoint, then Bearer on POST /realtime (Content-Type: text/xml). Plain XML, no SOAP envelope. Basic Auth is not sent on POST /realtime.
  • This server hands token minting to GrexxClient, which sends HTTP Basic first and may fall back to form-body client_id / client_secret after HTTP 400/401 invalid_client.
  • The token endpoint is not retried into a Bearer-less call. HTTP 401 remints once inside the SDK.
  • IRMA code 108 and HTTP 429 are rate limits. Code 102 is an IP allowlist rejection.
  • Success codes include Success (what acceptatie returned for ZipCodeCheck).

License

Apache-2.0 © WYRE Technology

來源:README.md,提交 42bf6f3

工具

0
SourceWeft 曾在隔離沙箱中以無憑證方式啟動該軟體包一次,以列出其工具,但未能完成:該軟體包類型無法在沙箱中執行。

版本歷史

5
  1. v2.3.1最新Oct 22, 2026
  2. v2.3.0Oct 21, 2026
  3. v2.2.2Oct 20, 2026
  4. v2.2.1Oct 9, 2026
  5. v1.1.1Sep 26, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分