Skip to main content
Glama
priority-mcp

Priority REST API MCP Server

by priority-mcp

Priority REST API MCP Server

Un servidor MCP que conecta a asistentes de IA (Claude y otros) directamente con un sistema Priority ERP. Cada operación OData (consulta, creación, actualización, eliminación, operaciones por lotes, archivos adjuntos, campos de texto) se expone como una herramienta MCP, de modo que los agentes de IA pueden leer y escribir datos de negocio en vivo sin código de integración personalizado.

Versión: 0.2.0 · Transporte: Streamable HTTP (SSE opcional) · Entorno de ejecución: Node.js 18 · Herramientas: 19


Inicio rápido

1. Clona e instala

git clone https://github.com/priority-mcp/priority-odata-mcp priority-mcp
cd priority-mcp
npm install

2. Crea el .env a partir del ejemplo

cp .env.example .env

Como mínimo, establece estas cuatro variables:

PRIORITY_BASE_URL=https://<host>/odata/Priority/<tabula.ini>/<company>/
PRIORITY_AUTH_TYPE=basic
PRIORITY_USERNAME=myuser
PRIORITY_PASSWORD=mypassword

3. Inicia el servidor

# Development (from source)
node src/index.js

# Production (bundled)
npm run build
node dist/index.js

En el primer arranque, si no se define ODATA_MCP_TOKEN, se genera y se imprime en stdout un token Bearer aleatorio. Cópialo para el siguiente paso.

4. Conecta desde Claude Code

Añade esto a tu configuración de MCP:

{
  "mcpServers": {
    "priority": {
      "type": "http",
      "url": "http://localhost:3000/mcp",
      "headers": {
        "Authorization": "Bearer <ODATA_MCP_TOKEN>"
      }
    }
  }
}

Related MCP server: mcp_sdk_eyra_accelerator

Transporte

El server usa Streamable HTTP as main transport: each POST /mcp request is completely stateless. Instead of McpServer y StreamableHTTPServerTransport are created per request and torn down (destroyed) after.

Endpoint

Método

Propósito

/mcp

POST

Endpoint principal de MCP (Streamable HTTP)

/sse

GET

Flujo SSE — requiere SSE_ENABLED=true

/sse

POST

Mensajes JSON-RPC para clientes SSE

/health

GET

Comprobación de salud — devuelve la versión y el estado

/.well-known/oauth-authorization-server

GET

Descubrimiento OAuth 2.1 (requerido por Claude Code ≥2.1.92)

/authorize, /token, /register

GET/POST

Flujo PKCE de OAuth 2.1 — autoaprueba

Nota: Los endpoints OAuth 2.1 existen para satisfacer el handshake de conexión Streamable HTTP de Claude Code. Autoaprueban todas las solicitudes y no están pensados para un control de acceso real; eso lo gestiona ODATA_MCP_TOKEN.


Autenticación

La autenticación funciona en dos capas independientes.

Capa 1 — Protección de este servidor

Todas las rutas (excepto /health y los endpoints OAuth) requieren:

Authorization: Bearer <ODATA_MCP_TOKEN>

Define ODATA_MCP_TOKEN en .env. Si no se define, se genera un UUID aleatorio al inicio y se imprime en consola.

Capa 2 — Llamada a Priority ERP

Controlada por PRIORITY_AUTH_TYPE:

  • basic — Autenticación HTTP Basic con PRIORITY_USERNAME + PRIORITY_PASSWORD

  • pat — Token Bearer mediante PRIORITY_PAT

  • oauth2 — igual que pat (se pasa el PAT como token Bearer)

  • none — sin cabecera de autenticación (solo pruebas locales)

Las operaciones de escritura (POST/PATCH/DELETE) obtienen automáticamente una cabecera X-CSRF-Token y reintentan con ella si la solicitud inicial es rechazada, siguiendo la patrón de protección CSRF de Priority.

Cuando se definen PRIORITY_APP_ID y PRIORITY_APP_KEY, se envían cabeceras de licencia opcionales por aplicación con cada solicitud a Priority (X-App-Id / X-App-Key).


Configuración

Copia .env.example a .env. El servidor busca el .env en el orden: ENV_FILE_PATH./mcp-servers/Priority-REST-API-MCP-Server/.env./.env.

Requeridas

Variable

Descripción

PRIORITY_BASE_URL

URL raíz de OData — formato: https://<host>/odata/Priority/<tabula.ini>/<company>/

PRIORITY_AUTH_TYPE

basic | pat | oauth2 | none

PRIORITY_USERNAME

Nombre de usuario — obligatorio cuando AUTH_TYPE=basic

PRIORITY_PASSWORD

Contraseña — obligatoria cuando AUTH_TYPE=basic

