Skip to main content
Glama
FrankoCamposT800

mcp-asdeporte

mcp-asdeporte

MCP server NestJS (@rekog/mcp-nest) que expone tools de solo lectura sobre ms-event-v2 y ms-inscription-v2.

Stack

  • NestJS 10 + @rekog/mcp-nest (Streamable HTTP en /mcp)

  • Hexagonal: src/<module>/{domain,application,infrastructure,controllers}

  • Auth chatbot → MCP: header x-api-key = MCP_INBOUND_APIKEY

  • Auth MCP → micros: header x-api-key = MCP_APIKEY

  • Observabilidad: nestjs-pino, x-correlation-id

  • Rate limit: @nestjs/throttler (default 60 req / 60s)

Related MCP server: eventos MCP Server

Setup

cp .env.example .env
# Completar EVENT_BASE_URL, INSCRIPTION_BASE_URL, MCP_APIKEY, MCP_INBOUND_APIKEY, CURSOR_API_KEY

npm install
npm run start:dev

Endpoint MCP: POST http://localhost:3100/mcp

Chat (Olimpia)

Asistente HTTP que usa Cursor SDK + tools MCP (solo lectura). Mismo proceso que /mcp.

Endpoint

Respuesta

POST /chat/ask

JSON { answer, runId, agentId }

POST /chat/ask/stream

SSE: token | done | error

Auth: header x-api-key = MCP_INBOUND_APIKEY
Body: { "question": string, "userid": uuid }
Env: CURSOR_API_KEY (obligatorio), CURSOR_MODEL, MCP_PUBLIC_URL, CHAT_TIMEOUT_MS (default 120s)
Node: ≥ 22.13 (@cursor/sdk)
Rate limit: mismo throttler global (60 / 60s)

# Sync
curl -s -X POST http://localhost:3100/chat/ask \
  -H "x-api-key: $MCP_INBOUND_APIKEY" \
  -H 'Content-Type: application/json' \
  -H 'x-correlation-id: demo-1' \
  -d '{"question":"¿Cuántos inscritos hay en Minions 2026?","userid":"62167a2d-d0eb-4f3e-a3ca-42cc4144465b"}'

# Stream (SSE)
curl -N -X POST http://localhost:3100/chat/ask/stream \
  -H "x-api-key: $MCP_INBOUND_APIKEY" \
  -H 'Content-Type: application/json' \
  -d '{"question":"¿Cuántos inscritos hay en Minions 2026?","userid":"62167a2d-d0eb-4f3e-a3ca-42cc4144465b"}'

SSE done.data es JSON stringificado con { answer, runId, agentId }. Si el client corta la conexión, el run se cancela.

Probar con MCP Inspector

Requiere Node.js ≥ 22.7.5 (requisito del Inspector). El MCP debe estar corriendo (npm run start:dev).

UI (recomendado)

npm run inspector

Abre http://localhost:6274. En la UI:

  1. Transport: Streamable HTTP

  2. URL: http://localhost:3100/mcp (preconfigurado vía inspector/mcp.json)

  3. Auth: header name x-api-key, value = tu MCP_INBOUND_APIKEY del .env

  4. Connect → Tools → List Tools / Call Tool

CLI (smoke)

# Lista tools (usa MCP_INBOUND_APIKEY del .env)
npm run inspector:list

# Health check
npm run inspector:ping

# Cualquier tool
node scripts/inspector-cli.mjs tools/call event_get --tool-arg id=<uuid>

Tools

Catálogo de solo lectura. El chatbot (o Inspector) elige la tool y manda los args; no hay mutaciones.

Tool

Para qué

mcp_ping

¿El MCP está vivo?

event_search

Buscar eventos por texto / filtros (Typesense)

event_get

Detalle de un evento (UUID o uri)

event_list

Listado paginado de eventos (GraphQL)

event_distances

Distancias / modalidades de un evento

