concur-mcp について
concur-mcpは、ClaudeなどのMCPクライアントをSAP Concurに接続する非公式のMCPサーバーです。ログイン済みブラウザーセッションを使い、経費レポート、経費、領収書、出張を扱えます。書き込みには毎回確認が必要です。
主な機能
- 01レポート、経費、出張の参照
- 02レポートと経費の作成・更新
- 03領収書のダウンロード、アップロード、添付
- 04利用可能な経費と領収書の確認
- 05変更の書き込み前に毎回確認
活用シーン
- 01未提出レポートと提出を妨げる例外の確認
- 02カード取引をレポートに追加
- 03領収書のアップロードと添付
- 04今後の出張予定の確認
MCP 対応
SAP Concurのセッション、レポート、経費、領収書、出張を操作するツールをMCPクライアントに提供します。書き込みには確認が必要です。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y @chrischall/concur-mcpCONCUR_DCConcur datacenter from your signed-in tab's host (e.g. us2, eu2). Defaults to us2.CONCUR_WS_PORTfetchproxy bridge concentrator port. Defaults to the fleet-shared 37149.CONCUR_OUTPUT_DIRWhere `concur_get_receipt` saves downloaded receipts (never overwriting an existing file). Defaults to ~/Downloads/concur-mcp.CONCUR_UPLOAD_ROOTSThe only folders `concur_upload_receipt` will read from (a path-delimiter-separated list; `~` expanded). Hosted (with `MCP_DATA_DIR` set) the default is `$MCP_DATA_DIR/uploads`. Defaults to ~/Downloads, ~/Documents and ~/Desktop, plus the working directory when it is a folder inside your home directory (never `/` or home itself).CONCUR_INLINE_RECEIPTS`true` makes `concur_get_receipt` return the image in the result instead of writing a file. Off locally, on when hosted.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
39掲載時のツール一覧 · 1 週間前に更新
このツールにパラメーターはありません。
詳細
SAP Concur MCP
Claude を SAP Concur に接続する Model Context Protocol サーバーです。経費精算レポート、レポートに含まれる経費、利用可能な(未割り当ての)経費、領収書、Concur Travel の出張を読み取り、書き込みできます。すべての書き込みには確認が必要です。
警告
AI 開発プロジェクトです。 このコードベースは Claude によって全面的に構築され、現在も積極的に保守されています。人間による実装の監査は行われていません。使用前に、すべてのコードとツールの権限を確認してください。
注意
非公式であり、サポート対象外です。 このサーバーは、Concur の文書化されたパートナー API を使用しません。Concur のウェブアプリ自体が使用する内部 GraphQL API を呼び出し、ご自身のサインイン済みブラウザーセッションで認証します。予告なく動作しなくなる可能性があり、自動化された使用は SAP Concur または勤務先の利用規約に抵触する場合があります。ご自身のアカウントで、ご自身の責任においてのみ使用してください。
できること
Claude に次のような質問ができます。
- 「未提出の Concur レポートはどれで、何が提出を妨げていますか?」
- 「まだレポートに含まれていないカード取引を表示して。」
- 「『Austin offsite』というレポートを作成して、先週の Uber とホテルの請求を追加して。」
- 「~/Downloads/dinner.pdf をアップロードして、夕食の経費に添付して。」
- 「次の出張はいつ出発で、どのホテルに泊まりますか?」
必要条件
- Claude Desktop、Claude Code、または任意の MCP ホスト
- Node.js 22.5 以降
- ContextMint Bridge ブラウザー拡張機能と、サインイン済みの Concur タブ(
https://<dc>.concursolutions.com/…)
インストール
Claude Code プラグイン
claude plugin marketplace add chrischall/concur-mcp
claude plugin install concur@chrischall
任意の MCP ホスト(npx)
{
"mcpServers": {
"concur": {
"command": "npx",
"args": ["-y", "@chrischall/concur-mcp"],
"env": { "CONCUR_DC": "us2" }
}
}
}
Claude Desktop(.mcpb)
最新リリースから .mcpb バンドルをインストールしてください。インストーラーでデータセンターを指定します(デフォルトは us2 です)。
認証の仕組み
Concur のウェブアプリは、ページ自体からは読み取れない HttpOnly の JWT Cookie を使って API 呼び出しを認証します。このサーバーは、fetchproxy ブリッジを使用して、サインイン済みの Concur タブからセッション Cookie を 3 つだけ読み取ります。JWT に加え、Concur のレガシーセッション Cookie である OTSESSIONAABQRD と OTSESSIONAABQRN です。その後の API 呼び出しはすべて Node から実行し、Authorization: Bearer <jwt> と、タブに存在した OTSESSION Cookie を含む Cookie ヘッダーを送信します。Concur のレガシーサービスが引き続き提供している部分(レポートキー、通貨、利用可能な領収書、権限)は、これらの Cookie がないとエラーを返します。Cookie はメモリ内だけに保持され、エラーやログに出力されることはありません。ホームディレクトリに書き込まれるのは、ブリッジのペアリング ID だけです。
トークンの有効期間は 60 分です。トークンの有効期限が切れる 2 分前になると、サーバーはタブから Cookie をまとめて読み直します。また、401 が発生した場合にも一度だけ読み直します(呼び出しごとに読み直しと再試行を 1 回ずつ行い、ループはしません)。古くなった OTSESSION Cookie と同じ原因で読み取りに失敗した場合も、同じく一度だけ読み直して再試行します。Concur はタブが開いている間、Cookie を最新の状態に保つため、ツールを使用する間はサインイン済みの Concur タブを開いたままにしてください。concur_healthcheck は、トークンの取得元、残りの有効時間(分)、レガシーセッション Cookie が見つかったかどうかを報告します。Cookie の値は決して報告しません。
以前のビルドからアップグレードする場合:ブリッジのスコープが
JWTのみからJWTと 2 つの OTSESSION Cookie に拡張されました。ペアリングの許可はスコープごとに行われるため、すでにペアリング済みのサーバーでは一度だけ再承認が必要です。次の呼び出しで、新しいペアコード(またはスコープ変更の通知)が返されるので、ContextMint Bridge のポップアップで承認してください。
ペアリング(初回のみ)
- ContextMint Bridge をインストールし(Chrome の場合は、リリースの ZIP を展開して読み込みます)、そのブラウザーで Concur にサインインします。
- Claude に
concur_healthcheckを実行するよう依頼します。最初の呼び出しでペアコードが返されます。 - ContextMint Bridge のポップアップでコードを承認します。信頼設定は再起動後も保持されます(
~/.fetchproxy/identity/に保存されます)。
複数のブラウザーを使っていますか? ContextMint Bridge が複数のブラウザーにインストールされている場合、各ブラウザーは同じローカルポートに接続し、どのブラウザーでもペアコードを承認できます。Concur セッションがあるブラウザーで承認してください。サーバーは承認した拡張機能を固定するため、そのブラウザーのタブだけが Cookie を提供できます。標準エラー出力に表示される refusing an extension whose identity is not the one this MCP paired with のような行は、別のブラウザーが拒否されていることを示すもので、問題ありません。
別のブラウザーで誤ってペアリングした場合、またはブラウザーを変更した場合:ContextMint Bridge のポップアップで concur-mcp の許可を取り消し、@fetchproxy/cli の fpx trust clear concur-mcp を実行してサーバーが固定した拡張機能を解除するか、~/.fetchproxy/identity/concur-mcp.extension-trust.json を削除します。サーバーを再起動し、正しいブラウザーから再度ペアリングしてください。
設定
| 環境変数 | デフォルト | 用途 |
|---|---|---|
CONCUR_DC | us2 | データセンターです。サインイン済みのタブのホスト名の最初のラベルです(us2.concursolutions.com の場合は us2、eu2 など)。セッショントークンの発行者と一致する必要があります。一致しない場合、使用すべき値を示すエラーが発生し、すべての呼び出しが失敗します。 |
CONCUR_WS_PORT | 37149 | fetchproxy ブリッジのポートです。fetchproxy フリート全体と ContextMint Bridge は 37149 を共有しています。ローカルテスト時、またはホストから登録ごとのポートが設定される場合にのみ上書きしてください。 |
CONCUR_OUTPUT_DIR | ~/Downloads/concur-mcp | concur_get_receipt がダウンロードした領収書を保存する場所です(既存のファイルは上書きしません)。 |
CONCUR_UPLOAD_ROOTS | ~/Downloads、~/Documents、~/Desktop、およびホームディレクトリ内のフォルダーである場合は現在の作業ディレクトリ(/ とホームディレクトリ自体は含みません。Claude Desktop はサーバーを / で起動するためです) | concur_upload_receipt が読み取る唯一のフォルダーです(パス区切り文字で区切られたリストで、~ は展開されます)。ホスト環境(MCP_DATA_DIR が設定されている場合)では、デフォルトは $MCP_DATA_DIR/uploads です。 |
CONCUR_INLINE_RECEIPTS | ローカルではオフ、ホスト環境ではオン | true にすると、concur_get_receipt はファイルを書き込む代わりに、結果内で画像を返します。 |
MCP_USER_TZ | サーバーのタイムゾーン | IANA タイムゾーン(例:America/New_York)です。concur_create_report が reportDate のデフォルト値を設定する際の「今日」の判定に使われます。ホスト環境では設定してください。ホスト環境のサーバーは UTC で動作するため、設定しないと夕方に作成したレポートの日付が翌日になります。 |
CONCUR_DEBUG | オフ | ブリッジの役割とライフサイクルを stderr に記録します。 |
MCP_CONFIRM_MODE | ask-user | 確認プロンプトを表示できないクライアントで書き込みを行う場合の動作です。詳しくは以下を参照してください。 |
MCP_CONFIRM_ELICITATION | on | off にすると確認プロンプトを一切表示しません。そのため、プロンプトを宣言していても表示しないクライアントを含め、すべてのクライアントで MCP_CONFIRM_MODE の動作が適用されます。 |
書き込みの確認
Concur の内容を変更する(または誰かにメールを送信する)すべてのツールでは、確認が必要です。
- MCP elicitation に対応しているクライアントは、送信内容を正確に説明した確認プロンプトを表示します。
- **それ以外(claude.ai、Claude Desktop)**では、最初の呼び出しでは変更は行われません。送信される内容のプレビューと、1回限りで有効期限の短い
confirmTokenが返されます。このトークンを含めて再度呼び出した場合にのみ書き込みが行われます。途中でリクエスト内容が変更された場合、トークンは拒否されます。
MCP_CONFIRM_MODE は、そのトークンを使用できる主体を決定します。
| 値 | 動作 |
|---|---|
ask-user(デフォルト) | モデルはプレビューを表示し、チャットでユーザーの承認を得てからトークンを再利用する必要があります。 |
auto | モデルはプレビューを確認した後、自身でトークンを使用できます。 |
refuse | 確認プロンプトのないクライアントでは、書き込みが拒否されます。認識されない値は refuse として扱われます。 |
Concur から返されるテキスト(ベンダー名、コメント、出張の詳細、メールなど)は信頼できないデータとして扱われ、書き込みを許可することはできません。
ツール
読み取りツールの多くは view: compact | full | raw を受け取ります(デフォルトは compact)。compact は通常不要なフィールドを省略し、full はすべてのフィールドを含めます。raw は、Concur の応答を加工せずに返します。
セッションと検索
| ツール | 機能 |
|---|---|
concur_healthcheck | トークンの取得元、API がトークンを受け付けたかどうか、往復時間、有効期限までの残り時間(分)を確認します |
concur_whoami | Concur のユーザー ID、データセンター、トークンの残り時間(分)、有効な機能を確認します |
concur_list_expense_types | レポートのポリシーで許可されている経費タイプ(ID、名前、グループ)を取得します |
concur_list_payment_types | 経費に指定できる支払タイプ(現金、会社カードなど)を取得します |
concur_list_currencies | Concur が受け付ける通貨を取得します。任意で絞り込みもできます |
concur_search_locations | 都市別の経費の場所を検索します(国や行政区画による絞り込みも可能です) |
レポートと経費(読み取り)
| ツール | 説明 |
|---|---|
concur_list_reports | ステータス(ALL、ACTIVE、UNSUBMITTED、SENT_FOR_PAYMENT)と日付範囲でレポートを一覧表示します |
concur_get_report | 1件のレポートのヘッダー、すべての経費明細、および例外(blocking は提出を妨げます)を取得します |
concur_get_report_timeline | レポートのタイムライン(コメントとワークフローイベント)および監査証跡を取得します |
concur_get_expense | 1件の経費のフォームフィールド(ラベル別)、明細項目、領収書、コメント、例外を取得します |
concur_list_available_expenses | まだレポートに含まれていないカード取引、電子領収書、モバイルで取り込んだデータを一覧表示します |
レポートと経費(書き込み — すべて確認が必要)
| ツール | 説明 | 元に戻せますか? |
|---|---|---|
concur_create_report | 未提出のレポートを作成します | はい(concur_delete_report) |
concur_update_report | ヘッダーフィールドを変更します。変更された項目のみ送信します | はい |
concur_delete_report | 未提出のレポートと、レポートに含まれるすべての経費を削除します | いいえ |
concur_add_report_comment | 承認者に表示されるコメントを追加します | いいえ(コメントは削除できません) |
concur_submit_report | レポートを承認者に送信します | いいえ — 担当者に届きます。承認前であれば concur_recall_report で取り戻せます |
concur_recall_report | 提出済みで未承認のレポートを取り戻します | はい |
concur_create_expense | 未提出のレポートに経費を追加します。編集可能なフォームフィールドをラベルで指定できます(カスタムフィールド、チケット番号、出発地/目的地など)。外貨の場合、その日付の Concur の為替レートが適用されます | はい |
concur_update_expense | フォームフィールドや為替レートを含む経費を変更します。変更された項目のみ送信します | はい |
concur_delete_expenses | レポートから経費を削除します(カード取引は利用可能な経費に戻ります) | いいえ |
concur_copy_expense | 経費を複製します | はい |
concur_move_available_expenses_to_report | 利用可能な経費をレポートに移動します | いいえ(Concur には元に戻す機能がありません) |
concur_delete_available_expenses | 利用可能な経費を削除します | いいえ |
同席者
| ツール | 説明 | 元に戻せますか? |
|---|---|---|
concur_search_attendees | 名前またはメールアドレスで同席者ディレクトリ(同僚、保存済みのゲスト)を検索します | 読み取り |
concur_set_attendees | 経費の同席者リストを置き換えます(デフォルトでは最初に自分が追加されます)。金額は均等に分割されます — 確認が必要 | いいえ(以前のリストを取得したり、消去したりするツールはありません) |
領収書
| ツール | 説明 | 確認が必要ですか? |
|---|---|---|
concur_list_available_receipts | 領収書ストアにある、経費に添付されていない領収書画像を一覧表示します | 読み取り |
concur_get_receipt | 領収書画像を CONCUR_OUTPUT_DIR にダウンロードします(またはインラインで表示します) | ローカルファイルのみ |
concur_upload_receipt | 許可されたフォルダーから png/jpg/pdf(≤ 25 MB)をアップロードします | はい |
concur_attach_receipt | 領収書が添付されていない経費に、保存済みの画像を添付します | はい |
concur_append_receipt | 保存済みの画像を、経費の領収書の追加ページとして加えます | はい |
concur_detach_receipt | 経費から画像を取り外します | はい |
concur_add_missing_receipt_declaration | 領収書がない経費について、領収書紛失申告書(宣誓書)を追加します — 領収書がないことを証明します。プレビューには、ポリシーに定められた申告文が表示されます。これを削除するツールはありません(領収書を添付すると置き換えられます) | はい |
concur_delete_receipt | 添付されていない領収書画像を削除します — 元に戻せません | はい |
旅行
| ツール | 説明 |
|---|---|
concur_list_trips | 旅行を一覧表示します(デフォルトでは今後の旅行。過去の旅行またはすべての旅行も指定可能)。フィルターを適用できます |
concur_get_trip | 1件の旅行と、航空券、ホテル、レンタカー、鉄道の予約情報を取得します |
concur_get_trip_history | 旅行の履歴(変更、承認、旅程メール)を取得します |
concur_send_itinerary | 旅行の旅程をメールで送信します — 実際にメールを送信します。確認が必要です |
制限を回避する手段
| ツール | 説明 |
|---|---|
concur_list_operations | Concur のウェブアプリが使用する GraphQL オペレーション — 名前、エンドポイント、目的、およびどの専用ツールがすでに実行するか |
concur_graphql_query | 読み取り専用のクエリ(spend または cds エンドポイント)を直接実行します。書き込みの可能性がある操作は拒否します |
concur_graphql_mutation | 全ドキュメントをプレビューに表示し、確認を必須として、直接ミューテーションを実行します。「対象外」に記載されたオペレーションは拒否します。これには submit も含まれます(concur_submit_report を使用してください) |
対象外
これらの機能は Concur にありますが、意図的に実装していません。未実装であることは拒否されることを意味しません。生の回避手段では、ガードが以下の項目を指定していない限り、それらにもアクセスできます。
concur_graphql_mutation が拒否するオペレーション(オペレーション名と、ウェブアプリがテキストで選択するフィールドの両方で照合するため、名前の変更やエイリアス化では通過できません):processApproval、updateWorkItemStatus、startSearch、saveBookingSelections、holdTrip、confirmTrip、commitChange、tryCancelTripOrBooking、SubmitExpenseReport(concur_submit_report を使用してください)。
- 承認 — 他の人のレポートを承認、または差し戻す操作(
contextRole: MANAGER)。未実装:approvalsportal.aspページ、GetApproversListおよびloadApprovalDetailsの読み取り、UpdateTimelineWorkflowの呼び出し。拒否対象:CDS のprocessApprovalとupdateWorkItemStatus(updateDelegatesDashboardWorkItemStatus)。このサーバーはお客様自身のデータのみを扱います。 - カード取引の管理 — カード口座のページとそのオペレーション:
/Expense/Client/cardtransactions.asp、GetCardAccounts、GetCardTransaction、MoveCCTransactionsToReport、CreateCBSReportAndMoveCCTransactionsToReport、RefreshYodleeTransactions。(すでに利用可能な経費として表示されているカード利用明細は対象です — 一覧表示、レポートへの移動、削除が可能です。) - 旅行の予約またはキャンセル — 検索、料金確認、予約、保留、確定、キャンセル(
startSearch、saveBookingSelections、holdTrip、confirmTrip、commitChange、tryCancelTripOrBooking)。旅程のメール送信を除き、旅行情報は読み取り専用です。
開発
npm install
npm run build # tsc → dist/, then esbuild → dist/bundle.js (the .mcpb entry)
npm test # typecheck + vitest
npm run test:coverage
この実装の基盤となる API サーフェス — ホスト、認証、使用するすべてのオペレーション、ライブ環境での検証内容 — は docs/CONCUR-API.md に記載されています。オペレーションの原文は docs/api/ にあります。
ライセンス
MIT
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。