Priority REST API MCP Server
Priority REST API MCP Server
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 토큰이 생성되어 stdout에 출력됩니다. 다음 단계를 위해 복사하세요.
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 요청은 완전히 무상태(stateless)입니다. 요청마다 새 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가 생성되어 stdout에 출력됩니다.
계층 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)은 초기 요청이 거부되면 Priority의 CSRF 보호 패턴에 따라 X-CSRF-Token 헤더를 자동으로 가져와 재시도합니다.
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 호출 읽기 시간 초과(ms) |
|
| POST/PATCH/DELETE 작업 시간 초과(ms) |
|
| 배치 작업 시간 초과(ms) |
|
| 프로덕션에서 자체 서명 인증서를 거부하려면 |
디버깅
변수 | 기본값 | 설명 |
|
|
|
|
| 전체 OData URL, 매개변수, 결과 수 출력 |
|
| 모든 Priority 요청에 |
|
| 빈/모의 API 응답에서 오류 발생 — 테스트에서만 비활성화 |
| — |
|
도구
19개 도구는 모두 src/tools/에 정의되어 있으며 src/tools/priorityTools.js에 등록되어 있습니다.
시스템 및 메타데이터
도구 | 설명 | 매개변수 |
| Priority 서비스 버전 및 응답 헤더 가져오기 | — |
| 모든 OData 엔티티 세트 나열; REST 지원 양식만 필터링 |
|
| 샘플 레코드를 가져와 엔티티의 필드 스키마 가져오기. 하위 양식 이름을 상위 + |
|
| 서버 측 메타데이터 캐시를 지우고 새로 고침. 항상 전체 플러시 수행(알려진 제한 사항 참조) |
|
쿼리
도구 | 설명 | 매개변수 |
| 키 또는 조회로 단일 레코드 가져오기, 선택적 |
|
| 전체 필터/선택/상위/건너뛰기/정렬/확장/개수 지원으로 OData 쿼리 실행. 가져온 후 날짜 필터 결과 검증 |
|
|
|
|
| 선택적 필터로 엔티티 전체의 숫자 필드 합계. 먼저 |
|
생성 / 업데이트 / 삭제
도구 | 설명 | 매개변수 |
| 새 레코드 생성. |
|
|
|
|
|
|
|
| 종속성 체이닝으로 하나의 |
|
텍스트 필드
도구 | 설명 | 매개변수 |
| 레코드의 |
|
|
|
|
|
|
|
첨부 파일
도구 | 설명 | 매개변수 |
| 레코드의 첨부 파일 목록 |
|
| 파일을 레코드의 |
|
구성 및 도움말
도구 | 설명 | 매개변수 |
| 전체 운영 가이드를 반환합니다: OData 구문, 하위 양식 패턴, 스로틀 제한, 날짜 처리 규칙, 알려진 실패 패턴, 아키텍처 예시. 익숙하지 않은 엔티티를 탐색할 때 먼저 호출하세요. | — |
| Priority 양식에 대한 REST API 액세스를 활성화하거나 비활성화하려면 |
|
프롬프트 및 리소스
서버는 MCP 프롬프트(재사용 가능한 지침 템플릿)와 리소스(실시간 데이터 엔드포인트)를 등록합니다.
프롬프트 (src/prompts/)
이름 | 용도 |
| 엔티티에 대한 OData 쿼리 구성을 위한 가이드 |
| 지정된 엔티티의 하위 양식 계층 구조를 설명합니다 |
| 생성, 업데이트, 삭제 작업을 안내합니다 |
| 날짜 필터의 중요한 규칙 — ISO 형식, 연산자 검증 |
| 문서화된 404/501/400 패턴 및 해결 방법 |
|
|
리소스 (src/resources/)
URI | 용도 |
| REST 지원 엔티티의 실시간 목록 ( |
| 특정 엔티티의 스키마 (템플릿 URI) |
| 바로 사용 가능한 쿼리 예제 라이브러리 |
| 하위 양식 패턴 및 작업에 대한 참조 가이드 |
예제 도구 호출
고객 1011의 가장 최근 판매 주문 3건을 쿼리합니다 — 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는 날짜를 UTC
Z가 아닌 시간대 오프셋이 포함된 ISO 8601 형식(예:2025-07-15T00:00:00+03:00)으로 반환합니다. 날짜 필터에는 ISO-Z 형식이 아닌CURDATE ge 2025-01-01구문을 사용하세요.
배포
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는 사용자당 분당 100회 API 호출, 최대 10개의 병렬 요청, 호출당 3분 타임아웃으로 제한합니다. 가능한 경우 에이전트가 작업을 일괄 처리하도록 설계하세요.
응답 상한 — MAXFORMLINES
Priority는 $top과 관계없이 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 모듈 (
"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