Skip to main content
Glama
vryahn

Payment Orchestrator MCP Server

by vryahn

支払いルーティングオーケストレーター

ホットパスにはエビデンス、エッジにはAI。

送信されようとしているカード認証を前提に、どの決済サービスプロバイダーがそれを受け取るべきかを決定します。これは、実証的な承認エビデンスに基づき、オペレーターが実単位で指定する手数料許容度に従って行われます。試行が拒否された場合、拒否のエラークラスをキーとするステートマシンが次に何が起こるかを決定します:同じPSPを後で再試行、今すぐフェイルオーバー、別のチャネル、または停止。ルーティング決定自体は決定的で監査可能であり、その内部で言語モデルは実行されません。

Claude Code内で構築・出荷されました:エンジン、AIエッジレイヤー、評価ハーネス、Web UI、API、そしてこのREADMEは、エージェントセッションで生成されました — 1つのオーケストレーションセッションがサブエージェント(バックエンド、UI、公開、ケーススタディ)に委任する形です — そして、自分で実行できるテストと評価によってゲートされています。エンジニアリング規律は、nutri.で説明されているものと同じです:エージェントがロードしなければならない規約、構造的なガードレール、そして「完了」の定義としての約束ではなく機械。ガードレールは、そうでなければ出荷されていたであろうものを捕捉しました:すべてのAPIパスを落とした書き直し(デプロイ後の検証で発見)、有効な発行者を未確認と誤ってラベル付けしたUI、そして著者の2つの誤った仮定(ページ数ルール、DNS設定)をサブエージェントが実行を拒否したこと。

ライブデモ https://orchestrator.vryahn.com · ケーススタディ https://vryahn.com/work/routing · API api/README.md · MCP MCP.md

84,011件のTESTトランザクション(22〜31日目、テーブルは1〜21日目でトレーニング)でのアウトオブサンプルリプレイ:cost_bias=0での期待承認率72.02%、実際に観測された**66.13%**に対して — +5.89ポイント、方向性のある結果であり、A/Bテストの結果ではありません。制限事項を参照してください。

実行方法

Python 3.11。requirements.txtはランタイムです — fastapiと標準ライブラリ、そしてVercelがインストールする唯一のものです。requirements-dev.txtは、データの再生成、バックテストの実行、MCPの提供、またはローカルでのテストに必要なオフラインスタック(duckdb、pandas、numpy、pyarrow、mcp、uvicorn、httpx)を追加します。

python3.11 -m venv .venv && .venv/bin/pip install -r requirements-dev.txt
.venv/bin/python cli.py --txn-file demo_transactions.json   # 8 decision-boundary cases
.venv/bin/uvicorn api.index:app --reload --port 8000        # API on /api/*, UI from public/

エンジンが読み取るテーブル(routing_tables.json、routing_meta.json)はコミットされているため、新しいクローンはオフラインパイプラインなしでルーティング(およびデプロイ)できます。データモデルが変更された場合のみ再生成してください:

.venv/bin/python synth_attempts.py         # seeded ~300k attempts -> attempts.parquet
.venv/bin/python build_routing_tables.py   # -> routing_tables.json, routing_meta.json
.venv/bin/python backtest.py --json        # -> backtest_summary.json
.venv/bin/python tests.py                  # engine
.venv/bin/python tests_ai.py               # AI edges + HTTP contract
.venv/bin/python evals/decline_eval.py     # normalizer against the golden set

Related MCP server: kong-ai-gateway-mcp

アーキテクチャ

flowchart LR
    subgraph offline["OFFLINE — batch, once per rebuild"]
        G["synth_attempts.py<br/>seeded generator"] --> A[("attempts.parquet<br/>1 row = 1 attempt, ~300k")]
        A -->|"build_routing_tables.py"| T[("routing_tables.json + routing_meta.json<br/>segment x PSP: n, approvals, p_hat, Wilson LB<br/>4-level hierarchy")]
        A -->|"backtest.py — train d1-21, test d22-31"| B["backtest_summary.json<br/>out-of-sample lift"]
    end

    subgraph edgein["EDGE IN — language to enum"]
        RAW["raw PSP decline<br/>ISO 8583 / decline_code / refusalReason / bank prose"] --> N{"decline_normalizer.py<br/>table -> LLM -> safe fallback"}
        EV["evals/ — 48 golden declines<br/>accuracy by route, hallucination gate"] -.->|"scores"| N
    end

    subgraph online["ONLINE — pure engine, never touches raw data"]
        X["txn: amount, bin6/issuer, funding,<br/>channel, attempt #, error history"] --> D{"decide(txn, config)"}
        T --> D
        N -->|"error_class"| D
        D --> S1["1. resolve segment per PSP<br/>walk L0 to L3 until n >= min_support"]
        S1 --> S2["2. score = Wilson LB x amount x (1 - fee)<br/>= expected net collected"]
        S2 --> S3["3. pick PSP — cost_bias 0..1 maps to<br/>fee tolerance 0..10pp; psps_down excluded"]
        S3 --> S4["4. retry state machine<br/>keyed on last error_class"]
        S4 --> R["Decision: route_psp, eligible_psps with scores,<br/>retry policy, reasoning lines"]
    end

    R --> OPS["ops.py — route, explain, simulate,<br/>evidence, normalize, backtest"]
    B --> OPS
    OPS --> CLI["cli.py"]
    OPS --> API["api/index.py — FastAPI on Vercel<br/>+ public/ web UI, same origin"]
    OPS --> MCP["mcp_server.py — 6 MCP tools"]

