Polymarket MCP

Un servidor MCP que brinda a cualquier agente acceso a mercados de predicción en Polymarket y Kalshi: búsqueda de mercados, libros de órdenes, historial de precios, posiciones y enrutamiento de órdenes en Polymarket, además de dos herramientas premium de señales (detección de overshoot/fade en vivo y riesgo de disputa de resolución).

Documentación

oddsrail

El rail que los agentes de IA usan para operar en mercados de predicción.

Un servidor MCP que le da a cualquier agente (Claude Code, Claude Desktop, o cualquier cosa compatible con MCP) acceso a mercados de predicción en Polymarket y Kalshi: búsqueda de mercados, libros de órdenes, historial de precios, posiciones y enrutamiento de órdenes, con atribución de código de builder on-chain en Polymarket, más dos herramientas de señales premium (detección de overshoot/fade en juego, riesgo de disputa de resolución).

Gratis de usar y sin comisiones. oddsrail incluye un código de builder de proyecto registrado a 0 bps, por lo que las órdenes enrutadas a través de él se atribuyen sin añadir ni un solo punto básico al trade de nadie. Los ingresos del proyecto provienen de una parte del pool de recompensas semanales de builders de Polymarket, pagado por el propio programa de Polymarket, no por ti. Ejecutar tu propio perfil de builder en su lugar es una variable de entorno (ODDSRAIL_BUILDER_CODE), y server_info siempre te dice qué código está en uso. Sin niveles de comisiones, sin herramientas bloqueadas por pago, sin necesidad de cuenta.

Cómo se compara oddsrail

Verificado directamente contra cada alternativa (sus repos, endpoints en vivo y entradas de registro, septiembre de 2026), no desde su marketing:

oddsrailAPIs crudas de las venuespmxtSimmerPolymarket agent-skills
Qué esservidor MCP autoalojadolas propias venuesAPI unificada + SDK + MCP, "CCXT para mercados de predicción"plataforma de trading para agentes + SDK + MCPdocumentos de skills en markdown para agentes
Venues donde puedes operarPolymarket, Kalshiuna cada unaPolymarket, Opinion, Limitless (escrituras alojadas); una docena más para datosPolymarket, Kalshi, más sus propios mercados sandbox $SIMSolo Polymarket
Custodiano custodial; las claves nunca salen de tu máquinatuyasmodo alojado: "PMXT maneja custodia e infraestructura de firma"; modo autoalojado: tus clavesautocustodia, firma localtuyas (solo documentación)
Atribución que controlassí: ODDSRAIL_BUILDER_CODE anula el valor predeterminado de 0 bpsn/ano documentadono documentadodocumenta encabezados de builder para tu propio código
Costo para el trader0 bps, herramientas gratuitasgratisprecios alojados no en el READMEno documentadogratis
Código abiertoMIT, código fuente completon/aMIT, ~2.1k estrellasno indicadodocs; licencia no indicada
Salvaguardas del operadorlímites de nocional, límite de órdenes abiertas, mercados permitidos; aplicados antes de la solicitud, también en dry-runningunano documentadolímites por trade, topes diarios, stop-loss/take-profit, kill switchninguna
Paper tradingfills en dry-run contra el libro en vivo, P&Lningunono documentadosandbox virtual $SIM, luego pasar a dinero realninguno
Costo con book-walking, auditoría de liquidación, fallos clasificados por jurisdicción, notas de peculiaridades de venues con fechasí, las cuatronono documentadono documentadopeculiaridades parcialmente documentadas
Tiempo realwatch_book, acotadowebsocket, tuyo para conectarno documentado en el READMEno documentadowebsocket documentado

Verificado el 2026-09-02 desde el propio README o docs de cada proyecto (pmxt: github.com/pmxt-dev/pmxt; Simmer: docs.simmer.markets; agent-skills: github.com/Polymarket/agent-skills). "No documentado" significa exactamente eso, no "ausente". Vuelve a verificar antes de citar; estos proyectos se mueven rápido.

La diferencia clave, en una línea: pmxt es la referencia para operar en todas partes; Simmer es la referencia para una economía de agentes con sandbox y capa de reputación; oddsrail es la referencia para operar correctamente, sin custodia, con atribución que tú controlas.

Dónde los demás están honestamente por delante: pmxt opera en tres venues frente a nuestras dos y cubre una docena más para datos, con conveniencia alojada y una comunidad muchas veces más grande que la nuestra. Simmer tiene un sandbox de saldo virtual, rieles de stop-loss y take-profit que no tenemos, una capa pública de razonamiento/reputación y un marketplace de skills de estrategias. Los agent-skills de Polymarket son la documentación propia de la venue y cubren puentes y depósitos, que oddsrail no cubre.