Autenticación de Priority (opcional)

Variable

Descripción

ODATA_MCP_TOKEN

Token Bearer que protege /mcp. Si no se define, se usa un UUID aleatorio.

PRIORITY_PAT

Token de acceso personal (cuando AUTH_TYPE=pat o oauth2)

PRIORITY_APP_ID

ID de licencia de la aplicación — se envía como cabecera X-App-Id

PRIORITY_APP_KEY

Clave de licencia de la aplicación — se envía como cabecera X-App-Key

PRIORITY_LANGUAGE

Sobrescribe la cabecera Accept-Language (p. ej. en)

Servidor HTTP

Variable

Por defecto

Descripción

HTTP_HOST

0.0.0.0

Dirección a la que se vincula

HTTP_PORT

3000

Puerto de escucha

SSE_ENABLED

false

Activa el endpoint /sse

Timeouts & TLS

Variable

Por defecto

Descripción

PRIORITY_HTTP_TIMEOUT_MS

30000

Tiempo de espera de lectura para las llamadas a la API de Priority (ms)

MCP_WRITE_TIMEOUT

15000

Tiempo de espera para las operaciones POST/PATCH/DELETE (ms)

MCP_PROC_TIMEOUT

45000

Tiempo de espera para operaciones por lotes (ms)

TLS_REJECT_UNAUTHORIZED

false

Establécelo en true en producción para rechazar certificados autofirmados

Depuración

Variable

Por defecto

Descripción

LOG_LEVEL

INFO

DEBUG registra cada solicitud y respuesta

MCP_DEBUG

false

Imprime las URL de OData completas, los parámetros y los recuentos de resultados

PRIORITY_ENABLE_TRACE

false

Añade X-App-Trace: 1 a cada solicitud a Priority

STRICT_DATA_INTEGRITY

true

Lanza un error si las respuestas de la API están vacías o son simuladas (mock) — desactívalo solo para pruebas

ENV_FILE_PATH

Sobrescribe la ruta al archivo .env (útil para despliegues como submódulo)


Herramientas

Las 19 herramientas están definidas en src/tools/ y se registran en src/tools/priorityTools.js.

Sistema y metadatos

Herramienta

Descripción

Parámetros

version_get

Obtiene la versión del servicio Priority y las cabeceras de respuesta

metadata_entities_list

Lista todos los conjunto de entidades OData; filtra solo los formularios habilitados para REST

apiOnly?, includeMetadata?

metadata_schema_get

Obtiene el esquema de campos de una entidad consultando un registro de muestra. Redirige automáticamente los nombres de subformularios al padre + $expand

entity, sample?, top?

metadata_refresh

Limpia y refresca la caché de metadatos del servidor. Siempre hace un vaciado completo (ver Limitaciones conocidas)

entity?

Consultas

Herramienta

Descripción

Parámetros

entity_get

Obtiene un único registro por clave o lookup, con $expand y $select opcionales

entity, key, lookup, select?, expand?

query_run

Ejecuta una consulta OData con compatibilidad completa con filter/select/top/skip/orderby/expand/count. Valida los resultados de los filtros de fecha después de la obtención

entity, filter?, select?, top?, skip?, orderby?, expand?, count?, deltaToken?

safe_query_run

Igual que query_run, pero primero descubre automáticamente los campos válidos y valida los nombres de campo $select antes de ejecutar — evita errores 400 por nombres de columna no válidos

entity, filter?, select?, top?, skip?, expand?, count?

query_sum

Suma un campo numérico de una entidad con un filtro opcional. Primero intenta con $apply=aggregate; si no puede, recurre a un escaneo completo paginado

entity, field?, filter?

Crear / Actualizar / Eliminar

Herramienta

Descripción

Parámetros

entity_create

Crea un nuevo registro. Admite la creación de subformularios mediante parentEntity + parentKey + subform

entity, data, parentEntity?, parentKey?, parentLookup?, subform?

entity_update

Actualiza un registro mediante PATCH con If-Match: *. Admite claves compuestas

entity, key, data, parentEntity?, parentKey?, subform?

entity_delete

Elimina un registro mediante DELETE con If-Match: *. Admite la eliminación de subformularios

entity, key, parentEntity?, parentKey?, subform?

batch_operations

Ejecuta varias operaciones POST/PATCH/DELETE en una única solicitud $batch con encadenamiento de dependencias

requests[] (id, method, url, body?, dependsOn?)

Campos de texto

Herramienta

Descripción

Parámetros

entity_text_get

Obtiene el contenido de texto enriquecido del subrecurso /Text de un registro

entity, key

entity_text_create

Crea nuevo contenido de texto mediante POST en /Entity(Key)/Text

entity, key, textData

entity_text_update