この設計の理由

  • オフライン/オンライン分割。 decide(txn, config) -> Decisionは純粋です。事前にマテリアライズされたテーブルを一度ロードし、生の試行を読み取ることはないため、決定はマイクロ秒単位で、データベースなしでテスト可能で、事後に監査可能です。これは、本番環境で調整レイヤーとルーティングレイヤーの間に引く境界と同じです。

  • フォールバック付きセグメント階層。 L0はgateway_group × funding × issuer_bucket × amount_band、L3はgateway_groupのみです。サポートはPSPごとに、一度に1つの次元(金額帯 → 発行者 → 資金調達)で解決され、セルがmin_support(デフォルト200)をクリアするまで続き、使用されたレベルは決定とともに報告されます。チャネルは第一級であり、決してドロップされません:ユーザー存在とオフセッションは異なる世界です。

  • 生のレートではなくウィルソン下限。 3/3承認のセグメントは100%セグメントではありません。サポートが薄くなるにつれて境界はゼロに向かって縮小するため、十分なエビデンスのある78%は、別の信頼ルールを追加しなくても、幸運な100%に勝ります。

  • cost_biasを実単位の明示的なノブとして。 トレードオフは「より安いPSPのために放棄する承認のパーセンテージポイント」として述べられます — tolerance = cost_bias × 10pp、そして最良の承認者からその許容度内で最も安いPSPが勝ちます。ブレンドスコアでは、ポイントの端数の手数料差が二桁の承認ギャップを静かに無効にする可能性がありますが、許容度フィルターはそれができません。バックテストはノブの価格を示します:cost_bias=0で72.02% / +5.89ポイント、0.5で71.56% / +5.43ポイント、1.0で69.57% / +3.44ポイント。

  • 盲目的なカウンターではなくエラークラスによる再試行。 insufficient_fundsはアカウントの問題であり、次の請求ウィンドウで同じPSPを再試行します。bank_auth_requiredはオフセッションでは顧客なしでは満たせないため、試行を消費する代わりにユーザー存在チャネルに再スケジュールします。fraud_riskはチェーンを永久に停止します。generic_declineはスコアによって次のPSPにフェイルオーバーします。認識されないクラスは一般的なフェイルオーバーポリシーに劣化し、その旨を報告します。

AIが属する場所 — そして属さない場所

decide()の内部にはLLMはありません。 サンプリングされたトークンでお金が動くべきではありません。言語モデルは、自然言語が実際に問題となる2つのエッジに限定されています。

内部 — decline_normalizer.py。 各PSPは独自の方言で拒否します:ISO 8583の数値、Stripe風のdecline_code、Adyen風のrefusalReason、または生の銀行の散文。再試行ステートマシンは1つのenumをキーとするため、エンジンがそれらを見る前に方言を収束させる必要があります。決定的なテーブルがボリュームを運ぶコードを処理します — 信頼度1.0、レイテンシなし、コストなし。テーブルミスのみがモデルチェーン(Gemini、次にMistral)に到達し、制約付きenumスキーマの下で回答します。enumの外側、または信頼度0.6未満のものはすべて、generic_declineを優先して破棄されます。これは再試行ポリシー自身の安全なデフォルトです。リポジトリはAPIキーが設定されていなくてもグリーンで実行されます。

