SAP Concur Expense Access (fpx)

一项只读 Openclaw Skills 集成,可通过用户已认证的浏览器会话查询 SAP Concur 费用报告和未分配费用。

chrischall
2026年10月10日
0 收藏
40 下载

安装与下载

1 ClawHub CLI

从源直接安装技能的最快方式。

npx clawhub@latest install concur-fpx

2 手动安装

将技能文件夹复制到以下位置之一

全局模式 ~/.openclaw/skills/
工作区 {'/skills/'}

优先级:工作区 › 全局 › 内置

3 提示词安装

将此提示词复制到 Openclaw 即可自动安装。

请帮我使用 Clawhub 安装 skill-concur-fpx。如果尚未安装 Clawhub,请先安装(npm i -g clawhub)。

更倾向于下载?

获取包含原生技能文件的ZIP压缩包。

下载技能 (.zip)

基本信息

名称 SAP Concur Expense Access (fpx)
Slug concur-fpx
创建者 chrischall
创建时间 2026-10-10 05:35:41
更新时间 2026-10-10 05:35:41
收藏数 0
使用量 40
浏览量 4

安装指南

  1. ClawHub CLI 从源直接安装技能的最快方式。
    npx clawhub@latest install concur-fpx
  2. 手动安装 将技能文件夹复制到以下位置之一
    全局模式
    ~/.openclaw/skills/
    工作区
    /skills/
    优先级:工作区 > 本地 > 内置
  3. 提示词安装 将此提示词复制到 OpenClaw 即可自动安装。
    请帮我使用 Clawhub 安装 concur-fpx。如果尚未安装 Clawhub,请先安装(npm i -g clawhub)。
    更倾向于下载?
    获取包含原生技能文件的ZIP压缩包。
    下载技能 (.zip)

什么是

SAP Concur Expense Access 技能让 AI 代理通过 fpx CLI 和 Concur 的 GraphQL API,从已登录的 Concur 浏览器标签页获取费用数据。它可访问费用报告、报告明细、供应商、费用类型、金额、收据、异常、报销状态、付款状态,以及尚未分配到报告的费用。
该技能专为安全的只读工作流设计,通过用户当前的 Concur 会话和 ContextMint Bridge 路由请求,而不是使用 bearer tokens 或直接 API 身份验证。因此,它适用于需要准确且经会话授权的财务数据、又不希望在集成中接入写入操作的 Openclaw Skills 工作流。

应用场景

检查进行中、未提交或已发送付款的费用报告状态。
查看报告标题和每笔费用条目,包括供应商、类别、金额、收据和异常。
查找可用但尚未分配到报告的公司卡费用或收据费用。
确认已登录的 Concur 用户,并获取详细报告查询所需的用户 ID。
按状态和日期范围筛选报告,以供报销或财务审核。
将 Concur GraphQL 响应传递给
jq
,用于基于 shell 的报告和自动化。
构建只读 Openclaw Skills 助理,在不修改 Concur 数据的情况下回答员工费用相关问题。

工作原理

用户安装 fpx CLI、创建 Concur 配置,并将 fpx 与含有已认证 Concur 会话的浏览器中的 ContextMint Bridge 配对。
技能根据已登录的标签页确定 Concur 数据中心,使用 CONCUR_DC 或默认值 us2。
每个请求都通过已登录的 Concur 浏览器标签页并使用 --via-tab 路由,使请求能够使用会话 cookies 并通过 Concur 的浏览器和机器人管理控制。
scripts/concur-gql 包装程序从 queries/ 加载经过验证的 GraphQL 查询,或接受 .graphql 文件路径,然后在 stdout 上返回 GraphQL JSON。
必要时,代理运行 whoami,以获取已登录用户的 UUID,然后再请求详细报告条目。
代理通过分页、状态和日期范围变量查询报告、单个报告或可用费用。
检查响应中的 .errors[] 后,才会信任 .data,因为 GraphQL 失败可能以 HTTP 200 返回。
可使用 jq 转换结果;fpx 退出代码则用于区分配对失败、机器人拦截和上游身份验证错误。

配置指南