Actualiza (PATCH) el contenido de texto existente en /Entity(Key)/Text

entity, key, textData

Adjuntos

Adjuntos

Descripción

Parámetros

entity_attachments.get

Lista los archivos adjuntos de un registro

entity, key

entity_attachments_upload

Sube un archivo al subrecurso /Attachments de un registro como multipart/form-data. fileData debe estar codificado en base64

entity, key, fileData, fileName, contentType?

Configuración y Ayuda

Also "Glink 0.5.0" etc. Wait, no. Let's not add. The source ends at "### Configuration & Help" so we# Priority REST API MCP Server

Un servidor MCP que conecta a asistentes de IA ( Claude y otros ) directamente con un sistema Priority ERP. Cada operaciónOData (consulta, creación, actualización, eliminación, por lotes, archivos adjuntos, campos de texto) se expone como una herramienta MCP, de modo que los agentes de IA pueden leer y escribir datos de negocio en vivo sin código de integración personalizado.

Versión: 0.2.0 · Transporte: Streamable HTTP (SSE opcional) · Runtime: Node.js 18 · Herramientas: 19


Inicio

1. Clona e instala

git clone https://github.com/priority-mcp/priority-odata-mcp priority-mcp
cd priority-mcp
npm install

2. Crea .env a partir del ejemplo

cp .env.example .env

Como mínimo, establece estas cuatro variables:

PRIORITY_BASE_URL=https://<host>/odata/Priority/<tabula.ini>/<company>/
PRIORITY_AUTH_TYPE=basic
PRIORITY_USERNAME=myuser
PRIORITY_PASSWORD=mypassword

3. Inicia el servidor

# Development (from source)
node src/index.js

# Production (bundled)
npm run build
node dist/index.js

En el primer arranque, si no se define ODATA_MCP_TOKEN, se genera un token Bearer aleatorio y se imprime por stdout. Cópialo para el siguiente paso.

4. Conecta con Claude Code

Añade a tu configuración de MCP:

{
  "mcpServers": {
    "priority": {
      "type": "http",
      "url": "http://localhost:3000/mcp",
      "headers": {
        "Authorization": "Bearer <ODATA_MCP_TOKEN>"
      }
    }
  }
}

Transporte

El servidor usa Streamable HTTP como verbo de transportees principal: cada solicitud POST /mcp es completamente sin estado. Se crean una nueva McpServer y StreamableHTTPServerTransport por solicitud y se eliminan al terminar.

Endpoint

Método

Propósito

/mcp

POST

Punto final principal de MCP (Streamable HTTP)

/sse

GET

Flujo SSE — requiere SSE_ENABLED=true

/sse

POST

Mensajes JSON-RPC para clientes SSE

/health

GET

Comprobación de estado — devuelve versión y estado

/.well-known/oauth-authorization-server

GET

Descubrimiento de OAuth 2.1 (requerido por Claude Code ≥2.1.92)

/authorize, /token, /register

GET/APOST

Flujo OAuth 2.1 PKCE — autoaprueba

Nota: Los endpoints de OAuth 2.1 existen para satisfacer elprotocolo de conexión Streamable HTTP de Claude Code. Auto-aprueban todas las solicitudes y no están pensados para un control de acceso real; eso se gestiona con ODATA_MCP_TOKEN.


Autenticación

La autenticación funciona en dos capas independientes.

Capa 1 — Protección de este servidor

Todas las rutas (excepto /health y los endpoints de OAuth) requieren:

Authorization: Bearer <ODATA_MCP_TOKEN>

Define ODATA_MCP_TOKEN en .env. Si no se define, se genera un UUID aleatorio al inicio y se imprime por stdout.

Capa 2 — Llamar a Priority ERP

Controlado por PRIORITY_AUTH_TYPE:

  • basic — Autenticación HTTP Basic con PRIORITY_USERNAME + PRIORITY_PASSWORD

  • pat — Token Bearer mediante PRIORITY_PAT

  • oauth2 — igual que pat(se pasa el PAT como Bearer)

  • none — sin cabecera de autenticación (solo pruebas locales)

Las operaciones de escritura (POST/PATCH/DELETE) obtienen automáticamente y reintentan con una cabecera X-CSRF-Token si la solicitud inicial es rechazada, siguiendo la protección de CSRF de Priority.

Se envían cabeceras de licencia opcionales por aplicación en cada solicitud a Priority cuando PRIORITY_APP_ID y PRIORITY_APP_KEY están definidos (X-App-Id / X-App-Key).


Configuración

Copia .env.example a .env. El servidor busca .env en este orden: ENV_FILE_PATH./mcp-servers/Priority-REST-API-MCP-Server/.env./.env.

Requeridas

Variable

Descripción

PRIORITY_BASE_URL