測定され、信頼されない — evals/。 48のゴールデン拒否:~60%はテーブルヒット、~40%は意図的にテーブル外(スペルミス、冗長な銀行テキスト、珍しいコード)、さらにgeneric_declineが正解であるいくつかの真に曖昧なもの。evals/baseline.jsonは2つのベースラインを記録しています。テーブルのみ(キーなし):32/48 = 66.67%、つまり28のテーブルルートケースで100%、残りの20は安全なgeneric_declineデフォルト。LLM(キー設定済み、--remoteでデプロイ済みAPIに対して実行):48/48 = 100% — 28はテーブル、19はgemini-3.6-flashが回答、1はgeneric_declineが期待される回答だった低信頼フォールバック。ランナーはルートごとの精度とクラスごとの混同行列を報告し、幻覚ゼロを主張し、精度が一致するベースラインより2ポイント以上低下した場合にビルドを失敗させます。

外部 — mcp_server.py。 6つのMCPツール — route_transaction、explain_decision、simulate、segment_evidence、normalize_decline、backtest_summary — により、エージェントは英語でエンジンを操作できます。エージェントはすべての決定を尋問でき、どれも変更できません。MCP.mdを参照してください。

制限事項

  • データは合成です。構造はルーティング決定を非自明にするように設計されており、実際のポートフォリオを再現するものではありません。

  • ライブPSPコネクタはありません:エンジンは決定するだけで、送信はしません。

  • 不正スコアリング、3DSオーケストレーション、ネットワークトークン、スキーム再試行ルールの強制はありません。

  • バックテストは方向性のあるものです。過去のルーティングはランダム化されておらず、容量制限はモデル化されておらず、「期待承認率」はTRAIN期間のウィルソンLBレートをTESTボリュームに適用したものであり、ライブA/B結果ではありません。

  • テーブルはすべての試行をプールしますが、バックテストは最初の試行のみでトレーニングおよびリプレイします。最初の試行のみの本番テーブルが次の修正となるでしょう。

  • LLM評価は48ケースと1回の実行です。この小さなゴールデンセットでの100%は回帰に対するゲートであり、本番のロングテールに関する主張ではありません。

ファイルマップ

ファイル

目的

synth_attempts.py

attempts.parquet用のシード付きジェネレーター。チャネルミックス、PSP手数料、承認モデル、エラーミックス、再試行動作は上部に文書化されています。

build_routing_tables.py

routing_tables.json(セグメント×PSP:n、承認数、p_hat、wilson_lb、全4レベル)とrouting_meta.json(金額帯の境界、発行者ホワイトリスト、bin6→発行者マップ、PSP手数料、エラークラスenum)を構築します。

orchestrator.py

エンジン:decide(txn, config) -> Decision、Configデータクラス。標準ライブラリのみ。

decline_normalizer.py

PSP拒否方言 → エンジンのerror_class enum:まずテーブル、ミス時はLLM、安全なフォールバック。

ops.py

APIとMCPで共有されるオペレーター関数(route、explain、simulate、evidence、normalize、backtest)。

api/index.py

Vercel上のFastAPI。契約はapi/README.mdにあります。

mcp_server.py

MCP stdioサーバー、6つのツール。MCP.mdを参照。

cli.py

CLIフロントエンド:フラグによる1トランザクション、または--txn-fileによるバッチ。

public/

静的Web UI。VercelによってAPIと同じオリジンから提供されます。

demo_transactions.json

why_interestingノート付きの8つの決定境界トランザクション。

backtest.py

TRAIN日1〜21 / TEST日22〜31のリプレイをcost_bias 0 / 0.5 / 1.0で実行。--jsonはbacktest_summary.jsonを書き換えます。

evals/

48のゴールデン拒否、スコアリングランナー、記録されたベースライン。

tests.py / tests_ai.py

アサートベースのチェック:エンジン、次にAIエッジとHTTP契約。


Bryan Rodríguez Abarca · vryahn.com · 技術的な演習から始まり、個人プロジェクトとして一般化されました。合成データ。

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables read-only investigation of payment transactions by building normalized timelines, detecting anomalies like duplicate charges and stuck refunds, and creating diagnostic escalations for human review. Never executes or modifies payment actions.
    -
  • F
    license
    A
    quality
    B
    maintenance
    Enables an LLM agent to investigate a Kong Gateway through fourteen read-only, schema-validated tools and a deterministic diagnostic engine, so it can trace routes, services, plugins and upstream health and explain faults such as why authentication is failing on a path. Every fact comes from the gateway itself, and the model only selects tools and writes the evidence-backed explanation.
    14
    -
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI agents to investigate synthetic fraud cases by pulling transactions, running deterministic rules evaluations, pivoting across devices, and recording auditable case files with provenance.
    4
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI clients to run read-only yes/no checks, classifications, and ordered scores with probabilities, supporting triage, routing, sentiment, and lead-fit decisions through hosted or self-hosted MCP tools.
    41 npm
    AGPL 3.0