安装 fpx CLI 并为 Concur 域创建配置:
npm install -g @fetchproxy/cli
fpx profile add concur --domain concursolutions.com
fpx pair -p concur
配对前,在 Chrome 中安装并运行 ContextMint Bridge,然后打开已登录的 SAP Concur 标签页,例如 https://us2.concursolutions.com/...。在保有 Concur 会话的浏览器中批准配对码。如果有多个浏览器连接到 ContextMint Bridge,请清除现有信任并在正确的浏览器中重新配对:
fpx trust clear fpx-concur
fpx pair -p concur
如果已登录的 Concur 主机使用的不是 us2 数据中心,请设置 CONCUR_DC:
export CONCUR_DC=eu2
在已安装技能的目录中运行核心包装程序。以下示例获取所有报告并使用 jq 格式化列表:
G=~/.claude/skills/concur-fpx/scripts/concur-gql
$G reports '{"status":"ALL"}' | jq '.data.employee.reportsForUser.list'
当请求开始返回退出代码 4 或 HTTP 401 时,重新加载 Concur 标签页或重新登录。退出代码 2 表示 Bridge 不可用或配对仍在等待中;退出代码 3 表示 Akamai 或其他机器人管理机制拦截了请求。
SAP Concur Expense Access (fpx) 数据架构与分类体系
该技能采用精简的面向查询的文件布局,并返回原始 GraphQL JSON,而不会创建本地费用记录。
组件 用途 关键数据
scripts/concur-gql 执行 GraphQL 操作的 shell 包装程序 查询名称或 .graphql 路径、可选的 variables JSON、stdout 上的 JSON
queries/whoami 解析已登录的 Concur 身份 userId、角色
queries/reports 列出费用报告 状态、日期范围、页码、大小、报告列表、分页
queries/report 获取单份报告的详细信息 报告标题及所有报告条目,包括明细项目详情
queries/available-expenses 查找未分配到报告的费用 分页的可用公司卡费用或收据费用
references/recipes.md 存放可直接运行的 jq 示例 shell 数据提取和格式化示例
references/operations.md 记录 Concur Web 应用使用的操作 约 130 个查询和 50 个 mutation,供参考;技能未接入写入功能
支持的查询变量包括 ALL、ACTIVE、UNSUBMITTED 和 SENT_FOR_PAYMENT 等 status 值;使用 YYYY-MM-DD 的日期范围;以及 page 和 size 等分页字段。获取详细报告需要使用 whoami 返回的真实 userId,因为报告条目解析器会拒绝空的用户 ID。
GraphQL 响应可能在 .data 旁边或取而代之包含 .errors[]。使用结果前,请检查 extensions.dataSource 和 response.status 等错误扩展信息。身份验证和传输状态通过 fpx 退出代码表示,而不会保存为技能元数据。

高级特性

使用 ContextMint Bridge 和会话 cookies 进行浏览器会话身份验证,无需 bearer token。
CONCUR_DC
实现数据中心感知路由,支持
us2
、
eu2
和其他 Concur 部署主机。
对不直接提供浏览器页面的 API 主机使用 --via-tab 中继行为。
先解析身份:运行一次
whoami
,并在详细报告查询中重复使用返回的 UUID。
按报告状态、日期范围、页码和每页大小进行分页和筛选。
shell 原生 JSON 输出,可与
jq
、脚本、CI 风格检查及其他 Openclaw Skills 自动化集成。
使用已验证的实时 GraphQL 查询并禁用 introspection,减少对未记录操作发现机制的依赖。
针对 HTTP 200 GraphQL 错误、配对失败、机器人拦截、会话过期和上游非 2xx 响应进行防御性错误处理。
采用只读设计,仅提供费用报告读取功能,不连接约 50 个已记录的 mutation 操作。


name: concur-fpx description: "Read SAP Concur expense data from a shell — your expense reports, each report's line items (vendor, type, amounts, receipts, exceptions), and available expenses not yet on a report — through the user's signed-in Concur browser tab with the fpx CLI. Use when asked about Concur expenses, expense reports, reimbursement/payment status, what's unsubmitted, or unassigned card/receipt expenses."

SAP Concur access (fpx)

Concur's web app talks to a GraphQL API at https://www-.api.concursolutions.com/spend-graphql/graphql, authed only by the browser's session cookies (credentials: include, no bearer header) and fronted by Akamai bot management. So every call routes through the user's signed-in Concur tab with fpx, relayed by the .concursolutions.com tab (--via-tab) because the API host serves no page of its own.

Read-only. Introspection is disabled; every query in queries/ was verified live.

One-time setup

npm install -g @fetchproxy/cli # provides `fpx`

fpx profile add concur --domain concursolutions.com
fpx pair -p concur # approve the pair code in ContextMint Bridge

Needs ContextMint Bridge in Chrome and an open, signed-in Concur tab (https://us2.concursolutions.com/…). Approve the pair code in the browser that holds the Concur session — if ContextMint Bridge runs in more than one browser, each one dials the same port and a code approved in the wrong one pins that browser. Fix: fpx trust clear fpx-concur, then pair again in the right one. Lines like refusing an extension whose identity is not the one this MCP paired with on stderr are the other browser being turned away; the call still works.

Datacenter: CONCUR_DC (default us2) — read it off the signed-in tab's host (us2.concursolutions.com → us2; eu2, …). Sessions are short: when calls start failing with exit 4 / HTTP 401, reload or sign back in to the tab.

Core call

scripts/concur-gql [vars-json] — is a file under queries/ by name (or any .graphql path). stdout is the GraphQL JSON, ready for jq.

G=~/.claude/skills/concur-fpx/scripts/concur-gql
$G reports '{"status":"ALL"}' | jq '.data.employee.reportsForUser.list'

Query Vars Returns

whoami — userId (UUID) + role
reports status (ALL/ACTIVE/UNSUBMITTED/SENT_FOR_PAYMENT), range {start,end} YYYY-MM-DD, page, size report list + pagination
report userId (required, from whoami), reportId report header + every entry
available-expenses page, size expenses not yet on a report

Resolve-first rule: employee(userId: "") resolves to the signed-in user, so most queries need no id — but reportEntriesDetails (inside report) rejects "" with a 400. Run whoami first and pass the real userId to report.

GraphQL errors arrive on HTTP 200 as .errors[] with the opaque message "An error occurred" — check .errors before trusting .data; the extensions.dataSource / response.status fields say which backend refused.

Exit codes (from fpx): 2 bridge down / pairing pending · 3 bot wall · 4 upstream non-2xx (401 = signed out).

Ready-to-run jq recipes: references/recipes.md. The full operation list the web app uses (≈130 queries, ≈50 mutations — writes deliberately not wired) is in references/operations.md, for extending this.

暂停

Recon