event_convocatories

Secciones de convocatoria

inscription_get

Detalle de una inscripción (UUID o slug)

inscriptions_by_event

Inscritos de un evento (filtros + paginación)

inscriptions_by_user

Inscripciones de un usuario

inscription_search

Buscar inscritos en un evento por texto libre

is_inscribed

¿Usuario X está inscrito en evento Y?

inscription_totals

Conteo de inscritos por eventid(s)

user_next_competitions

Próximas competencias de un usuario

user_sport_types

Deportes / tipos de evento del usuario

inscription_recovery

Recuperar inscripción por nombre + fecha + evento

cart_get

Detalle de un carrito (lean, sin secretos de pago)

carts_by_user

Historial de carritos de un usuario

Flujo típico (chatbot)

  1. Buscar evento → event_search / event_list

  2. Detalle / distancias / convocatoria → event_get, event_distances, event_convocatories

  3. Totales o listado de inscritos → inscription_totals, inscriptions_by_event / inscription_search

  4. Persona concreta → inscription_get (slug o UUID) o is_inscribed / inscriptions_by_user

  5. Usuario autenticado → user_next_competitions, user_sport_types; recuperación → inscription_recovery

  6. Carrito / compra → cart_get, carts_by_user


mcp_ping

Sin parámetros. Responde { status: "ok", service: "mcp-asdeporte" }.

Preguntas: ¿Está arriba el MCP? / health check.

npm run inspector:ping

Búsqueda full-text Typesense. Respuesta lean: found, page, hits[] (nombre, uri, fechas, precios flags, etc.).

Arg

Req

Notas

q

sí

Texto. Usa * si solo filtras

filter_by

no

Ej. inscription_allow:true && city:CDMX

sort_by

no

Ej. epoch_date:desc

query_by

no

Campos a buscar

page / per_page

no

Paginación (default 20, max 250)

Preguntas ejemplo:

  • ¿Hay eventos de Minions / maratón / ciclismo?

  • Eventos en CDMX con inscripción abierta

  • Próximas carreras ordenadas por fecha

node scripts/inspector-cli.mjs tools/call event_search --tool-arg 'q=minions' --tool-arg per_page=5
node scripts/inspector-cli.mjs tools/call event_search --tool-arg 'q=*' --tool-arg 'filter_by=inscription_allow:true'

event_get

Detalle de un evento por UUID o uri.

Arg

Req

id

sí — UUID o uri

Devuelve (lean): nombre, uri, dirección, fechas, precios, currency, sports, inscription_allow, published, short_description, organizationid…

Preguntas ejemplo:

  • Dame el detalle del evento Minions

  • ¿Cuánto cuesta / está publicada la inscripción?

  • ¿Cuál es la uri / fechas del evento X?

node scripts/inspector-cli.mjs tools/call event_get --tool-arg id=minions-run-cdmx-2026-2rv
node scripts/inspector-cli.mjs tools/call event_get --tool-arg id=<uuid>

event_list

Listado GraphQL paginado (alternativa más “admin” a Typesense).

Arg

Req

keyword

no

organizationid

no — UUID org

page / perpage

no

Preguntas ejemplo:

  • Lista eventos de la organización X

  • Busca por keyword “étape”


event_distances

Modalidades / distancias de un evento (stock, unidad, metros, disabled).

Arg

Req

event

sí — UUID o uri

Preguntas ejemplo:

  • ¿Qué distancias tiene Minions? (3k / 5k / 10k…)

  • ¿Queda stock en la de 10 km?

node scripts/inspector-cli.mjs tools/call event_distances --tool-arg event=<uuid-o-uri>

event_convocatories

Secciones e items de convocatoria (HTML/contenido editorial).

Arg

Req

eventOrUri

sí — UUID o uri

lang

no — ej. es, en

Preguntas ejemplo:

  • ¿Cuál es la ruta / entrega de kit / premiación?

  • Muéstrame la convocatoria en inglés

  • ¿Hay EXPO o beneficios plus?

