Payment Orchestrator MCP Server
Orquestador de enrutamiento de pagos
Evidencia en la ruta crítica, IA en los bordes.
Dada una autorización de tarjeta a punto de enviarse, decide qué proveedor de servicios de pago debe recibirla — basándose en evidencia empírica de aprobación, con una tolerancia de comisión que el operador expresa en unidades reales. Si el intento se rechaza, una máquina de estados claveada por la clase de error del rechazo decide qué ocurre a continuación: el mismo PSP más tarde, conmutación por error ahora, un canal diferente, o detenerse. La decisión de enrutamiento en sí es determinista y auditable; ningún modelo de lenguaje se ejecuta dentro de ella.
Construido y publicado dentro de Claude Code: el motor, la capa de IA en los bordes, el arnés de evaluación, la interfaz web, la API y este README se produjeron en sesiones agénticas — una sesión orquestadora que delegaba en subagentes (backend, UI, publicación, caso de estudio) — y están protegidos por los tests y evaluaciones que puedes ejecutar tú mismo. La disciplina de ingeniería es la misma que se describe en nutri.: convenciones que el agente debe cargar, barandillas estructurales y una máquina — no una promesa — como definición de terminado. Las barandillas atraparon lo que de otro modo se habría publicado: una reescritura que eliminó todas las rutas de la API (detectada por verificación post-despliegue), una interfaz que etiquetaba erróneamente emisores válidos como no vistos, y dos suposiciones erróneas del autor (una regla de recuento de páginas, una configuración de DNS) que los subagentes se negaron a aplicar.
Demo en vivo https://orchestrator.vryahn.com · Caso de estudio
https://vryahn.com/work/routing · API api/README.md ·
MCP MCP.md
Replay fuera de muestra sobre 84.011 transacciones TEST (días 22–31, tablas
entrenadas con los días 1–21): aprobación esperada 72,02% con cost_bias=0
frente al 66,13% realmente observado — +5,89 pp, direccional, no un
resultado A/B. Ver Limitaciones.
Ejecutarlo
Python 3.11. requirements.txt es el runtime — fastapi más la biblioteca
estándar, y es lo único que instala Vercel. requirements-dev.txt añade la
pila offline (duckdb, pandas, numpy, pyarrow, mcp, uvicorn, httpx) necesaria
para regenerar datos, ejecutar el backtest, servir MCP o probar localmente.
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/Las tablas que lee el motor (routing_tables.json, routing_meta.json) están
confirmadas, así que un clon nuevo enruta — y despliega — sin la canalización
offline. Regenera solo si cambia el modelo de datos:
.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 setRelated MCP server: ai-log-mcp-server
Arquitectura
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"]Por qué este diseño
División offline/online.
decide(txn, config) -> Decisiones pura. Carga tablas pre-materializadas una vez y nunca lee intentos brutos, por lo que la decisión es de microsegundos, comprobable sin base de datos y auditable a posteriori. Es la misma frontera que dibujarías en producción entre una capa de conciliación y una capa de enrutamiento.Jerarquía de segmentos con respaldo. L0 es
gateway_group × funding × issuer_bucket × amount_band; L3 esgateway_groupsolo. El soporte se resuelve por PSP, una dimensión a la vez (banda de importe → emisor → funding), hasta que una celda superamin_support(por defecto 200), y el nivel usado se informa con la decisión. El canal es de primera clase y nunca se descarta: usuario presente y fuera de sesión son mundos diferentes.Límite inferior de Wilson, no la tasa bruta. Un segmento con 3/3 aprobaciones no es un segmento al 100%. El límite se reduce hacia cero a medida que el soporte se adelgaza, así que un 78% bien evidenciado supera a un 100% afortunado sin una regla de confianza separada añadida.
cost_biascomo perilla explícita, en unidades reales. La compensación se expresa como "puntos porcentuales de aprobación que estoy dispuesto a ceder por un PSP más barato" —tolerance = cost_bias × 10pp, y gana el PSP más barato dentro de esa tolerancia respecto al mejor aprobador. Una puntuación combinada permitiría que una diferencia de comisión de fracciones de punto anulara en silencio una brecha de aprobación de dos dígitos; un filtro de tolerancia no puede. El backtest pone precio a la perilla: 72,02% / +5,89 pp de aprobación concost_bias=0, 71,56% / +5,43 pp con 0,5, 69,57% / +3,44 pp con 1,0.Reintento por clase de error, no por un contador ciego.
insufficient_fundses un problema de cuenta y reintenta el mismo PSP en la siguiente ventana de facturación;bank_auth_requiredfuera de sesión no puede satisfacerse sin el cliente, así que se reprograma a un canal con usuario presente en lugar de quemar intentos;fraud_riskdetiene la cadena permanentemente;generic_declineconmuta por error al siguiente PSP según la puntuación. Una clase no reconocida degrada a la política genérica de conmutación por error y lo indica.
Dónde pertenece la IA — y dónde no
No hay LLM dentro de decide(). El dinero no debería moverse por un token
muestreado. El modelo de lenguaje está confinado a los dos bordes donde el
lenguaje natural es realmente el problema.
Dentro — decline_normalizer.py. Cada PSP rechaza en su propio dialecto:
numéricos ISO 8583, un decline_code tipo Stripe, un refusalReason tipo Adyen,
o prosa bancaria cruda. La máquina de estados de reintento se clavea en un único
enum, así que los dialectos deben colapsar antes de que el motor los vea. Una
tabla determinista maneja los códigos que llevan volumen — confianza 1.0, sin
latencia, sin coste. Solo un fallo de tabla llega a la cadena de modelos (Gemini,
luego Mistral), que responde bajo un esquema de enum restringido. Cualquier cosa
fuera del enum, o por debajo de 0,6 de confianza, se descarta en favor de
generic_decline, que es el valor seguro por defecto de la propia política de
reintento. El repositorio funciona en verde sin claves API configuradas.
Medido, no confiado — evals/. 48 rechazos dorados: ~60% aciertos de tabla,
~40% deliberadamente fuera de tabla (erratas, texto bancario verboso, códigos
inusuales) más algunos genuinamente ambiguos donde generic_decline es la
respuesta correcta. El evals/baseline.json registra dos líneas base.
Solo tabla (sin claves): 32/48 = 66,67%, es decir, 100% en los 28 casos de
ruta de tabla y el valor seguro generic_decline por defecto en los 20 que caen
por el camino. LLM (claves configuradas, ejecutado contra la API desplegada con
--remote): 48/48 = 100% — 28 de tabla, 19 respondidos por
gemini-3.6-flash, 1 por el respaldo de baja confianza donde generic_decline
era la respuesta esperada. El ejecutor informa de la precisión por ruta y una
tabla de confusión por clase, afirma cero alucinaciones y falla la compilación
si la precisión cae más de 2 pp por debajo de la línea base correspondiente.
Fuera — mcp_server.py. Seis herramientas MCP — route_transaction,
explain_decision, simulate, segment_evidence, normalize_decline,
backtest_summary — permiten a un agente operar el motor en inglés. El agente
puede interrogar cada decisión y no cambiar ninguna. Ver MCP.md.
Limitaciones
Los datos son sintéticos. La estructura está diseñada para que las decisiones de enrutamiento no sean triviales, no para reproducir ninguna cartera real.
Sin conectores PSP en vivo: el motor decide, no envía.
Sin puntuación de fraude, orquestación 3DS, tokens de red ni aplicación de reglas de reintento de esquema.
El backtest es direccional. El enrutamiento histórico no fue aleatorizado, los límites de capacidad no se modelan y la "aprobación esperada" es una tasa Wilson-LB del período TRAIN aplicada al volumen TEST — no un resultado A/B en vivo.
Las tablas agrupan todos los intentos mientras que el backtest entrena y reproduce solo con primeros intentos; tablas de producción solo de primeros intentos serían la siguiente corrección.
La evaluación del LLM son 48 casos y una ejecución; 100% en un conjunto dorado tan pequeño es una barrera contra regresiones, no una afirmación sobre la cola larga en producción.
Mapa de archivos
archivo | propósito |
| generador con semilla para |
| construye |
| el motor: |
| dialectos de rechazo PSP → el enum |
| las funciones de operador (route, explain, simulate, evidence, normalize, backtest) compartidas por la API y MCP |
| FastAPI en Vercel; contrato en |
| servidor MCP stdio, seis herramientas; ver |
| interfaz CLI: una transacción mediante flags, o un lote mediante |
| interfaz web estática, servida por Vercel desde el mismo origen que la API |
| 8 transacciones en el límite de decisión con notas |
| replay TRAIN días 1–21 / TEST días 22–31 con |
| 48 rechazos dorados, el ejecutor de puntuación y la línea base registrada |
| comprobaciones basadas en aserciones: el motor, luego los bordes de IA y el contrato HTTP |
Bryan Rodríguez Abarca · vryahn.com · Comenzó como un ejercicio técnico, generalizado como proyecto personal. Datos sintéticos.
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
- AlicenseNot gradedqualityDmaintenanceEnables natural-language investigation of Datadog data including logs, metrics, monitors, traces, hosts, dashboards, events, and incidents, all through read-only API access.2,053MIT
- FlicenseNot gradedqualityBmaintenanceEnables querying and managing AI logs through tools like listing logs, retrieving jobs, and performing AI-powered chat queries. Also provides access to gateway security reports and guardrail testing.
- AlicenseAqualityBmaintenanceInvestigate fraud directly from Claude, Cursor, or any MCP-compatible client. Analyze suspicious activity with clear, evidence-backed verdicts. Pivot from a single signup to every account sharing the same device, IP address, or email inbox. Check entities against a cross-operator abuse network, review linked accounts, and efficiently process your fraud review queue. Read-only by default, with no r10269MIT
- FlicenseNot gradedqualityBmaintenanceEnables operations teams to diagnose and resolve stuck orders via natural-language queries. It provides evidence-based resolution proposals, but any state-changing action requires explicit human confirmation.
Related MCP Connectors
See, price, and control every tool call your AI agents make: policy checks, cost, and audit tools.
A paid remote MCP for AI SDK data query MCP, built to return verdicts, receipts, usage logs, and aud
Enterprise AI Control Plane: governance, guardrails, spend tracking, compliance & smart routing.
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/vryahn/payment_orchestrator'
If you have feedback or need assistance with the MCP directory API, please join our Discord server