Skip to main content
Glama
priority-mcp

Priority REST API MCP Server

by priority-mcp

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 install

2. サンプルから.envを作成

cp .env.example .env

最低限、次の4つの変数を設定してください:

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

3. サーバーを起動

# 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が作成され、処理後に破棄されます。

エンドポイント

メソッド

目的

/mcp

POST

プライマリMCPエンドポイント(Streamable HTTP)

/sse

GET

SSEストリーム — SSE_ENABLED=trueが必要

/sse

POST

SSEクライアント向けJSON-RPCメッセージ

/health

GET

ヘルスチェック — バージョンとステータスを返す

/.well-known/oauth-authorization-server

GET

OAuth 2.1ディスカバリ(Claude Code ≥2.1.92で必須)

/authorize, /token, /register

GET/POST

OAuth 2.1 PKCEフロー — 自動承認される

注: OAuth 2.1エンドポイントは、Claude CodeのStreamable HTTP接続ハンドシェイクを満たすために存在します。すべてのリクエストを自動承認するため、実際のアクセス制御を目的としたものではありません。アクセス制御はODATA_MCP_TOKENによって処理されます。


認証

認証は2つの独立したレイヤーで動作します。

レイヤー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)は、PriorityのCSRF保護パターンに従い、最初のリクエストが拒否された場合にX-CSRF-Tokenヘッダーを自動的に取得して再試行します。

PRIORITY_APP_IDとPRIORITY_APP_KEYが設定されている場合、オプションのアプリケーションライセンスヘッダー(X-App-Id / X-App-Key)がすべてのPriorityリクエストとともに送信されます。


設定

.env.exampleを.envにコピーしてください。サーバーは.envを次の順序で検索します: ENV_FILE_PATH → ./mcp-servers/Priority-REST-API-MCP-Server/.env → ./.env。

必須

変数

説明

PRIORITY_BASE_URL

ODataルートURL — 形式: https://<host>/odata/Priority/<tabula.ini>/<company>/

PRIORITY_AUTH_TYPE

basic | pat | oauth2 | none

PRIORITY_USERNAME

ユーザー名 — AUTH_TYPE=basicの場合に必須

PRIORITY_PASSWORD

パスワード — AUTH_TYPE=basicの場合に必須

Priority認証(オプション)

変数

説明

ODATA_MCP_TOKEN

/mcpを保護するBearerトークン。未設定の場合はランダムなUUIDが使用される。

PRIORITY_PAT

パーソナルアクセストークン(AUTH_TYPE=patまたはoauth2の場合)

PRIORITY_APP_ID

アプリケーションライセンスID — X-App-Idヘッダーとして送信

PRIORITY_APP_KEY

アプリケーションライセンスキー — X-App-Keyヘッダーとして送信

PRIORITY_LANGUAGE

Accept-Languageヘッダーを上書き(例: en)

HTTPサーバー

変数

デフォルト

説明

HTTP_HOST

0.0.0.0

バインドアドレス

HTTP_PORT

3000

リッスンポート

SSE_ENABLED

false

/sseエンドポイントを有効化

タイムアウトとTLS

変数

デフォルト

説明

PRIORITY_HTTP_TIMEOUT_MS

30000

Priority API呼び出しの読み取りタイムアウト(ms)

MCP_WRITE_TIMEOUT

15000

POST/PATCH/DELETE操作のタイムアウト(ms)

MCP_PROC_TIMEOUT

45000

バッチ操作のタイムアウト(ms)

TLS_REJECT_UNAUTHORIZED

false

本番環境ではtrueに設定して自己署名証明書を拒否

デバッグ

変数

デフォルト

説明

LOG_LEVEL

INFO

DEBUGはすべてのリクエストとレスポンスをログ出力

MCP_DEBUG

false

完全なOData URL、パラメータ、結果件数を出力

PRIORITY_ENABLE_TRACE

false

すべてのPriorityリクエストにX-App-Trace: 1を追加

STRICT_DATA_INTEGRITY

true

空/モックのAPIレスポンスでエラーをスロー — テスト時のみ無効化

ENV_FILE_PATH

—

.envファイルのパスを上書き(サブモジュールデプロイメントに有用)


ツール

19個のツールはすべてsrc/tools/で定義され、src/tools/priorityTools.jsで登録されています。

システムとメタデータ

ツール

説明

パラメータ

version_get

Priorityサービスのバージョンとレスポンスヘッダーを取得

—

metadata_entities_list

すべてのODataエンティティセットを一覧表示。REST対応フォームのみにフィルタリング