¹ La API cruda de Polymarket tiene los endpoints. También modela rechazos como valores de retorno ok:false, ordena sus libros de peor a mejor, incluye un endpoint de trades que devuelve la cinta pública del mercado y aplica un mínimo nocional no documentado de $1. oddsrail existe porque nos topamos con cada uno de esos problemas y codificamos la solución.

² Los precios de Kalshi son cadenas de dólares (los centavos enteros se eliminaron en 2026-03), su libro de órdenes es solo de ofertas en ambos lados, y su SDK actual requiere Python ≥3.13. Todo normalizado aquí.

Inicio rápido

Se requiere Python 3.11+.

pip install oddsrail
claude mcp add --transport stdio oddsrail -- oddsrail

O desde un clon, sin instalar:

python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
claude mcp add --transport stdio oddsrail -- /abs/path/to/oddsrail/.venv/bin/python -m oddsrail.server

Luego pídele al agente: "busca mercados sobre la final de la Copa del Mundo y ejecuta la señal de overshoot en el favorito".

Instalar en un solo paso

ClienteCómo
Claude web o de escritorio, nada que instalar (alojado, paper trading)Configuración, Conectores, Añadir conector personalizado, URL https://mcp.oddsrail.app/mcp, luego inicia sesión con tu correo. Ver Alojado.
Claude Code (alojado, paper trading)claude mcp add --transport http oddsrail https://mcp.oddsrail.app/mcp
Claude Code (plugin, con las cuatro skills de flujo de trabajo)claude plugin marketplace add hmesutozsoy/oddsrail luego claude plugin install oddsrail@oddsrail
Claude Code (solo servidor)claude mcp add --transport stdio oddsrail -- uvx oddsrail
Cualquier agente que lea skillsnpx skills add hmesutozsoy/oddsrail
CursorInstalar oddsrail en Cursor
VS CodeInstalar oddsrail en VS Code
Cualquier otra cosa que hable MCP sobre stdio{"command": "uvx", "args": ["oddsrail"]} (o pip install oddsrail y ejecuta oddsrail)

El plugin y los enlaces de un clic lanzan el servidor con uvx, por lo que necesitan uv en la máquina. Sin uv, pip install oddsrail gives you an oddsrail comando para apuntar cualquier cliente. Todo comienza en dry-run.

