Priority REST API MCP Server
Priority REST API MCP 服务器
一个将 AI 助手(Claude 及其他)直接连接到 Priority ERP 系统的 MCP 服务器。每个 OData 操作(查询、创建、更新、删除、批处理、附件、文本字段)都以 MCP 工具的形式暴露,使 AI 代理无需自定义集成代码即可读写实时业务数据。
版本: 0.2.0 · 传输方式: Streamable HTTP(可选 SSE)· 运行时: Node.js 18 · 工具数: 19
快速开始
1. 克隆并安装
git clone https://github.com/priority-mcp/priority-odata-mcp priority-mcp
cd priority-mcp
npm install2. 根据示例创建 .env
cp .env.example .env至少需要设置以下四个变量:
PRIORITY_BASE_URL=https://<host>/odata/Priority/<tabula.ini>/<company>/
PRIORITY_AUTH_TYPE=basic
PRIORITY_USERNAME=myuser
PRIORITY_PASSWORD=mypassword3. 启动服务器
# Development (from source)
node src/index.js
# Production (bundled)
npm run build
node dist/index.js首次运行时,如果未设置 ODATA_MCP_TOKEN,将生成一个随机 Bearer 令牌并打印到标准输出。请复制该令牌用于下一步。
4. 从 Claude Code 连接
在 MCP 配置中添加:
{
"mcpServers": {
"priority": {
"type": "http",
"url": "http://localhost:3000/mcp",
"headers": {
"Authorization": "Bearer <ODATA_MCP_TOKEN>"
}
}
}
}Related MCP server: mcp_sdk_eyra_accelerator
传输方式
服务器使用 Streamable HTTP 作为主要传输方式——每个 POST /mcp 请求都是完全无状态的。每个请求都会创建新的 McpServer 和 StreamableHTTPServerTransport,处理完毕后即销毁。
端点 | 方法 | 用途 |
| POST | 主要 MCP 端点(Streamable HTTP) |
| GET | SSE 流——需要 |
| POST | 面向 SSE 客户端的 JSON-RPC 消息 |
| GET | 健康检查——返回版本和状态 |
| GET | OAuth 2.1 发现(Claude Code ≥2.1.92 必需) |
| GET/POST | OAuth 2.1 PKCE 流程——自动批准 |
注意: OAuth 2.1 端点的存在是为了满足 Claude Code 的 Streamable HTTP 连接握手要求。它们会自动批准所有请求,并非用于真正的访问控制——访问控制由
ODATA_MCP_TOKEN处理。
身份验证
身份验证在两个独立的层面运行。
第 1 层——保护此服务器
所有路由(/health 和 OAuth 端点除外)都需要:
Authorization: Bearer <ODATA_MCP_TOKEN>在 .env 中设置 ODATA_MCP_TOKEN。如果未设置,启动时会生成一个随机 UUID 并打印到标准输出。
第 2 层——调用 Priority ERP
由 PRIORITY_AUTH_TYPE 控制:
basic— 使用PRIORITY_USERNAME+PRIORITY_PASSWORD进行 HTTP Basic 认证pat— 通过PRIORITY_PAT使用 Bearer 令牌oauth2— 与pat相同(将 PAT 作为 Bearer 令牌传递)none— 不发送认证头(仅限本地测试)
写操作(POST/PATCH/DELETE)如果初始请求被拒绝,会自动获取 X-CSRF-Token 头并重试,遵循 Priority 的 CSRF 保护模式。
当设置了 PRIORITY_APP_ID 和 PRIORITY_APP_KEY 时,每个 Priority 请求都会发送可选的按应用程序许可头(X-App-Id / X-App-Key)。
配置
将 .env.example 复制为 .env。服务器按以下顺序搜索 .env:ENV_FILE_PATH → ./mcp-servers/Priority-REST-API-MCP-Server/.env → ./.env。
必需项
变量 | 描述 |
| OData 根 URL——格式: |
|
|
| 用户名——当 |
| 密码——当 |
Priority 认证(可选)
变量 | 描述 |
| 保护 |
| 个人访问令牌(当 |
| 应用程序许可 ID——作为 |
| 应用程序许可密钥——作为 |
| 覆盖 |
HTTP 服务器
变量 | 默认值 | 描述 |
|
| 绑定地址 |
|
| 监听端口 |
|
| 启用 |
超时与 TLS
变量 | 默认值 | 描述 |
|
| Priority API 调用的读取超时(毫秒) |
|
| POST/PATCH/DELETE 操作的超时(毫秒) |
|
| 批处理操作的超时(毫秒) |
|
| 生产环境中设置为 |
调试
变量 | 默认值 | 描述 |
|
|
|
|
| 打印完整的 OData URL、参数、结果计数 |
|
| 为每个 Priority 请求添加 |
|
| 在空/模拟 API 响应时抛出异常——仅测试时禁用 |
| — | 覆盖 |
工具
所有 19 个工具都定义在 src/tools/ 中,并在 src/tools/priorityTools.js 中注册。
系统与元数据
工具 | 描述 | 参数 |
| 获取 Priority 服务版本和响应头 | — |
| 列出所有 OData 实体集;仅筛选 REST 启用的表单 |
|
| 通过获取示例记录获取实体的字段架构。自动将子表单名称重定向到父表单 + |
|
| 清除并刷新服务器端元数据缓存。始终执行完全刷新(参见已知限制) |
|
查询
工具 | 描述 | 参数 |
| 按主键或查找获取单条记录,支持可选的 |
|
| 运行 OData 查询,支持完整的 filter/select/top/skip/orderby/expand/count。获取后验证日期筛选结果 |
|
| 与 |
|
| 对实体中的数值字段求和,支持可选筛选。先尝试 |
|
创建 / 更新 / 删除
工具 | 描述 | 参数 |
| 创建新记录。支持通过 |
|
| 通过 PATCH 更新记录,使用 |
|
| 通过 DELETE 删除记录,使用 |
|
| 在单个 |
|
文本字段
工具 | 描述 | 参数 |
| 获取记录 |
|
| 向 |
|
| 对 |
|
附件
工具 | 描述 | 参数 |
| 列出记录上的附件 |
|
| 以 multipart/form-data 将文件上传到记录的 |
|
配置与帮助
Tool | Description | Parameters |
| 返回完整操作指南:OData 语法、子表单模式、限流限制、日期处理规则、已知故障模式及架构示例。在探索不熟悉的实体时,请首先调用此工具 | — |
| 在 |
|
提示词与资源
服务器注册了 MCP 提示词(可复用的指令模板)和资源(实时数据端点)。
提示词(src/prompts/)
名称 | 用途 |
| 针对实体构造 OData 查询的指南 |
| 解释给定实体的子表单层级结构 |
| 指导创建、更新和删除操作 |
| 日期过滤器的关键规则 — ISO 格式、运算符验证 |
| 已记录的 404/501/400 模式及其解决方法 |
| 解释 |
资源(src/resources/)
URI | 用途 |
| 所有已启用 REST 的实体的实时列表( |
| 特定实体的模式(模板 URI) |
| 可直接使用的查询示例库 |
| 子表单模式与操作的参考指南 |
工具调用示例
查询客户 1011 最近的三张销售订单 — 以 JSON-RPC 2.0 发送至 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"
}
}
}服务器发出:
GET /odata/Priority/.../ORDERS?$format=json&$filter=CUSTNAME+eq+'1011'
&$select=ORDNAME,CUSTNAME,CURDATE,TOTPRICE&$top=3&$orderby=CURDATE+desc响应:
{
"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
}
}日期格式: Priority 返回的日期为带时区偏移的 ISO 8601 格式(例如
2025-07-15T00:00:00+03:00),而非 UTCZ。在日期过滤器中使用CURDATE ge 2025-01-01语法 — 不要使用 ISO-Z 格式。
部署
Docker
# Build
docker build -t priority-mcp .
# Run
docker run --env-file .env -p 3000:3000 priority-mcpDockerfile 使用 node:18-slim,运行 npm run build 通过 esbuild 将 src/ 打包到 dist/,然后启动 dist/index.js。Docker Compose 配置和本地 TLS 证书生成器位于 deployment/local/。
生产环境检查清单
显式设置
ODATA_MCP_TOKEN— 不要依赖自动生成的值设置
TLS_REJECT_UNAUTHORIZED=true设置
STRICT_DATA_INTEGRITY=true(默认)设置
LOG_LEVEL=INFO(默认 — 抑制维护性日志噪音)如果不对外公开,请将
HTTP_HOST固定到特定接口
已知限制
构建前值得了解的 Priority ERP 特定行为。
速率限制 — 每个用户每分钟 100 次调用 Priority Cloud 将 API 调用限制为每个用户每分钟 100 次,最多 10 个并行请求,每次调用超时 3 分钟。设计代理时请尽可能批量处理操作。
响应上限 — MAXFORMLINES
无论 $top 如何设置,Priority 都会在 MAXFORMLINES 系统常量处静默截断响应。如果需要所有记录,请使用基于 $skip 的分页。
子表单不是独立实体
直接查询 PORDERITEMS_SUBFORM 会返回 HTTP 404。必须通过父实体并使用 $expand=PORDERITEMS_SUBFORM 访问子表单。metadata_schema_get 会自动检测此情况并重定向。
不支持 $apply=aggregate
由于此 Priority 版本不支持 $apply=aggregate(...),query_sum 始终回退到完整分页扫描。
GET /ENTITY/$count 返回 500
请改用 ?$top=0&$count=true。在内部,tryEstimateCount() 会先尝试 /$count,然后以每批 500 条记录进行分页(上限为 10,000 条)。
某些字段不支持 contains()/startswith()
EPROG.ENAME 和 EREP.ENAME 仅支持 eq 精确匹配 — 字符串函数返回 HTTP 501。
实体级元数据刷新返回 400
metadata_refresh 会忽略 entity 参数并始终执行完整缓存刷新,因为 Priority 拒绝实体范围的缓存清除请求。
批量 URL 编码
batch_operations 请求中的 URL 永远不会被自动编码。空格和特殊字符必须手动进行百分号编码(空格 → %20)。
复合键
某些实体使用复合键,例如 FORMLIMITED:ENAME='X',TYPE='F';AINVOICES:IVNUM='T9696',IVTYPE='A',DEBIT='D'。将完整的复合键字符串传递给 entity_update 和 entity_delete。
项目结构
/
├── 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测试
没有自动化测试运行器。测试是需要实时 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警告: 写入测试将创建、更新和删除真实记录。请仅针对开发公司运行。
技术栈
运行时: Node.js 18、ES Modules(
"type": "module")MCP SDK:
@modelcontextprotocol/sdk ^1.29.0HTTP 服务器:
express ^4.21.1HTTP 客户端:
axios ^1.7.7模式验证:
zod ^4.3.6打包器:
esbuild ^0.25.0(通过npm run build)其他:
cors、dotenv、form-data、uuid、http-errors
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 gradedqualityCmaintenanceA 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.18MIT
- FlicenseNot gradedqualityDmaintenanceA 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.
- AlicenseCqualityDmaintenanceAn 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.331MIT
- AlicenseNot gradedqualityDmaintenanceA 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.4527MIT
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.
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/priority-mcp/priority-odata-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server