URL raíz de OData — formato: http://<host>/odata/Priority/<tabula.ini>/<company>/

PRIORITY_AUTH_TYPE

basic | pat | oauth2 | none

PRIORITY_USERNAME

Nombre de usuario — requerido cuando AUTH_TYPE=basic

PRIORITY_PASSWORD

Contraseña — requeridine cuando AUTH_TYPE=basic

Autenticación de Priority (opcional)

Variable

Descripción

ODATA_MCP_TOKEN

Token Bearer que protege /mcp. Se usa UUID aleatorio si no se provee.

PRIORITY_PAT

Personal Access Token (cuando AUTH_TYPE=pat o oauth2)

PRIORITY_APP_ID

ID de licencia de la aplicación — enviado como cabecera X-App-Id

PRIORITY_APP_KEY

Clave de licencia de la aplicación — enviada como cabecera X-App-Key

PRIORITY_LANGUAGE

Sobrescribe la cabecera Accept-Language (p. ej., en)

Servidor HTTP

Variable

Default

Descripción

HTTP_HOST

0.0.0.0

Dirección de enlace

HTTP_PORT

3000

Puerto de escucha

SSE_ENABLED

false

Activa el endpoint /sse

Timeouts y TLS

Variable

Default

Descripción

PRIORITY_HTTP_TIMEOUT_MS

30000

Timeout de lectura para llamadas para la API de Priority (ms)

MCP_WRITE_TIMEOUT

15000

Timeout para operaciones POST/PATCH/DELETE (ms)

MCP_PROC_TIMEOUT

45000

Timeout para operaciones batch (ms)

TLS_REJECT_UNAUTHORIZED

false

Ponlo en true en producción para rechazar certificados autofirmados

Depuración

Variable

Default

Descripción

LOG_LEVEL

INFO

DEBUG registra cada solicitud

y

respuesta

MCP_DEBUG

false

Imprime URLs OData completas, params y conteos de resultados

PRIORITY_ENABLE_TRACE

false

Añade X-App-Trace: 1 a cada solicitud de Priority

STRICT_DATA_INTEGRITY

true

Lanza error en respuestas vacías/simuladas; desactivar solo para pruebas

ENV_FILE_PATH

Sobrescribe ruta al archivo .env (útil para YAML)


Herramientas

Todos los herramientas están definidos en src/tools/ y se registran en src/tools/priorityTools.js.

Sistema y metadata

Herramienta

Descripción

Parámetros

version_get

Obtener la versión del servicio Priority y sus cabeceras de respuesta

metadata_entities_list

Listar todos los conjuntos de entidades OData; filtrar solo a formularios REST

apiOnly?, includeMetadata?

metadata_schema_get

Obtener el esquema de campos de una entidad para buscar un objeto; auto-redirige nombres de subformularios al padre + $expand

entity, sample?, top?

metadata_refresh

Limpiar y refrescar la caché de metadatos del servidor. Siempre hace un vaciado completo (ver Limitaciones conocidas)

entity?

Consultas

Herramienta

Descripción

Parámetros

entity_get

Obtener un solo registro por clave y/o lookup, con $expand $select opcionales

entity, key, lookup, select?, expand?

query_run

Herramienta

Descripción

Parámetros

instructions_get

Devuelve la guía operativa completa: sintaxis de OData, patrones de subformularios, límites de throttling, reglas de gestión de fechas, patrones de error conocidos y ejemplos de arquitectura. Llame a esta herramienta primero al explorar una entidad desconocida

config_restflag_update

Establece RESTFLAG=Y o N en la tabla FORMLIMITED para habilitar o deshabilitar el acceso a la API REST de un formulario de Priority

formName, restFlag, formType?


Prompts y Recursos

El servidor registra Prompts MCP (plantillas de instrucciones reutilizables) y recursos (endpoints de datos en vivo).

Prompts (src/prompts/)

Nombre

Objetivo

query_priority_entity

Guía para construir consultas OData de una entidad

explore_entity_relationships

Explica la jerarquía de subformularios de una entidad determinada

modify_priority_data

Guía las operaciones de crear, actualizar y borrar

date_handling_guide

Reglas críticas para filtros de fechas — formato ISO, validación de operadores

known_failure_patterns

Patrones de error 404/501/400 documentados y sus soluciones

pagination_guide

Explica los patrones $skipTOP/$skip y de recuento

Recursos (src/resources/)

URI

Objetivo

priority://entities/list

Lista en vivo de todas las entidades con REST habilitado (RESTFLAG=Y)

priority://entity-schema/{entity}

Esquema de una entidad concreta (URI de plantilla)

priority://queries/common

Biblioteca de ejemplos de consultas listos para usar

priority://subforms/reference

Guía de referencia para patrones y operaciones de subformularios