node scripts/inspector-cli.mjs tools/call event_convocatories --tool-arg eventOrUri=<uri> --tool-arg lang=es

inscription_get

Una inscripción. Exactamente un filtro: inscriptionid (UUID) o slug (nº de compra).

Arg

Req

inscriptionid

uno de los dos

slug

uno de los dos — ej. ASDLNN2JFGZ9Q

Devuelve (lean): status, participante, email, número, montos, distanceid, categoryid, eventid, created_at…

Preguntas ejemplo:

  • Dame la inscripción con slug ASD…

  • Detalle de la inscripción <uuid>

  • ¿Está paid o pending_payment?

node scripts/inspector-cli.mjs tools/call inscription_get --tool-arg slug=ASDLNN2JFGZ9Q
node scripts/inspector-cli.mjs tools/call inscription_get --tool-arg inscriptionid=<uuid>

inscriptions_by_event

Listado paginado de inscritos de un evento.

Arg

Req

Notas

eventid

sí

UUID del evento

status

no

paid, cancelled, pending_payment, created, payment_declined

userid

no

Filtrar un usuario

filter

no

Texto: nombre, email, folio, número

page / perpage

no

Default 10

Preguntas ejemplo:

  • Lista 10 inscritos paid del Minions

  • Busca al inscrito “Servando” en el evento X

  • ¿Cuántos pending_payment hay? (ver total de la respuesta)

node scripts/inspector-cli.mjs tools/call inscriptions_by_event \
  --tool-arg eventid=<uuid> --tool-arg status=paid --tool-arg perpage=5

inscriptions_by_user

Historial de inscripciones de un usuario (el chatbot debe tener el userid).

Arg

Req

userid

sí

status

no

from / to

no — fechas ISO

eventname

no

page / perpage

no

Preguntas ejemplo:

  • ¿En qué eventos está inscrito el user Y?

  • Inscripciones pagadas de Y en 2026

  • Filtra por nombre de evento “Étape”

node scripts/inspector-cli.mjs tools/call inscriptions_by_user --tool-arg userid=<uuid> --tool-arg perpage=10

is_inscribed

¿El usuario tiene inscripción(es) en ese evento? Devuelve array (vacío = no).

Arg

Req

userid

sí

eventid

sí

Preguntas ejemplo:

  • ¿El user Y está inscrito en Minions?

  • Confirma inscripción user+evento antes de otra acción

node scripts/inspector-cli.mjs tools/call is_inscribed \
  --tool-arg userid=<uuid> --tool-arg eventid=<uuid>

inscription_totals

Totales de inscritos por uno o más eventos.

Arg

Req

eventids

sí — array de UUIDs

Preguntas ejemplo:

  • ¿Cuántos inscritos tiene Minions?

  • Compara totales de estos 3 eventos

node scripts/inspector-cli.mjs tools/call inscription_totals \
  --tool-arg 'eventids=["d09a20b1-90ee-474b-85bd-d5fac1772525"]'

Búsqueda de inscritos dentro de un evento por texto libre (nombre, email, folio, número). Preferir frente a inscriptions_by_event cuando se busca a una persona.

Arg

Req

Notas

filter

sí

Texto de búsqueda

eventid

sí

UUID del evento

page / perpage

no

Default 10

Preguntas ejemplo:

  • Busca “Servando” en el Minions

  • ¿Hay alguien con folio … en el evento X?

node scripts/inspector-cli.mjs tools/call inscription_search \
  --tool-arg filter=Servando --tool-arg eventid=<uuid>

user_next_competitions

Próximas competencias del usuario (eventos futuros con inscripción). El chatbot debe tener el userid.

Arg

Req

userid

sí

page / perpage

no

Devuelve (lean): inscriptionid, status, eventid, fecha, nombre oficial, uri, address…