Las cuatro skills (skills/*/SKILL.md) se generan desde los propios prompts MCP del servidor mediante scripts/gen_skills.py, y una prueba falla si se desvían, por lo que una skill y el prompt que refleja nunca pueden discrepar.

Alojado: nada que instalar

mcp.oddsrail.app ejecuta el mismo servidor como un endpoint MCP remoto con cuentas, para que un agente dentro de Claude pueda usarlo sin una máquina propia. Añade la URL como conector personalizado (planes Pro, Max, Team y Enterprise), inicia sesión con tu correo cuando Claude lo pida, y cada llamada a partir de entonces llevará tu cuenta.

Lo que es el servidor alojado, en una frase: datos de mercado de Polymarket, las herramientas de señales, check_order, y paper trading con un bankroll virtual de $1,000 por cuenta, con fills contra el libro en vivo. Lo que no es: un lugar donde se mueve dinero. No tiene claves de wallet, no ejecuta ninguna orden real y no sirve herramientas de Kalshi (el Acuerdo de Desarrollador de la API de Kalshi limita el uso de la API al trading propio de un miembro, por lo que un servicio compartido no puede enrutarlo). Herramientas con alcance de cuenta como open_orders y las herramientas del relayer sin gas están ausentes, porque en un servidor compartido describirían la cuenta de nadie. Quedan veinticuatro herramientas: las de datos públicos y paper, más arena_register, arena_unregister y arena_status, que colocan el libro mayor de paper de la cuenta en el tablero público.

El trading en vivo sigue siendo autoalojado: pip install oddsrail con tu propia clave, y el mismo place_order publica órdenes reales cuando configuras ODDSRAIL_DRY_RUN=0. El libro mayor de paper que acumulas en Claude es tuyo para reiniciarlo con paper_reset; nada más sobre la cuenta existe. Política de privacidad: oddsrail.app/privacy. Código fuente: oddsrail/cloud/ y oddsrail/hosted.py; notas de despliegue en deploy/cloud/.

Página de builder y arena

oddsrail.app/build es un conjunto de interruptores: estrategias (fade de overshoots, comprar resoluciones casi seguras, operar tu propia probabilidad, seguir el movimiento, cotizaciones de dos lados), reglas de riesgo (stop loss como regla de revisión, take profit, límite de pérdida diaria, nunca añadir a perdedores, límites de exposición) e higiene de mercado (riesgo de disputa, calidad de fill, observar el libro). Pulsa Ejecutar y los interruptores se ejecutan en el servidor alojado como una pasada de paper determinista (oddsrail/cloud/runner.py): el universo se escanea, la señal de cada estrategia se calcula con el mismo código que usan las herramientas MCP, cada orden pasa por check_order, los fills provienen del libro en vivo hacia un libro mayor de paper que pertenece a tu navegador, y la pasada regresa como una lista de decisiones con veredictos y razones. Sin cuenta, sin instalación, sin clave, sin modelo. Una pasada es un tick en el libro actual, no un backtest: el libro mayor lleva posiciones y cotizaciones en reposo entre pasadas, y nada se observa en el medio, por lo que un historial necesita muchas pasadas. Los mismos interruptores también se componen en un prompt para ejecutar las piezas dentro de tu propio Claude con el conector; la pieza de cotizaciones de dos lados lleva la advertencia del propio mantenedor sobre el markout en cualquier dirección.

oddsrail.app/arena es el tablero público. División de paper: cuentas alojadas que se registraron con arena_register, clasificadas por retorno sobre el bankroll virtual, servidas como JSON desde mcp.oddsrail.app/arena/paper.json. División en vivo: wallets cuyos fills de Polymarket llevan el código de builder de oddsrail, clasificados por volumen atribuido desde el feed público, con P&L realizado y abierto desde la API de datos de Polymarket; regístrate mediante pull request o el formulario en la página (site/arena/agents.json). Sin premios aún; las reglas están en la página.

Ve los footguns tú mismo, sin claves

pip install oddsrail && python examples/footguns.py

Seis cosas que las APIs de las venues hacen mal, mostradas en vivo contra los endpoints públicos: el libro de órdenes de peor a mejor, las escaleras de cadenas de dólares solo de ofertas de Kalshi, los geoblocks que parecen saludables hasta la orden, el veredicto de geoblock consultivo, el endpoint Gamma obsoleto y el emparejamiento ingenuo entre venues. Cada sección imprime la trampa cruda, luego la llamada de oddsrail que devuelve la respuesta correcta. Unos diez segundos, solo lectura.

Cómo funciona la atribución (CLOB V2, verificado agosto de 2026)

  1. Obtén tu código de builder (un bytes32) en polymarket.com → Configuración → Builders. Configura tus tasas de comisión allí: taker hasta 100 bps, maker hasta 50 bps, aditivas sobre las comisiones de la plataforma, liquidadas a tu wallet de builder.
  2. export ODDSRAIL_BUILDER_CODE=0x... donde se ejecuta el servidor.
  3. Cada orden que cualquier agente enruta a través de place_order tiene el código colocado en el campo builder de la estructura de orden V2 antes de firmar, por lo que la atribución está on-chain, visible en cada evento OrderFilled en CTF Exchange V2.
  4. Verifica con la herramienta builder_stats (endpoint público de builder-trades + leaderboard).

Si omites esto, las órdenes llevan el código de builder incluido de oddsrail (0xa576c5ce…, registrado a 0 bps maker / 0 bps taker), sin costarte nada y financiando el proyecto. Si configuras el tuyo, el tuyo gana; el predeterminado es un predeterminado, no un bloqueo.

El perfil de builder de oddsrail está Verificado en el programa de builders de Polymarket (2026-09-02), y el equipo de builders de Polymarket confirmó la atribución de código de builder como el patrón correcto para una herramienta autoalojada y no custodial: no se envían claves con el producto, y el código se adjunta y firma con la propia wallet del operador.

Variables de entorno

VariableValor por defectoSignificado
ODDSRAIL_DRY_RUN11 = las órdenes se simulan y se devuelven, nunca se envían. Establece 0 para operar.
ODDSRAIL_BUILDER_CODEvalor por defecto del proyectoTu código de builder en bytes32. Anula el valor por defecto incluido del proyecto para que la atribución (y cualquier parte del fondo de recompensas) se acredite a ti en su lugar.
POLYMARKET_PRIVATE_KEYsin establecerClave de la wallet del operador; solo se requiere para operar en vivo. Nunca sale de esta máquina.
POLYMARKET_WALLET_ADDRESSsin establecerDirección de la wallet proxy/depósito, si la cuenta usa una.
POLYMARKET_RELAYER_API_KEYsin establecerTu propia clave de API del Relayer (polymarket.com → Configuración → Claves de API del Relayer), para split_position / merge_positions / redeem_positions sin gas.
POLYMARKET_RELAYER_API_KEY_ADDRESSsin establecerLa dirección para la que se emitió la clave del relayer. Ambas partes son necesarias; sin ellas, las herramientas sin gas no envían nada.
ODDSRAIL_MAX_ORDER_NOTIONALsin establecerSalvaguarda: nocional máximo en USDC por orden. Se aplica antes de cualquier solicitud, también en modo simulado.
ODDSRAIL_MAX_SESSION_NOTIONALsin establecerSalvaguarda: nocional acumulado máximo de órdenes activas enviadas por este proceso del servidor.
ODDSRAIL_MAX_OPEN_ORDERSsin establecerSalvaguarda: máximo de órdenes en reposo en la cuenta (activas; se verifica contra el venue antes de colocar).
ODDSRAIL_ALLOWED_MARKETSsin establecerSalvaguarda: lista separada por comas de ids de token de Polymarket y/o tickers de Kalshi que el agente puede operar. Cualquier otra cosa es rechazada.
ODDSRAIL_PAPER1Simula órdenes de Polymarket en papel contra el libro en vivo. 0 lo desactiva.
ODDSRAIL_PAPER_LEDGER~/.oddsrail/paper.jsonDónde vive el libro de papel. Un archivo JSON local.
ODDSRAIL_PAPER_BANKROLL1000Efectivo inicial en papel en USDC.

Estado

Pruebas fuera de línea: 143 pruebas que cubren las rutas donde un error cuesta dinero: la traducción sí/no→bid/ask de Kalshi, el dimensionamiento de Kelly, el recorrido del libro, el emparejamiento entre venues, los casos límite de señales, la red de seguridad del modo simulado y el manejo de fallos por jurisdicción (un bloqueo geográfico nunca debe leerse como un resultado de búsqueda vacío o una orden en reposo), además del servidor alojado de extremo a extremo (registro dinámico de clientes, PKCE, inicio de sesión con magic-link, rotación de tokens, un libro de papel por cuenta) contra un proceso local real. No necesitan claves ni red:

pip install -e ".[dev]" && pytest

CI las ejecuta en Python 3.11, 3.12 y 3.13 en cada push y pull request.

Venues en vivo: cada herramienta de lectura y ambas rutas de órdenes simuladas se han probado de extremo a extremo contra Polymarket y Kalshi reales a través de una sesión real de cliente MCP. Se han colocado y confirmado en cadena dos órdenes de Polymarket atribuidas (una compra y una venta).

Aún no probado en vivo: la ruta de colocación de órdenes de Kalshi. Su forma de solicitud está probada por unidades y su endpoint verificado, pero no se ha enviado ninguna orden a una cuenta real de Kalshi, porque el autor aún no tiene una financiada y verificada. Esto no está probado, no es imposible de probar. Trata kalshi_place_order como no comprobado y comienza en modo simulado.

Dónde funciona esto

Dos cosas diferentes pueden impedir que oddsrail opere, y tienen remedios opuestos. Una es una restricción del venue, aplicada en la orden. La otra es un filtro de red, que rompe la conexión en sí.

Restricciones de Polymarket. Polymarket publica su lista de jurisdicciones restringidas como referencia de API: https://docs.polymarket.com/api-reference/geoblock. Hay tres niveles. Las jurisdicciones sancionadas por OFAC (Irán, Siria, Cuba, Corea del Norte y las regiones de Crimea, Donetsk y Luhansk de Ucrania) están bloqueadas tanto en el frontend como en la API, sin nuevas órdenes y sin cierre de posiciones existentes. Un segundo nivel más largo es solo cierre tanto en el frontend como en la API: las posiciones existentes pueden cerrarse, las nuevas no pueden abrirse. Incluye Estados Unidos, Reino Unido, Francia, Alemania, Italia, Polonia, Eslovaquia, Bélgica, Singapur, Australia, Nueva Zelanda, Brasil, Rusia, Taiwán, Tailandia y las provincias canadienses de Ontario, Quebec, Columbia Británica y Alberta. Un tercer grupo, Irlanda, Japón, Malta (solo deportes) y los Países Bajos, es de solo cierre en el frontend de Polymarket, con la API explícitamente no restringida.

Observa la forma de ese fallo: recae en la orden, no en la conexión. Las lecturas públicas responden con normalidad, por lo que oddsrail parecerá estar funcionando hasta que una orden sea rechazada. Verificado contra la documentación de Polymarket el 2026-08-31; Polymarket actualiza la lista sin previo aviso, así que lee la URL en lugar de este párrafo.

Restricciones de Kalshi. Kalshi es un único mercado de contratos designado por la CFTC y admite miembros fuera de los Estados Unidos, pero su Acuerdo de Miembro §VI nombra una larga lista de Jurisdicciones Restringidas cuyos miembros no pueden operar Contratos de Eventos, entre ellas Australia, Bélgica, Canadá, Francia, Irlanda, Italia, Nueva Zelanda, Polonia, Portugal, Singapur, Suiza, el Reino Unido, Hungría, India, los Emiratos Árabes Unidos y China continental. La lista se publica en el Aviso de Intercambio de Kalshi del 22 de junio de 2026 (https://kalshi-public-docs.s3.amazonaws.com/regulatory/notices/Kalshi%20Exchange%20Notice%20(Updated%20Member%20Agreement)%20(22%20June%202026).pdf), y Kalshi se reserva el derecho de cambiarla. La misma sección es explícita en que la restricción se aplica solo a operar Contratos de Eventos y no impide por sí misma la membresía o el acceso no comercial, por lo que las herramientas de lectura de Kalshi de oddsrail siguen siendo utilizables incluso donde sus herramientas de órdenes no lo son.

Las dos listas se superponen en gran medida. Kalshi no es un respaldo general para un operador restringido por Polymarket, y la diferencia va en ambas direcciones. Entre las jurisdicciones que polymarket.com lista como de solo cierre, Alemania, Brasil, Eslovaquia y Estados Unidos no están en la lista restringida de Kalshi; Japón y los Países Bajos no están restringidos por ninguna API (solo por el frontend de Polymarket). Verifica ambas listas para tu propia jurisdicción en lugar de asumir que el otro venue está abierto. El caso de EE. UU. tiene su propia peculiaridad.

Estados Unidos. polymarket.com, el venue con el que habla oddsrail, es de solo cierre para EE. UU. Polymarket opera por separado Polymarket US (polymarket.us), gestionado por QCX LLC como un Mercado de Contratos Designado regulado por la CFTC. oddsrail no lo soporta. Es un host de API diferente, un modelo de autenticación diferente (encabezados de clave API en lugar de firmas de wallet EIP-712), un SDK diferente y un rail de financiación diferente. Una cuenta de polymarket.us y sus claves no funcionarán con este servidor. Kalshi no lista a EE. UU. como restringido, por lo que para un operador de EE. UU., Kalshi es el venue al que oddsrail puede llegar realmente, sin atribución de código de builder, ya que la API REST de Kalshi no tiene ese campo.

Filtros de red. Independientemente de cualquier regla del venue, un filtro nacional puede bloquear los dominios por completo. Turquía hace esto: Polymarket no restringe Turquía, y Turquía no está en la lista de Kalshi tampoco, pero los ISP turcos bloquean polymarket.com. Eso es un problema de conectividad, no de elegibilidad, y se ve diferente: fallos de DNS, errores TLS, reinicios o una página intersticial del ISP servida donde se esperaba JSON. oddsrail clasifica ambas formas y le dice al agente llamante cuál encontró.

La elegibilidad es del operador, no de la herramienta. oddsrail es autoalojado y no custodial, lo cual es una ventaja real y también significa que tienes la cuenta y haces las declaraciones del venue; no hay intermediario que las haga por ti. El flujo de operaciones de Polymarket requiere una atestación de que no eres una persona estadounidense, no estás ubicado en una jurisdicción restringida y no estás "usando una VPN u otras medidas para eludir o intentar eludir" restricciones, y establece que Polymarket se reserva el derecho de poner una wallet no conforme en modo de solo cierre. La §VI de Kalshi es una declaración sobre dónde estás domiciliado, organizado y ubicado, rehecha cada vez que colocas una orden. server_info informa el veredicto de bloqueo geográfico de Polymarket para la IP de esta máquina, pero una sonda técnica no es una verificación de cumplimiento: los términos se aplican a la residencia, ciudadanía e incorporación, no a la IP de salida. Lee los términos; si algo de esto te importa, obtén tu propio asesoramiento legal. Nada aquí es asesoramiento legal.

La lógica de señales, la capa MCP y toda la suite de pruebas funcionan bien fuera de línea independientemente.

Salvaguardas: límites con los que el agente no puede discutir

Cualquiera que entregue claves a un agente quiere tres cosas primero: un tope en una orden, un tope en una sesión y una valla alrededor de qué mercados puede tocar. Las tres son variables de entorno establecidas por el operador (tabla anterior), aplicadas antes de que salga cualquier solicitud, tanto en modo simulado como en vivo, para que el agente encuentre la valla en el ensayo. Una negativa es una respuesta estructurada que nombra la regla, el límite y la solicitud:

{"accepted": false, "blocked_by": "guardrail", "rule": "max_order_notional",
 "limit": 25.0, "requested": 99.5, "note": "refused by an operator-set guardrail ... Nothing was sent."}

El contador de sesión vive en el proceso del servidor; reiniciarlo restablece el presupuesto, lo cual es decisión del operador. server_info informa los límites activos y cuánto del presupuesto de sesión se ha utilizado.

Operación en papel: simulación con memoria

Por defecto, cada orden simulada de Polymarket se ejecuta contra el libro de órdenes en vivo, recorrido dentro del precio límite; lo que no se ejecuta queda como una orden en papel y se ejecuta más tarde si el mercado la cruza. paper_positions informa efectivo, posiciones a marcas actuales, P&L realizado y no realizado y las órdenes en papel en reposo; paper_reset comienza de nuevo. El libro es un archivo JSON local. Sé claro sobre lo que esto es: las ejecuciones asumen sin posición en cola, sin latencia, sin impacto en el mercado y sin comisiones, por lo que los resultados en papel son un límite superior de la misma estrategia en vivo. Las órdenes simuladas de Kalshi aún devuelven solo la intención.

Tiempo real: observa cómo se mueve el libro

watch_book(token_id, seconds, max_events) se suscribe a la transmisión en tiempo real de un token y devuelve los eventos que llegaron (instantánea del libro, luego cambios de precio y operaciones), limitado a un máximo de 60 segundos para que un agente no pueda colgar una sesión en un mercado tranquilo. Úsalo después de get_orderbook cuando la decisión dependa de que el libro se mueva, no solo de dónde está.

Si la transmisión falla con CERTIFICATE_VERIFY_FAILED mientras las herramientas REST funcionan, tu Python no tiene un paquete de CA (común con instalaciones de macOS de python.org). oddsrail clasifica eso como local_tls y le dice al agente la solución: ejecuta Install Certificates.command desde la carpeta de Python en /Applications, o establece SSL_CERT_FILE a la ruta impresa por python -m certifi.

Gestión de posiciones sin gas (relayer)

Tres herramientas mueven garantías sin pagar gas, a través del relayer de Polymarket: split_position (USDC → un conjunto completo de SÍ+NO), merge_positions (SÍ+NO coincidentes → USDC, o max), y redeem_positions (las acciones ganadoras de un mercado resuelto → USDC). Las tres respetan el modo simulado y devuelven el id de transacción del relayer y el hash más el resultado final.

Usan tu propia clave de API del Relayer, creada en polymarket.com → Configuración → Claves de API del Relayer y exportada como POLYMARKET_RELAYER_API_KEY + POLYMARKET_RELAYER_API_KEY_ADDRESS. Ese es el patrón que el equipo de builders de Polymarket recomienda para una herramienta autoalojada: ningún secreto de builder se envía con oddsrail, y cada operador autentica el relayer como sí mismo. Los límites del relayer son por nivel de builder: 100 solicitudes/día sin verificar, 10,000 verificadas. Sin la clave, las herramientas devuelven una respuesta estructurada de "no configurado" y no envían nada; nunca recurren a una transmisión que paga gas desde el firmante.

Probado en vivo (2026-09-02): una división de 1 USDC y la fusión coincidente pasaron por el relayer desde este código, sin gas, en la cuenta de prueba del mantenedor con su propia clave de API del Relayer. Los ids del relayer y los hashes de transacción de Polygon están en docs/live-proof.md. redeem_positions aún está sin probar en vivo: necesita un mercado resuelto con acciones ganadoras, que esa cuenta aún no ha tenido. redeemable_positions lista lo que la wallet configurada podría canjear o fusionar ahora mismo, y el prompt settle_resolved encadena los dos.

Kalshi (venue #2)

Kalshi es trae tu propia clave y de un solo inquilino por diseño: el operador suministra su propia clave de API, opera su propia cuenta, y este servidor no almacena nada en caché. Eso es deliberado: el Acuerdo de Desarrollador de Kalshi limita el uso de la API a las operaciones propias de un miembro (§3), prohíbe facilitar las operaciones de otros miembros (§3.2) y la sublicencia de la API (§3.7), y restringe el almacenamiento/compartición de datos de la API (§3.1). Un servicio de Kalshi alojado y multiinquilino no sería conforme; uno autoalojado sí lo es. Aquí no existe la atribución. Los Códigos de Builder de Kalshi son una integración de Solana/DFlow/Jupiter; no hay ningún campo de builder o afiliado en la API REST, por lo que el flujo de órdenes de Kalshi no puede ser atribuido o monetizado como el de Polymarket. Kalshi está en oddsrail por cobertura y alcance de señal, no por ingresos de enrutamiento.

Dos formas en esta API son fáciles de equivocar, por lo que oddsrail normaliza ambas:

  • Los precios son cadenas de dólares, no centavos ("0.5600"), los tamaños son cadenas de punto fijo ("10.00"); los campos heredados de centavos enteros fueron eliminados en marzo de 2026. Toda la aritmética usa Decimal.
  • El libro de órdenes es solo de ofertas en ambos lados. yes_dollars y no_dollars son ambos escaleras de ofertas, ascendentes, por lo que la mejor oferta es el último elemento, y una oferta de NO a $0.99 es una demanda de SÍ a $0.01. kalshi_get_orderbook devuelve una vista convencional de oferta/demanda mejor-primero del libro de SÍ más las escaleras crudas.

La colocación de órdenes habla en términos naturales, outcome (sí/no), action (comprar/vender), price = probabilidad de ese resultado, y se traduce al libro de SÍ de Kalshi bid/ask internamente (comprar NO @ 0.25 se convierte en demanda @ 0.75). Esa traducción está exhaustivamente probada por unidades (tests/test_money_paths.py), ya que es el lugar obvio para enviar un error de posición invertida.

Credenciales: KALSHI_KEY_ID más KALSHI_PRIVATE_KEY_PATH (PKCS#8 PEM) o KALSHI_PRIVATE_KEY. Establezca KALSHI_DEMO=1 para acceder al entorno de demostración. Las herramientas de lectura no necesitan ninguna clave.

Herramientas entre venues

  • find_markets(query): busca en Polymarket y Kalshi en una sola llamada y devuelve una forma normalizada por mercado: venue, market_id (el id que toma la herramienta de órdenes de ese venue), title, precio de sí/no como probabilidades en (0,1), mejor oferta/demanda, spread, volumen de 24h, hora de cierre y trade_with nombrando la herramienta a llamar. Úselo cuando no sepa ya el venue.
  • quote_cost(venue, market_id, side, size): lo que un tamaño realmente costaría, recorriendo el libro en lugar de leer el nivel superior. Devuelve precio de llenado promedio, deslizamiento vs. mejor, nocional, niveles consumidos y si el tamaño es llenable en absoluto, más el programa de tarifas por mercado de Polymarket donde publique uno. Kalshi no publica tarifas en su carga de mercado, por lo que se reportan como desconocidas en lugar de estimadas.
  • compare_venues(query): listados candidatos del mismo evento entre venues. No es un escáner de arbitraje. Emparejar un evento entre venues es un problema de resolución de entidades no resuelto: la superposición ingenua de títulos empareja alegremente una elección brasileña con una ucraniana y reporta una "brecha" de 70 puntos que es ficción. Se aplican dos puertas (similitud de título ≥ 0.5 y fechas de cierre dentro de una semana), por lo que generalmente no devuelve nada, que es la respuesta honesta. Una diferencia de precio entre candidatos se reporta como yes_price_difference, nunca como ganancia.

Búsqueda de Kalshi

Kalshi no tiene un endpoint de búsqueda de texto. oddsrail busca por evento (el índice legible por humanos, con with_nested_markets) en lugar de paginar decenas de miles de mercados con nombres de máquina, y coincide en límites de palabras; sin eso, "fed" coincide con "Bundestag alemán" y una consulta de tasa de la Fed devuelve mercados de elecciones alemanas. Los resultados llevan truncated, porque un escaneo limitado significa que un resultado vacío no es prueba de que un mercado no exista.

Ciclo de vida de órdenes y descubrimiento

  • order_status(order_id): en reposo / parcialmente_llenado / llenado / desaparecido, con tamaño_coincidido. La respuesta que un agente necesita después de place_order.
  • my_fills(), my_positions(): las ejecuciones y tenencias del operador, sin manipulación de direcciones. (Los llenados provienen del feed de actividad de la API de Datos; el list_account_trades del SDK devuelve la cinta pública del mercado y no se usa.)
  • cancel_all_orders(): interruptor de apagado, aplana todas las órdenes en reposo a la vez.
  • resolution_criteria(venue, market_id) devuelve el contrato de resolución completo: qué resuelve SÍ, quién lo resuelve, de qué fuentes. Léalo antes de confiar en un precio.
  • closing_soon(hours): mercados que cierran dentro de N horas en cualquiera de los venues, donde se concentra la actividad.

Prompts de flujo de trabajo

Los prompts de MCP aparecen en los clientes como flujos de trabajo listos, y codifican el orden de operaciones que mantiene a un agente fuera de problemas; la secuenciación es la experiencia, que una lista plana de herramientas no puede transmitir.

  • /find_fade_setup(query, bankroll): señal → libro → costo → resolución → tamaño → prueba en seco, con los criterios de rechazo en cada paso
  • /check_cross_venue_edge(query): candidatos → auditoría de liquidación → costo en ambas piernas, y dice claramente cuando la respuesta es "sin ventaja"
  • /daily_review: posiciones, órdenes en reposo, llenados, cierre-pronto, atribución

Riesgo y liquidación

  • settlement_audit(polymarket_id, kalshi_ticker): la verificación que decide si una diferencia de precio entre venues es una ventaja o un desajuste. Compara tiempos de cierre, fuentes de resolución, estado de disputa de UMA y estructura de mercado en datos en vivo sin lista de pares pre-curada, devolviendo ok / caution / block con razones, y listando las verificaciones que no realizó.
  • check_order(venue, market_id, side, price, size, intent): el último paso antes de place_order. Verificaciones deterministas de la orden propuesta contra las propias palabras del operador y el mercado en vivo: ¿existe el mercado y acepta órdenes, coinciden las palabras de la intención con el mercado y el lado SÍ/NO, es el precio razonable contra el libro, es el tamaño superior al mínimo de $1 de Polymarket y dentro de las salvaguardas, hay liquidez dentro del límite, se nombra una fuente de resolución? Devuelve ok / caution / block con la evidencia por verificación y una lectura de una línea. Ningún segundo modelo juzga nada; nada se envía.
  • position_size(bankroll_usd, price, fair_value): tamaño fraccional-Kelly, con tope, rechazando apuestas de ventaja negativa, devolviendo sus propios supuestos.

Herramientas (41)

  • search_markets, get_market, get_orderbook, price_history, get_positions: solo lectura, sin claves
  • overshoot_signal, premium: detección fresca de salto de pánico + tendencia de reversión histórica de este mercado (portado del analizador polymarket-wc)
  • dispute_risk, premium: heurística transparente de 0–100 para resoluciones disputadas (propensas a UMA)
  • place_order, cancel_order, open_orders: trading, prueba en seco por defecto. price es una probabilidad en (0,1), size está en SHARES, y el intercambio aplica un mínimo nocional de $1 en órdenes comercializables. Las herramientas de trading llevan anotaciones destructiveHint para que los clientes puedan restringirlas.
  • builder_stats: verificación de atribución + tabla de clasificación pública de builders
  • find_markets, compare_venues, quote_cost: entre venues (arriba)
  • server_info: estado de configuración, por venue

Kalshi: kalshi_search_markets, kalshi_get_market, kalshi_get_orderbook, kalshi_get_trades, kalshi_balance, kalshi_positions, kalshi_open_orders, kalshi_place_order, kalshi_cancel_order.

Notas de pila

  • SDK unificado oficial polymarket-client (0.6.x): AsyncPublicClient para datos, AsyncSecureClient.place_limit_order(..., builder_code=...) para órdenes atribuidas. El py-clob-client heredado está archivado y no puede adjuntar códigos de builder. No lo use.
  • MCP SDK 2.0: MCPServer de mcp.server.mcpserver (la importación antigua mcp.server.fastmcp.FastMCP desapareció en 2.x).
  • Kalshi está en httpx + cryptography simple, no el SDK oficial: kalshi-python-sync requiere Python >=3.13 y se re-lanza semanalmente en sincronía con la versión de la especificación. La autenticación es RSA-PSS(SHA256, salt=longitud de digestión) sobre str(unix_ms) + METHOD + path, donde la ruta incluye /trade-api/v2 y excluye la cadena de consulta. La URL base ahora es external-api.kalshi.com.
  • x402 (planeado): el paquete oficial de PyPI x402 (v2.20+) puede envolver herramientas MCP directamente (x402.mcp, el pago viaja en la llamada de herramienta _meta), pero sus ayudantes MCP actualmente apuntan a mcp 1.x, por lo que integrar significa fijar mcp>=1.28,<2 o esperar la versión compatible con 2.x. La liquidación en mainnet necesita un facilitador (Coinbase CDP: 1,000 liquidaciones gratuitas/mes, luego $0.001). Mantenga los niveles gratuitos de ambas señales para que los registros puedan indexar el servidor.

Para quién es esto

La tabla de clasificación pública de builders de Polymarket muestra lo que vale un solo operador enrutando su propio flujo. Extraído 2026-08-31 a través de la propia herramienta builder_stats de este servidor. Vuelva a ejecutarlo, los números se mueven:

volumen semanal
#1 (traderline)$7.70M
mediana del top 25$533K
entrada al top 25$140K

Las filas instructivas son las pequeñas: MagicMarkets enruta $901K/semana con un solo usuario activo; Jupiter $515K con uno; Sharkbetting $1.15M con dos. Esos son operadores de bots enrutando su propio flujo, que es exactamente para quien está construido esto.

Hoja de ruta

  1. Prueba de humo en vivo desde una red desbloqueada: hecho 2026-08-23, todas las herramientas pasan
  2. Registrar código de builder (polymarket.com → Configuración → Builders), establecer tarifas a 0 bps en el lanzamiento, exportar ODDSRAIL_BUILDER_CODE; primera orden atribuida en un tamaño pequeño
  3. Kalshi como venue #2: hecho 2026-08-23, 9 herramientas, verificado en vivo
  4. Envoltura paga x402 para las dos señales una vez que el conflicto mcp-2.x se resuelva
  5. Listados de registros: registro oficial de MCP (mcp-publisher, marcador de PyPI mcp-name:), Smithery (necesita streamable-HTTP público + una herramienta gratuita para su escáner), Glama (glama.json)

Listado / distribución

  • GitHub: https://github.com/hmesutozsoy/oddsrail (público, MIT)
  • Glama: rastrea GitHub automáticamente; glama.json en la raíz del repositorio reclama el mantenimiento.
  • PyPI: https://pypi.org/project/oddsrail/ (pip install oddsrail)
  • Registro oficial de MCP: listado como app.oddsrail/polymarket-kalshi-trading (renombrado de …-arbitrage en 0.10.1; el nombre antiguo está obsoleto) (publicado 2026-08-30, estado activo). Re-publique después de un aumento de versión con mcp-publisher publish; mantenga la versión de server.json en sincronía con pyproject.toml o el registro lo rechazará.
  • Smithery: requiere un endpoint streamable-HTTP HTTPS público, disponible una vez que oddsrail esté alojado en lugar de ejecutarse localmente sobre stdio.