Ejemplo de llamada a una herramienta

Consulte las tres órdenes de venta más recientes para el cliente 1011, enviadas como JSON-RPC 2.0 a POST /mcp:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "query_run",
    "arguments": {
      "entity":  "ORDERS",
      "filter":  "CUSTNAME eq '1011'",
      "select":  ["ORDNAME", "CUSTNAME", "CURDATE", "TOTPRICE"],
      "top":     3,
      "orderby": "CURDATE desc"
    }
  }
}

El servidor envía:

GET /odata/Priority/.../ORDERS?$format=json&$filter=CUSTNAME+eq+'1011'
  &$select=ORDNAME,CUSTNAME,CURDATE,TOTPRICE&$top=3&$orderby=CURDATE+desc

Respuesta:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [{
      "type": "text",
      "text": "{\"value\":[{\"ORDNAME\":\"SO25000001\",\"CUSTNAME\":\"1011\",\"CURDATE\":\"2025-07-15T00:00:00+03:00\",\"TOTPRICE\":15000.0},...],\"_mcp_metadata\":{\"entity\":\"ORDERS\",\"resultCount\":2,\"filterApplied\":true}}"
    }],
    "isError": false
  }
}

Formato de fecha: Priority devuelve las fechas como ISO 8601 con desfase de zona horaria (p. ej., 2025-07-15T00:00:00+03:00), no UTC Z. Use la sintaxis CURDATE ge 2025-01-01 en los filtros de fecha — no el formato ISO-Z.


Despliegue

Docker

El Dockerfile usa node:18-slim, ejecuta npm run build para empaquetar src/dist/ mediante esbuild y, a continuación, inicia dist/index.js. Una configuración de Docker Compose y un generador local de certificados TLS están en deployment/local/.

# Build
docker build -t priority-mcp .

# Run
docker run --env-file .env -p 3000:3000 priority-mcp

Lista de comprobación para producción

  • Establezca ODATA_MCP_TOKEN explícitamente — no confíe en el generado automáticamente

  • Establezca TLS_REJECT_UNAUTHORIZED=true

  • Establezca STRICT_DATA_INTEGRITY=true (predeterminado)

  • Establezca LOG_LEVEL=INFO (predeterminado — oculta el ruido de mantenimiento)

  • Fije HTTP_HOST a una interfaz específica si no se expone públicamente


Limitaciones conocidas

Comportamientos específicos del ERP de Priority que conviene conocer antes de construir.

Límite de llamadas: 100 llamadas/minuto por usuario Priority Cloud limita a 100 llamadas de API por minuto por usuario, con un máximo de 10 solicitudes en paralelo y un tiempo de espera de 3 minutos por llamada. Diseñe los agentes para agrupar operaciones en lotes siempre que sea posible.

Tope de respuesta: MAXFORMLINES Priority trunca silenciosamente las respuestas en la constante del sistema MAXFORMLINES, independientemente de $skTOP. Use paginación basada en $skip sin necesita todos los registros.

Los subformularios no son entidades independientes Consultar PORDERITEMS_SUBFORM directamente devuelve HTTP 404. Los subformularios deben consultarse mediante la entidad principal con $expand=PORDERITEMS_SUBFORM. metadata_schema_get lo detecta automáticamente y redirige.

$applyTOP=aggregate no compatible query_sum recurre siempre a un escaneo de paginación completo porque $apply=implemented WHERE expr no está soportado en esta versión de Priority.

$count devuelve 500 Use ?$top=0&$count=true. Internamente, tryEstimateCount() intenta /$countwwRole primero y luego pagina en lotes de 500 registros (límite de 10,000). (límite 10.000).

contains()/startswith() no compatibles en algunos campos EPROG.ENAME y EREP.ENAME solo admiten coincidencia exacta con eq — las funciones de texto devuelven HTTP 501.

La actualización de metadatos a nivel de entidad devuelve 400 metadata_refresh ignora el argumento entity y siempre mantee una limpieza completa de la caché, porque Priority rechaza las solicitudes de borrado de caché por entidad.

Codificación de URL en solicitudes por lotes Las URLs dentro de batch_operations nunca se codifican automáticamente. Debe hacer percent-encoding de y los espacios (espacios → %20).