apiOnly?, includeMetadata?

metadata_schema_get

サンプルレコードを取得してエンティティのフィールドスキーマを取得。サブフォーム名を親+$expandに自動リダイレクト

entity, sample?, top?

metadata_refresh

サーバー側メタデータキャッシュをクリアして更新。常に完全フラッシュを実行(既知の制限を参照)

entity?

クエリ

ツール

説明

パラメータ

entity_get

キーまたはルックアップで単一レコードを取得。オプションで$expandと$selectに対応

entity, key, lookup, select?, expand?

query_run

完全なfilter/select/top/skip/orderby/expand/countサポートでODataクエリを実行。取得後に日付フィルター結果を検証

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

safe_query_run

query_runと同様だが、最初に有効なフィールドを自動検出し、実行前に$selectフィールド名を検証 — 無効な列名による400エラーを防止

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

query_sum

オプションのフィルター付きでエンティティ全体の数値フィールドを合計。最初に$apply=aggregateを試行し、失敗した場合は完全なページングスキャンにフォールバック

entity, field?, filter?

作成 / 更新 / 削除

ツール

説明

パラメータ

entity_create

新しいレコードを作成。parentEntity + parentKey + subformによるサブフォーム作成に対応

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

entity_update

If-Match: *を使用してPATCHでレコードを更新。複合キーに対応

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

entity_delete

If-Match: *を使用してDELETEでレコードを削除。サブフォーム削除に対応

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

batch_operations

依存関係チェーン付きで複数のPOST/PATCH/DELETEを1つの$batchリクエストで実行

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

テキストフィールド

ツール

説明

パラメータ

entity_text_get

レコードの/Textサブリソースのリッチテキストコンテンツを取得

entity, key

entity_text_create

/Entity(Key)/Textに新しいテキストコンテンツをPOST

entity, key, textData

entity_text_update

/Entity(Key)/Textの既存テキストコンテンツをPATCH

entity, key, textData

添付ファイル

ツール

説明

パラメータ

entity_attachments_get

レコードの添付ファイルを一覧表示

entity, key

entity_attachments_upload

レコードの/Attachmentsサブリソースにmultipart/form-dataとしてファイルをアップロード。fileDataはbase64エンコードされている必要があります

entity, key, fileData, fileName, contentType?

設定とヘルプ

ツール

説明

パラメーター

instructions_get

完全な運用ガイドを返します: OData 構文、サブフォームパターン、スロットル制限、日付処理ルール、既知の障害パターン、アーキテクチャ例。馴染みのないエンティティを調査する際は、最初にこれを呼び出してください。

—

config_restflag_update

FORMLIMITED テーブルで RESTFLAG=Y または N を設定して、Priority フォームの REST API アクセスを有効または無効にします。

formName, restFlag, formType?


プロンプトとリソース

サーバーは MCP プロンプト (再利用可能な命令テンプレート) と リソース (ライブデータエンドポイント) を登録します。

プロンプト (src/prompts/)

名前

目的

query_priority_entity

エンティティに対する OData クエリを構築するためのガイド

explore_entity_relationships

指定されたエンティティのサブフォーム階層を説明します

modify_priority_data

作成、更新、削除の各操作をガイドします

date_handling_guide

日付フィルターの重要なルール — ISO 形式、演算子の検証

known_failure_patterns

文書化された 404/501/400 パターンとその回避策

pagination_guide

$top/$skip とカウントパターンについて説明します

リソース (src/resources/)

URI

目的

priority://entities/list

REST 対応の全エンティティのライブリスト (RESTFLAG=Y)

priority://entity-schema/{entity}

特定のエンティティのスキーマ (テンプレート URI)

priority://queries/common

すぐに使用できるクエリ例のライブラリ

priority://subforms/reference

サブフォームパターンと操作のリファレンスガイド


ツール呼び出しの例

顧客 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-mcp

Dockerfile は 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 を返す

Priority がエンティティスコープのキャッシュクリアリクエストを拒否するため、metadata_refresh は entity 引数を無視して常に完全なキャッシュフラッシュを実行します。

バッチ 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.0

  • HTTP サーバー: express ^4.21.1

  • HTTP クライアント: axios ^1.7.7

  • スキーマ検証: zod ^4.3.6

  • バンドラー: esbuild ^0.25.0 (npm run build 経由)

  • その他: cors、dotenv、form-data、uuid、http-errors

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    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 npm
    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
    B
    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.
    112 npm
    32
    MIT