Preguntas ejemplo:

  • ¿Cuáles son mis próximas carreras?

  • Próximos eventos del user Y

node scripts/inspector-cli.mjs tools/call user_next_competitions \
  --tool-arg userid=<uuid>

user_sport_types

Deportes / tipos de evento en los que el usuario se ha inscrito (con conteos).

Arg

Req

userid

sí

Devuelve: events_total + lista sports (sportid, name, total).

Preguntas ejemplo:

  • ¿En qué deportes corre el user Y?

  • Resumen de tipos de evento del usuario

node scripts/inspector-cli.mjs tools/call user_sport_types --tool-arg userid=<uuid>

inscription_recovery

Recupera una inscripción por nombre completo + fecha de nacimiento + evento. Sensible: el chatbot debe verificar identidad antes de llamar.

Arg

Req

Notas

full_name

sí

Como está registrado

birthdate

sí

ISO, ej. 1978-06-13 o datetime completo

eventid

sí

UUID del evento

Preguntas ejemplo:

  • Recupera mi inscripción al Minions: Juan Pérez, 1978-06-13

node scripts/inspector-cli.mjs tools/call inscription_recovery \
  --tool-arg full_name="Juan Perez" \
  --tool-arg birthdate=1978-06-13T12:00:00.000Z \
  --tool-arg eventid=<uuid>

cart_get

Detalle lean de un carrito: status, montos, inscripciones, federaciones, store. Sin tarjetas, SPEI, URLs de gateway ni customer ids.

Arg

Req

cartid

sí — UUID

Preguntas ejemplo:

  • ¿En qué status está el carrito X?

  • ¿Qué inscripciones trae este carrito?

node scripts/inspector-cli.mjs tools/call cart_get --tool-arg cartid=<uuid>

carts_by_user

Historial paginado de carritos de un usuario.

Arg

Req

userid

sí

page / perpage

no

Preguntas ejemplo:

  • ¿Qué carritos tiene el user Y?

  • Últimos carritos pending_payment de Y

node scripts/inspector-cli.mjs tools/call carts_by_user --tool-arg userid=<uuid>

Fuera de alcance (hoy)

No hay tools de escritura ni de: facturas, ratings, goals, transacciones, import CSV, shipping, dependientes, etc. Solo lectura event + inscription (+ cart lean) según la tabla de arriba.

Hardening

  • Upstream timeout (UPSTREAM_TIMEOUT_MS) → 504

  • Chat timeout (CHAT_TIMEOUT_MS, default 120s) → 504 / SSE error; cancela el run Cursor

  • Upstream 401/403 → 401; 5xx → 502

  • Correlation: header x-correlation-id (generado si falta; logueado en chat con agentId / runId)

  • Rate limit: @nestjs/throttler en /mcp y /chat (mismo window)

  • Chat stream: abort al req.close → run.cancel() + dispose del agent

Estructura

src/
  shared/          # config, http clients, guards, interceptors, ping
  event/           # tools event_* (hexagonal)
  inscription/     # tools inscription_* (hexagonal)
  chat/            # Olimpia: /chat/ask + /chat/ask/stream (Cursor + MCP)
inspector/         # config MCP Inspector (Streamable HTTP)
scripts/           # wrapper CLI Inspector + x-api-key

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    MCP server for eventos event management platform, enabling AI assistants to manage events and tickets via API integration. Supports authentication, ticket CRUD operations, and listing with pagination.
    1
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Read-only MCP server for the PlayMetrics youth-sports club management platform, enabling AI agents to query clubs, teams, players, schedules, registrations, and payments.
    1
    MIT
  • F
    license
    B
    quality
    B
    maintenance
    Read-only MCP server for Municipalidad de Rosario citizen queries, routing by intent to official sources and a local document index. It exposes tools for querying official documents, procedures, claims, payments, appointments, and news via MCP stdio or HTTP.
    10
    -