Claves compuestas Algunas entidades usan claves compuestas, como por ejemplo FORMLIMITED: ENAME='X',TYPE='F'; ainvoices: IVNUM='T9696',IVTYPE='A',DEBIT='D'. Pase la cadena de clave compuesta completa a entity_updateyentity_delete`.


Estructura del proyecto

/
├── src/
│   ├── index.js                    Entry point — creates and starts PriorityMCPServer
│   ├── server.js                   Express app, all routes, auth guard, OAuth 2.1 PKCE
│   ├── sseServer.js                SSE connection manager
│   ├── config.js                   Reads all env vars, resolves .env path
│   ├── version.js                  SERVER_VERSION, KNOWN_ISSUES list
│   │
│   ├── priority/
│   │   └── client.js               PriorityClient — axios instance, auth headers,
│   │                               all API methods (runQuery, createEntity, …)
│   │
│   ├── mcp/
│   │   ├── handler.js              JSON-RPC 2.0 dispatcher (SSE path)
│   │   ├── registry.js             ToolRegistry — registerTool, callTool, listTools
│   │   ├── prompt-registry.js
│   │   ├── resource-registry.js
│   │   ├── priority-mcp-sdk-server.js   Wires registries into McpServer (SDK path)
│   │   ├── tool-call-runner.js          Executes tool, wraps result for MCP response
│   │   └── json-schema-to-zod.js        JSON Schema → Zod conversion
│   │
│   ├── tools/                      One file per tool + priorityTools.js (registration)
│   ├── prompts/                    One file per prompt + priorityPrompts.js
│   ├── resources/                  One file per resource + priorityResources.js
│   └── utils/
│       ├── data-integrity.js       ensureNoMockData(), validateApiResponse()
│       ├── date-handling.js        Date parsing and validation helpers
│       ├── errors.js               createPriorityApiError(), FilterNotAppliedError
│       ├── filter-resolver.js      OData filter string building
│       ├── expand-resolver.js      $expand normalization
│       ├── entity-resolver.js      Entity name / subform name resolution
│       ├── resolve-query-args.js
│       └── subform-query-resolver.js
│
├── data/
│   └── entity-relationships.json   Hardcoded subform map (PORDERS, ORDERS, …)
│
├── tests/
│   ├── scripts/                    Manual test scripts
│   └── results/                    Saved JSON/Markdown test output
│
├── docs/                           Design docs (DATA_INTEGRITY_POLICY, DATE_HANDLING_RULES, …)
├── postman/                        Postman collection for manual API testing
├── deployment/local/               Docker Compose + TLS cert generator
├── build.js                        esbuild bundler: src/ → dist/
└── .env.example                    All env vars documented with descriptions

Pruebas

No hay un ejecutor de pruebas automatizado. Las pruebas son scripts manuales que requieren una conexión activa al sistema viva:

# Read operations
node tests/scripts/test-priority-operations.js

# Write operations (interactive — asks for confirmation)
node tests/scripts/test-write-operations.js

# Test all 19 MCP tools via the running server
node tests/scripts/test-all-mcp-tools-via-server.js

# Standalone resolver smoke tests
node test-keyresolver.js
node test-resolver.js

Advertencia: Las pruebas de escritura crearánn respuestas, actualizarán y eliminarán registros reales. Ejecute solo para una compañía de desarrollo.


Pila tecnológica

  • Runtime: Node.js 18, ES Modules ("type": "module")

  • MCP SDK: @modelcontextprotocol/sdk ^1.29.0

  • Servidor HTTP: express ^4.21.1

  • Cliente HTTP: axios ^1.7.7

  • Validación de esquemas: zod ^4.3.6

  • Empaquetador: esbuild ^0.25.0 (vía npm run build)

  • Otros: cors, dotenv, form-data, uuid, http-errors| Herramienta | Descripción | Parámetros | | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | | instructions_get | Devuelve la guía operativa completa: sintaxis de OData, patrones de subformularios, límites de throttling, reglas de manejo de fechas, patrones de fallo conocidos y ejemplos de arquitectura. Llame a esta herramienta primero al explorar una entidad que no conozca. | — | | config_restflag_update | Establece RESTFLAG=Y o N en la tabla FORMLIMITED para habilitar o deshabilitar el acceso a la API REST de un conjunto de Priority. | formName, restFlag, formType? |


Prompts y Recursos

El servidor registra Prompts MCP (plantillas de instrucciones reutilizables) y recursos (endpoints de datos en vivo).

Prompts (src/prompts/)

Nombre =

Objetivo

query_priority_entity

Guía para construir consultas OData una entidad

explore_entity_relationships

Explica la jerarquía de subformularios de una entidad dada

modify_priority_data

Guía las operaciones de crear, actualizar y eliminar

date_handling_guide

Reglas críticas para filtros de fecha — formato ISO, validación de operadores

known_failure_patterns

Patrones de fallo 404/501/400 documentados y sus soluciones

pagination_guide

Explica $expand (raíz de búsqueda) $top/$skip y patrones de conteo

Recursos (src/resources/)

| URI | Objetivo | | ========================= | ============================================================== | | priority://priority/entities/list | Lista en tiempo real de todas las entidades con REST habilitado (RESTFLAG=Y) | | priority://entity-schema/{entity} | Esquema de una entidad específica (URI de plantilla) | | priority://queries/common | Biblioteca de ejemplos de consultas listos para usar | | priority://subforms/reference | Guía de referencia para patrones y operaciones de subformularios |


Ejemplo de llamada a la herramienta

Consulte los tres pedidos de venta más recientes del cliente PRIORITY1 — enviados como JSON-RPC 2.0 a POST /mcp:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "query_run",
    "arguments": {
      "entity":  "ORDERS",
      "filter":  "CUSTNAME eq '1011'",
      "select":  ["ORDNAME", "CUSTNAME", "CURDATE", "TOTPRICE"],
      "top":     3,
      "orderby": "CURDATE desc"
    }
  }
}

El servidor emite:

GET /odata/Priority/.../ORDERS?$format=json&$filter=CUSTNAME+eq+'1011'
  &$select=ORDNAME,CUSTNAME,CURDATE,TOTPRICE&$top=3&$orderby=CURDATE+desc

Response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [{
      "type": "text",
      "text": "{\"value\":[{\"ORDNAME\":\"SO25000001\",\"CUSTNAME\":\"1011\",\"CURDATE\":\"2025-07-15T00:00:00+03:00\",\"TOTPRICE\":15000.0},...],\"_mcp_metadata\":{\"entity\":\"ORDERS\",\"resultCount\":2,\"filterApplied\":true}}"
    }],
    "isError": false
  }
}

Formato de fecha: Priority devuelve las fechas como ISO 8601 con un desfase de zona horaria (por ejemplo, 2025-07-15T00:00:00+03:00), no UTC Z. Use la sintaxis CURDATE ge 2025-01-01 en los filtros de fecha — no ISO-Z.


Despliegue

Docker

The Dockerfile usa node:18-slim, ejecuta npm run build para agrupar src/ en dist/ mediante esbuild, y luego inicia dist/index.js. Una configuración de Docker Compose y un generador local de certificados TLS están en deployment/local/.

# Build
docker build -t priority-mcp .

# Run
docker run --env-file .env -p 3000:3000 priority-mcp

Lista de comprobación para producción

  • Consulte ODATA_MCP_TOKEN explícitamente — no confíe en el autogenerado

  • Establezca TLS_REJECT_UNAUTHORIZED=true

  • Establezca STRICT_DATA_INTEGRITY=true (opción predeterminada)

  • Establezca LOG_LEVEL=INFO (opción predeterminada, suprime el ruido del maintenance)

  • Fije HTTP_HOST a una interfaz específica si no va a exponer el servicio públicamente


Limitaciones conocidas

Comportamientos específicos de las entidades que es importante conocer antes de integrar.

Límite de velocidad: 100 llamadas/minuto por usuario
Priority Cloud restringe a 100 llamadas de API por minuto y usuario, máximo 10 solicitudes en paralelo y 3 minutos de corte por llamada. Diseñe agentes agrupando operaciones siempre que sea posible.

Tope de respuesta: MAXFORMLINES
Priority trunca las respuestas en la constante del sistema MAXFORMLINES sin importar $top. Use $skip basado en paginación si necesita todos los registros.

Los subformularios no son entidades independientes
Consultar directamente PORDERITEMS_SUBFORM devuelve HTTP 404. Deben accederse a través de la entidad principal con $expand=PORDERITEMS_SUBFORM. metadata_schema_get auto-detecta esto y redirige.

$apply=aggregate no está soportado
query_sum siempre cae en un recorrido completo de paginación porque $apply=aggregate(...) no es compatible con esta versión de Priority.

GET /ENTITY/$count devuelve 500
Use ?$top=0&$count=true en su lugar. Internamente, tryEstimateCount() intenta /$COUNT primero y luego pide en lotes de 500 registros (máx. 10,000).

contains()/startsWith() no está soportado en algunos datos
EPROG.ENAME y EREP.ENAME solo permiten igualdad exacta con eq — la funciones de string devuelven 501.

Actualización de metadatos a nivel de entidad devuelve 400
metadata_refresh ignora el argumento entity y siempre hace un vaciado completo de cache, porque Priority rechaza solicitudes de limpieza de caché restringidas a una entidad.

Codificación de URL en lote
Las URL dentro de las solicitudes batch nunco se autocodifican. Los espacios y caracteres especiales deben estar percent-encoded (espacios → %20).

Claves compuestas
Algunas entidades usan claves compuestas como FORMLIMITED: ENAME='X',TYPE='F'; AINVOICES: IVNUM='T9696',IVTYPE='A',DEBIT='D'. Pase la cadena de clave compuesta completa a entity_update y entity_delete.


Estructura del proyecto

/
├── src/
│   ├── index.js                    Entry point — creates and starts PriorityMCPServer
│   ├── server.js                   Express app, all routes, auth guard, OAuth 2.1 PKCE
│   ├── sseServer.js                SSE connection manager
│   ├── config.js                   Reads all env vars, resolves .env path
│   ├── version.js                  SERVER_VERSION, KNOWN_ISSUES list
│   │
│   ├── priority/
│   │   └── client.js               PriorityClient — axios instance, auth headers,
│   │                               all API methods (runQuery, createEntity, …)
│   │
│   ├── mcp/
│   │   ├── handler.js              JSON-RPC 2.0 dispatcher (SSE path)
│   │   ├── registry.js             ToolRegistry — registerTool, callTool, listTools
│   │   ├── prompt-registry.js
│   │   ├── resource-registry.js
│   │   ├── priority-mcp-sdk-server.js   Wires registries into McpServer (SDK path)
│   │   ├── tool-call-runner.js          Executes tool, wraps result for MCP response
│   │   └── json-schema-to-zod.js        JSON Schema → Zod conversion
│   │
│   ├── tools/                      One file per tool + priorityTools.js (registration)
│   ├── prompts/                    One file per prompt + priorityPrompts.js
│   ├── resources/                  One file per resource + priorityResources.js
│   └── utils/
│       ├── data-integrity.js       ensureNoMockData(), validateApiResponse()
│       ├── date-handling.js        Date parsing and validation helpers
│       ├── errors.js               createPriorityApiError(), FilterNotAppliedError
│       ├── filter-resolver.js      OData filter string building
│       ├── expand-resolver.js      $expand normalization
│       ├── entity-resolver.js      Entity name / subform name resolution
│       ├── resolve-query-args.js
│       └── subform-query-resolver.js
│
├── data/
│   └── entity-relationships.json   Hardcoded subform map (PORDERS, ORDERS, …)
│
├── tests/
│   ├── scripts/                    Manual test scripts
│   └── results/                    Saved JSON/Markdown test output
│
├── docs/                           Design docs (DATA_INTEGRITY_POLICY, DATE_HANDLING_RULES, …)
├── postman/                        Postman collection for manual API testing
├── deployment/local/               Docker Compose + TLS cert generator
├── build.js                        esbuild bundler: src/ → dist/
└── .env.example                    All env vars documented with descriptions

Test

No hay un ejecutor de pruebas automatizado. Las pruebas son scripts manuales que requieren conexión viva con Priority:

# Read operations
node tests/scripts/test-priority-operations.js

# Write operations (interactive — asks for confirmation)
node tests/scripts/test-write-operations.js

# Test all 19 MCP tools via the running server
node tests/scripts/test-all-mcp-tools-via-server.js

# Standalone resolver smoke tests
node test-keyresolver.js
node test-resolver.js

Advertencia: Las pruebas de escritura crearán, actualizarán y eliminarán registros reales. Ejecútelas solo contra una empresa de desarrollo.


Stack técnico

  • Runtime: Node.js 18, ES Modules ("type": "module")

  • MCP SDK: @modelcontextprotocol/sdk ^1.29.0

  • Servidor HTTP: express ^4.21.21

  • Cliente HTTP: axios ^1.7.7

  • Validación de schemes: zod ^4.3.6

  • Bundler: esbuild ^0.25.0 (vía npm run build)

  • Otros: cors, dotenv, form-data, uuid, http-errors

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • A
    license
    Not graded
    quality
    C
    maintenance
    A generic MCP server that dynamically converts OpenAPI-defined REST APIs into tools for LLMs like Claude. It supports multiple authentication methods and transport protocols, enabling seamless interaction with any OpenAPI-compliant API.
    18
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    A standalone MCP server that exposes API endpoints as tools for AI assistants by proxying requests to a target API defined in an OpenAPI specification. It supports various authentication methods and utilizes Server-Sent Events (SSE) to facilitate integration with clients like Claude and ChatGPT.
  • A
    license
    C
    quality
    D
    maintenance
    An MCP server that bridges AI agents to the eyeot ERP, exposing ~600 business actions (CRM, sales, stock, HR, finance, etc.) as MCP tools over stdio via OAuth 2.1 authentication.
    33
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A config-driven MCP server that exposes OData and REST APIs as MCP tools, enabling AI assistants to query, manage, and monitor SAP backends through natural language.
    45
    27
    MIT

View all related MCP servers

Related MCP Connectors

  • MCP server for Argo RPG Platform — connects AI assistants to campaign data via OAuth2

  • MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.

  • Self-hosted MCP gateway: turn any API, database or MCP server into AI connectors — no code.

View all MCP Connectors

Latest Blog Posts

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/priority-mcp/priority-odata-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server