Connect your AI Agents to Concur in minutes

Available tools
list_report_expenses
List all expense entries on a report. Concur v4 returns the full set (no pagination). Use get_report_expense for full details on a specific entry.
get_report_expense
Get a single expense entry on a report including amount, date, location, and custom fields. Accepts either the v4 hex expense_id or the v3-style ID returned by create_report_expense.
list_expense_itemizations
List itemizations on an expense entry. Itemizations split a single charge across multiple expense types or amounts. Accepts either the v4 hex expense_id or the v3-style ID returned by create_report_expense.
update_report_expense
Update a single expense entry on a report. COMPANY-TOKEN ONLY: user OAuth tokens are rejected. Accepts either the v4 hex expense_id or the v3-style ID from create_report_expense. Cannot set comments — Concur exposes those as a separate sub-resource.
delete_report_expense
Permanently delete an expense entry from a report. Cannot be undone. Accepts either the v4 hex expense_id or the v3-style ID returned by create_report_expense.
create_report_expense
Create a new expense entry on an existing report. USER-TOKEN ONLY: company JWTs are rejected. Returns both expense_id (v3) and v4_expense_id; pass v4_expense_id to v4 read/update/delete tools and expense_id to attach_receipt_to_expense.
attach_receipt_to_expense
Upload a receipt image and attach it directly to an expense entry. Image is sent as base64 in file_content with the matching MIME in media_type. Max 5 MB.
get_expense_form_fields
Get form-field metadata for an expense entry (custom fields by expense type). Pass expense_type_id to filter. Accepts either the v4 hex expense_id or the v3-style ID returned by create_report_expense.
list_payment_types
List payment types available to a Concur user (e.g. 'Cash', 'Company Paid') via Expense Config v4. USER-TOKEN ONLY: company JWTs are rejected. Returns v4 short codes (e.g. 'CASH'); pass these directly to create_report_expense, which auto-resolves to the v3 tenant-encoded form. Requires the expense.config.paymenttypes.restricted.read scope.
get_current_user
Get the authenticated user or company profile from /profile/v1/me. Returns the principal record (extension fields pass through).
get_principal
Get a Concur principal (user or company) by ID via /profile/v1/principals/{id}. Use the JWT 'sub' claim or the id from get_current_user.
create_quick_expense
Create a quick expense (no image) for the authenticated user. Required: expense_type_id, transaction_amount, transaction_date.
create_quick_expense_with_image
Create a quick expense and attach a receipt image in one call. Send the image as base64 in file_content with the matching MIME in media_type. Max 50 MB.
upload_receipt
Upload an e-receipt (image + structured metadata) to the user's receipt library. The connector builds the Concur general-receipt JSON from flat inputs. Image is base64 in file_content. Max 25 MB.
upload_receipt_image_only
Upload an image-only receipt to the user's receipt library. Image is sent as base64 in file_content with media_type. Max 25 MB. Requires the receipts.write scope.
list_user_receipts
List e-receipts for the authenticated user. Returns the full set (Concur v4 does not paginate this endpoint).
list_image_only_receipts
List image-only receipts in the user's receipt library.
get_receipt
Get an e-receipt by ID.
get_image_only_receipt
Get an image-only receipt's metadata by ID. Use list_image_only_receipts to find IDs. Requires the receipts.read scope.
get_receipt_status
Get the processing status of a submitted receipt by ID. Useful for tracking async OCR/validation.
download_receipt
Download an e-receipt's image bytes by ID. Returns base64 file_content plus its media_type. Use list_user_receipts or get_receipt to find IDs. Requires the receipts.read scope.
download_image_only_receipt
Download an image-only receipt's image bytes by ID. Returns base64 file_content plus its media_type. Use list_image_only_receipts to find IDs. Requires the receipts.read scope.
get_report
Get an expense report by ID. Returns name, status, totals, and policy custom fields. Use list_reports_to_approve to find pending reports as an approver.
create_report
Create a new (unsubmitted) expense report. policy_id MUST be a v4 ID: first call list_reports to find any existing report, then call get_report on it and use the policy_id from that v4 response. Do NOT pass policy_id_v3 from list_reports — v4 will reject it.
update_report
Update fields on an unsubmitted report. report_source is required by Concur (one of OTHER/SE/UI/EA/TR/MOB; use 'OTHER' for API callers).
update_report_as_company
Update a report using a company-level JWT. COMPANY-TOKEN ONLY: user OAuth tokens are rejected. Works on any report regardless of submission state. Limited to business_purpose, comment, name, paper-receipts flag, and custom_data.
delete_report
Permanently delete an expense report. Cannot be undone. Use get_report first to confirm the right ID.
list_reports
List the authenticated user's expense reports. Supports cursor pagination via offset/limit and server-side filters (approval_status, payment_status, modified_after). Pass user_login_id to filter by login ID or 'ALL' for all users (company token only).
list_reports_to_approve
List reports the authenticated user can approve as an approver or delegate. Concur v4 returns the full set (no pagination).
get_report_form_fields
Get policy-driven form-field metadata for a report (data type, required flag, access level). Pass policy_id for the target policy if it differs from the report's current one.
list_report_exceptions
List policy exceptions on a report. Returns header-level (expense_id None) and per-expense items. is_blocking=true means red-flag (prevents submit_report). Call this when submit_report fails or when hasBlockingExceptions is true.
list_users
List Concur users in the company via Identity v4.1 (SCIM). Admin-only: caller must have the User/Company Administrator role; non-admin tokens get 401 even with identity.user.ids.read. Use search_users for filtered queries. The returned id is the UUID to use as user_id in other tools.
search_users
Search Concur users via Identity v4.1 SCIM (POST /Users/.search). Filter by userName, name, emails, active status, or raw SCIM expression. Admin-only: caller must have the User/Company Administrator role; non-admin tokens get 401 even with the read scopes. Use list_users for unfiltered listing.
validate_credential
Validate the connected Concur account by fetching the authenticated principal's profile.
submit_report
Submit an unsubmitted expense report for approval. The authenticated user must own the report (TRAVELER context). If submission fails with red-flag exceptions, call list_report_exceptions to see which rules are blocking, fix the entries, and retry.
approve_report
Approve a submitted expense report (MANAGER context). Pass user_id to approve as a delegate. Use list_reports_to_approve to find pending IDs.
sendback_report
Send a submitted report back to the submitter for changes (MANAGER context). Comment is required. Pass user_id to send back as a delegate.

How to set up Merge Agent Handler
In an mcp.json file, add the configuration below, and restart Cursor.
Learn more in the official documentation ↗
1{
2 "mcpServers": {
3 "agent-handler": {
4 "url": "https://ah-api-develop.merge.dev/api/v1/tool-packs/{TOOL_PACK_ID}/registered-users/{REGISTERED_USER_ID}/mcp",
5 "headers": {
6 "Authorization": "Bearer yMt*****"
7 }
8 }
9 }
10}
11Open your Claude Desktop configuration file and add the server configuration below. You'll also need to restart the application for the changes to take effect.
Make sure Claude is using the Node v20+.
Learn more in the official documentation ↗
1{
2 "mcpServers": {
3 "agent-handler": {
4 "command": "npx",
5 "args": [
6 "-y",
7 "mcp-remote@latest",
8 "https://ah-api-develop.merge.dev/api/v1/tool-packs/{TOOL_PACK_ID}/registered-users/{REGISTERED_USER_ID}/mcp",
9 "--header",
10 "Authorization: Bearer ${AUTH_TOKEN}"
11 ],
12 "env": {
13 "AUTH_TOKEN": "yMt*****"
14 }
15 }
16 }
17}Open your Windsurf MCP configuration file and add the server configuration below.
Click on the refresh button in the top right of the Manage MCP server page or in the top right of the chat box in the box icon.
Learn more in the official documentation ↗
1{
2 "mcpServers": {
3 "agent-handler": {
4 "command": "npx",
5 "args": [
6 "-y",
7 "mcp-remote@latest",
8 "https://ah-api.merge.dev/api/v1/tool-packs/<tool-pack-id>/registered-users/<registered-user-id>/mcp",
9 "--header",
10 "Authorization: Bearer ${AUTH_TOKEN}"
11 ],
12 "env": {
13 "AUTH_TOKEN": "<ah-production-access-key>"
14 }
15 }
16 }
17 }In Command Palette (Cmd+Shift+P on macOS, Ctrl+Shift+P on Windows), run "MCP: Open User Configuration".
You can then add the configuration below and press "start" right under servers. Enter the auth token when prompted.
Learn more in the official documentation ↗
1{
2 "inputs": [
3 {
4 "type": "promptString",
5 "id": "agent-handler-auth",
6 "description": "Agent Handler AUTH_TOKEN", // "yMt*****" when prompt
7 "password": true
8 }
9 ],
10 "servers": {
11 "agent-handler": {
12 "type": "stdio",
13 "command": "npx",
14 "args": [
15 "-y",
16 "mcp-remote@latest",
17 "https://ah-api-develop.merge.dev/api/v1/tool-packs/{TOOL_PACK_ID}/registered-users/{REGISTERED_USER_ID}/mcp",
18 "--header",
19 "Authorization: Bearer ${input:agent-handler-auth}"
20 ]
21 }
22 }
23}FAQs on using Merge's Concur MCP server
FAQs on using Merge's Concur MCP server
Ready to try it out?
Whether you're an engineer experimenting with agents or a product manager looking to add tools, you can get started for free now












