关于 Oblio
Oblio MCP 服务将 AI 助手连接到罗马尼亚公司的 Oblio 账户,用于处理发票和形式发票。它会计算单据总额供确认,并要求先批准财务单据操作。
主要功能
- 01读取客户、产品、增值税率和发票
- 02开具发票与形式发票
- 03登记发票付款
- 04取消、恢复、冲销或删除发票
- 05计算并核对财务单据总额
适用场景
- 01查找指定期间未付款的发票
- 02按明细和增值税要求准备发票
- 03登记收到的发票款项
- 04将形式发票转换为发票
MCP 相关
向 MCP 客户端提供 Oblio 账户及发票操作。财务单据操作会标记为需确认,并在开具或变更前计算总额。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
17收录的工具列表 · 更新于 3 天前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| number | string | 是 | 单据编号,作为文本提供,不含序列名:"0042" 不等于 42。 |
| series_name | string | 是 | 单据所属的序列,必须与 list_series 显示的内容完全一致。 |
| expect_total | string | 否 | 发票必须具有的总额("121.00");如不一致,则不会进行任何更改。建议提供:号码可能对应错误的发票。 |
详细介绍
Oblio MCP 服务
通过 Oblio 的 API,让你的 AI 助手为罗马尼亚公司开具和跟踪发票。它会读取客户、产品、系列、增值税税率和已开具的发票;开具发票和形式发票、记录付款,并取消、恢复、冲销或删除发票。每个会创建、更改或撤销财务单据的工具都属于 money:客户端会先征求你的同意,并显示按 ANAF 核算方式计算的总额。
你需要 一个 Oblio 账户、其 API 密钥,以及服务要代表其操作的公司的税号(CIF)。没有沙盒:在这里开具的发票是真实发票,并会使用该系列中的下一个编号。
你可以这样提问
- “9 月份有哪些发票尚未付款?”
- “为 Client SRL 开具发票:8 小时咨询服务,每小时 1,000 RON,另加 21% 增值税,30 天后到期。”
- “Client SRL 今天通过银行转账支付了发票 FCT 0042 的 1,000 EUR。请记录这笔付款。”
- “将形式发票 PRF 0007 转为发票。”
- “冲销发票 FCT 0042,并保留已记录在该发票上的付款。”
安装
使用 Claude Code:
claude mcp add oblio -e OBLIO_CONFIG="<path to Oblio app.json>" -- npx -y @foreverworks/mcp-oblio
Claude Desktop(Settings、Developer、Edit Config)和大多数其他客户端都通过同一条命令读取 JSON:
{
"mcpServers": {
"oblio": {
"command": "npx",
"args": ["-y", "@foreverworks/mcp-oblio"],
"env": {
"OBLIO_CONFIG": "<path to Oblio app.json>"
}
}
}
}
每个客户端都会在 Node 22.19 或更高版本上运行已发布的软件包。VS Code 和 Claude Desktop 版本会在添加服务时询问 OBLIO_CONFIG。Cursor 则从环境变量中读取它(${env:OBLIO_CONFIG}),因此请在启动 Cursor 前设置好该变量。配置 说明了其中包含的内容。
从克隆仓库安装
git clone https://github.com/foreverworks/mcps.git && cd mcps
npm ci && npm run build
claude mcp add oblio -e OBLIO_CONFIG="<path to Oblio app.json>" -- node "$PWD/servers/oblio/dist/index.js"
在 JSON 配置中,命令为 node,唯一参数是 servers/oblio/dist/index.js 的完整路径。若要通过 HTTP 在多个客户端间共享同一个运行实例,请参阅 docs/deploying.md。
配置
| 变量 | 必需 | 含义 |
|---|---|---|
OBLIO_CONFIG | 是 | app.json(见下文)的路径,服务只会读取该文件。在 systemd 下,若未设置此变量,则会使用 CREDENTIALS_DIRECTORY 中的 app.json(LoadCredential=app.json:<path>)。 |
OBLIO_STATE_DIR | 否 | 访问令牌缓存的存放位置;默认位置见 docs/configuration.md。 |
app.json 包含三个必填值:
{
"client_id": "<the email you sign in to Oblio with>",
"client_secret": "<the API secret>",
"company_cif": "<the CIF of the company every call acts on>"
}
company_cif 没有默认值,因此任何调用都无法代表未指定的公司执行操作。
api_base 和 token_url 可覆盖 Oblio 的端点,用于测试或代理。
服务绝不会写入 app.json;错误信息会指出有问题的字段,但绝不会显示字段值。
获取 API 密钥
- 登录 Oblio 网页应用。
- 打开 Settings,然后选择 Account Data(Setari, Date cont),并复制 API 密钥。
- 在
app.json中将其填入client_secret,并将你登录时使用的电子邮件地址填入client_id。
每次重置账户密码时,Oblio 都会生成新的密钥,因此重置后需要在 app.json 中填入新密钥。
状态文件夹中存放着 access_token.json,这是 Oblio 为该密钥签发的有效期为一小时的令牌,文件权限设为 0600,并在多个进程间加锁。所有服务共用的变量(传输方式、限制、确认设置)见 docs/configuration.md。
首次运行
- 请助手运行 Oblio 的
health检查。它会返回账户、app.json中的公司 CIF,以及该账户能否访问该公司。如果密钥被拒绝,此时就会显示出来,不会签发任何内容。 - 查询系列(
list_series)和 VAT 税率(list_vat_rates):发票会使用 Oblio 提供的系列名称,以及每个明细行对应的税率名称。
在 shell 中运行 node dist/index.js --health 会打印一行 OBLIO:,如果凭据无效,则以非零状态码退出,适合用于定时任务。
工具
read 不会更改任何内容;write 会更改 Oblio 账户中的内容;money 会创建、更改或撤销财务单据,并且客户端会在每次调用前询问你。
| 工具 | 访问权限 | 功能 |
|---|---|---|
health | read | 检查服务是否正常运行、使用哪个账户、公司 CIF 是什么,以及该账户能否访问该 CIF。始终会询问 Oblio。 |
list_companies | read | 账户关联的公司。缓存 10 分钟。 |
list_clients | read | 已保存的客户,按名称或 CIF 筛选,每次返回一页。不会缓存。 |
list_products | read | 已保存的产品和服务,按名称或代码筛选,每次返回一页。不会缓存。 |
list_series | read | 单据系列及各系列接下来将签发的编号。缓存 10 分钟;签发或删除任何单据后会清除缓存。 |
list_vat_rates | read | 明细行的 vat_name 和 vat_percentage 所使用的 VAT 税率。缓存 10 分钟。 |
list_invoices | read | 按期间、系列、买方、状态(未付款、已付款、已取消)和 e-Factura 状态查询已签发发票,按最新优先排序,每次返回一页。 |
get_invoice / get_proforma | read | 按系列和编号查询一份单据:其 PDF 和 e-Factura 链接、总额及付款记录。 |
create_proforma | write | 签发形式发票。它不是财务单据,但会占用该系列中的一个编号。 |
create_invoice | money | 签发发票。 |
invoice_from_proforma | money | 签发一张引用形式发票的发票,并沿用形式发票的客户、明细行和总额。 |
collect_invoice | money | 记录已签发发票收到的付款:付款方式、金额、日期和参考信息。 |
cancel_invoice / restore_invoice | money | 取消发票(其编号仍会被占用),或撤销该操作。 |
reverse_invoice | money | 为已签发的发票开具冲销发票(storno),金额与原发票完全相同,但符号相反。 |
delete_invoice | money | 永久删除发票。Oblio 仅允许删除系列中的最后一个编号。 |
Money
七个 money 工具会在 tools/list 中标记出来,你的客户端会要求你批准每次调用(Claude Code 在所有权限模式下都会这样做)。设置 MCP_CONFIRM=elicit 后,服务会改为自行询问你,并根据参数生成一行确认内容。例如:
Issue invoice in series FCT to Client SRL (CIF RO87654329): 9680.00 RON incl. VAT 1680.00 (1 line), dated 2026-09-28, due 2026-10-28, marked paid by Ordin de plata OP 7001
Record 1000.00 EUR paid on invoice FCT 0042 to Client SRL, Ordin de plata OP 7001, 2026-10-02, leaving 210.00 EUR unpaid
Issue a reversing invoice for FCT 0042, Client SRL, total -9680.00 RON, in series FCT, keeping the payment recorded on it
DELETE invoice FCT 0042 totalling 9680.00 permanently (no undo; only the last number in a series can be deleted, and anything already sent to ANAF stays there)
第一行是下文文档输入中的文档。最后一行是带有 expect_total 的 delete_invoice;若不提供该参数,这一行会显示“未提供总额,因此未进行检查”。服务会将其名称放在最前面,因此你会看到 oblio: 开具发票 ...。
你批准的内容就是实际开具的内容:
- 你确认的总额就是实际开具的总额。 该金额由
documentTotal(工具包中的invoiceTotals.ts)计算;create_invoice返回的computedTotal也使用同一函数。开具后,系统会重新读取文档;如果 Oblio 的总额不同,调用就会失败,并返回reason: "total_mismatch",指出已开具的文档。invoice_from_proforma会先读取形式发票,并确保发票总额与其一致。 - 取消、恢复和删除操作会先读取发票,并说明其总额、Oblio 操作的文档以及公司的 CIF。如果提供了
expect_total,而其数值所对应发票的总额不同,则不会进行任何更改。(Oblio 的文档读取结果不包含买方信息,因此无法以相同方式核对买方。) - 付款会与发票进行核对:如果发票已取消、已全额付款,或付款金额超过未付余额,服务就会拒绝该操作,并告知未付余额。
故障排查
auth:”Oblio 拒绝了 client_id 和密钥“。 密钥已更改,通常是因为重置了密码。请从 Settings、Account Data 中复制新密钥到 app.json。
开具或删除操作后出现带有 reason: "outcome_unknown" 的 api 错误。 连接已断开,因此无法确定 Oblio 是否执行了操作。请先查找该文档(使用 get_invoice 或 Oblio 的网页应用)。如果找不到,请使用错误报告的 idempotency_key 再次调用:Oblio 不会使用相同的键开具两次。重复调用 collect_invoice 是安全的:如果付款已到账,它会找到该笔付款且不会重复记录。
带有 reason: "total_mismatch" 的 api 错误。 文档已开具,但 Oblio 的总额与你确认的金额不同。请打开该文档(使用 get_invoice 或 get_proforma);如果金额有误,请取消该文档,不要再次开具。
api 错误中包含 Oblio 自己的消息,例如 “Seria FCT nu exista”。该消息会指出出错的字段或系列;list_series 和 list_vat_rates 会提供 Oblio 要求的名称。
调用时出现状态码为 401 或 403 的 api 错误。 该账号无权操作 company_cif 中的公司;health 和 list_companies 会显示该账号可访问的公司。
带有 reason: "drift" 的 api 错误。 Oblio 的响应结构发生了变化。服务不会猜测;请报告此问题。
工作原理
文档输入
create_invoice 和 create_proforma 接受经过验证的文档输入模型,采用 Oblio 的“Parametri document”表格格式,并使用 snake_case。公司的 CIF 不属于其中:它来自 app.json,因此粘贴的示例无法向另一家公司开具发票。
{
"client": { "name": "Client SRL", "cif": "RO87654329", "vat_payer": true },
"series_name": "FCT",
"issue_date": "2026-09-28",
"due_date": "2026-10-28",
"currency": "RON",
"products": [
{ "name": "Consulting", "price": "1000.00", "quantity": "8", "measuring_unit": "ora",
"vat_name": "Normala", "vat_percentage": "21", "vat_included": false, "product_type": "Serviciu" }
],
"collect": { "type": "Ordin de plata", "document_number": "OP 7001" }
}
- 每个金额都是十进制字符串(
"1000.00"),会通过模式检查,并以字符串形式发送给 Oblio,因此不会经过浮点数。计算使用工具包中精确的decimal.ts。 - 每一行都必须包含
vat_included,因为 Oblio 的默认值(“含税”)会在不提示的情况下将净价变成含税价。必须包含vat_percentage,因为你确认的总额会根据它计算。 - 买方的代码和 IBAN 会通过校验位检查:罗马尼亚买方的
cif必须是校验位有效的 CIF 或有效的 CNP,以免数字换位导致发票发送给另一家公司。country为其他国家的买方则按原样通过。使用send_email时,响应中的emailedTo会显示 Oblio 将发票发送到了哪里。 - 系列和编号会检查格式:系列由字母和数字组成,格式与
list_series显示的一致;编号只能包含数字,并以文本形式表示("0042")。 - 其他所有可能出错的情况都会在发送前一次性拒绝(
src/domain/rules.ts):小数位数超过precision(Oblio 会静默舍入)、数量为零、价格为负数、税率超出 0-100、到期日早于开票日期、没有收据系列的Chitanta,以及没有参考信息的其他付款方式。 - 重试不会导致重复开具。 Oblio 会拒绝具有相同
idempotency_key的第二份文档。如果未提供该键,系统会根据文档生成(文档类型、公司、内容和开票日期:src/domain/keys.ts)。若要在同一天开具一份有意完全相同的文档,请提供自定义键。
总额
EN 16931 的规则是 ANAF 验证每份 e-Factura 时所依据的规则,Oblio 也遵循该规则:一行的金额为数量乘以价格,并舍入到小数点后 2 位;每个税率的 VAT 根据这些金额的总和计算一次(同一税率下的含税行和未税行属于两个组,各自舍入一次);总额为金额加 VAT。含 VAT 的总价中所含 VAT 为总价 × 税率 /(100 + 税率)。所有计算均采用远离零的舍入方式,与 PHP 的 round() 相同。由于这种舍入具有对称性,storno 的各行金额合计恰好等于原单总额的相反数;测试会检查这些舍入情况。
付款与冲销
collect_invoice 接受发票的系列和编号、付款方式(银行转账为
Ordin de plata,Card,现金并提供收据为 Chitanta,以及 Oblio 的其他
类型)、金额、日期和付款参考(收据则填写其系列,因为编号由 Oblio 生成)。
尽管 Oblio 会默认使用发票总额和当天日期,但金额和日期仍为必填项,因为
任何人都不应在未查看的情况下确认这些默认值。系统会先读取发票,因此你
确认的行中,买方和货币均以发票本身为准,返回结果也会给出付款前后的余额。
如果付款已成功记录,重复调用会找到该付款,不会再次记录;若要记录另一笔
类型、参考、金额和日期完全相同的付款,请提供你自己的 idempotency_key。
付款需在 Oblio 网页应用中删除;此服务无法撤销付款。
reverse_invoice 使用 Oblio 自己的参考流程,因此冲销发票与原发票会在 Oblio
中关联,无需重新输入信息。该操作会冲销整张发票;如需部分更正,请使用
create_invoice 开具更正发票。storno_series 用于选择系列(默认使用原发票
的系列);remove_payments 用于决定保留原发票上记录的付款(默认如此,例如
单独退款时)还是移除这些付款(Oblio 的 refund)。已取消的发票和本身属于
冲销发票的发票均不允许冲销。幂等键取自被冲销的发票,因此无论在哪一天重试,
都不会再次开具冲销发票;若要有意再次冲销,请先取消第一次冲销,再提供你
自己的键。
列出发票
list_invoices 会列出每张发票的系列和编号、日期、币种、Oblio 记录的总额、
是否已取消、买方、付款、e-Factura 状态和 PDF 链接。若要按名称查找买方,
请先用 list_clients 查找,再按其 CIF 筛选。
unpaid和paid根据 Oblio 的“已收款”标记筛选,并排除已取消的发票;cancelled仅列出已取消的发票。草稿永远不会列出。- Oblio 会报告每张发票的 e-Factura 状态(
not_sent、processing、sent、errors),但无法按此筛选,因此会在 Oblio 返回每页结果后逐条应用筛选。 筛选后的页面会说明已读取的行数(scanned),即使页面为空,也可能提供 下一页:请继续使用nextCursor。 - 每页最多包含 100 行。游标会记录最后读取的行,因此在翻页期间开具的发票 不会导致行重复;如果游标与不同的筛选条件搭配使用,则会被拒绝。
失败能说明什么
没有沙盒,因此每种失败能说明什么,决定了是否重试调用(在工具包的
makeHttp 中,见 src/infra/http.ts):
- 429 说明没有发生任何操作:每次调用都会重试,并遵守
Retry-After。 - 使用新令牌时收到 401:会重新获取一次令牌;若第二次仍收到 401,则 视为最终结果。
- 连接中断或 5xx 也无法说明操作是否发生。读取、取消和恢复操作会重试。
开具和删除操作不会重试:它们会以
outcome_unknown失败(见 故障排除)。
Oblio 对单据的限流为每 100 秒 30 次请求,对其他操作的限流为每 10 秒 30 次。
服务会将请求速率控制在两者的限额以下(src/infra/http/throttle.ts:开具操作
同时最多 10 个请求,之后每 5 秒一个;其他操作每秒 2 个),因此遇到突发请求时
会等待,而不是触发 429。通过 HTTP 使用时,限速适用于该进程的所有客户端。
返回的内容
Oblio 未提供 OpenAPI 或 JSON Schema,其 SDK 也不包含类型,因此我们在 src/domain/schema.ts 中手动建模线上的类型,依据是 https://www.oblio.eu/api 和 PHP SDK OblioSoftware/OblioApi@027a5cc。每个响应都会在边界处根据这些类型进行解析;文档中记录的字段缺失时,调用会以 drift 失败,而不会继续传递;超出文档记录范围的字段则会被丢弃。无论 Oblio 返回的是 true、1 还是 "1",标志值都会解析为布尔值;小数会保留为 Oblio 返回的字符串;系列编号会保留为文本("0051")。api 失败时,错误会优先显示 Oblio 自己的 statusMessage,因为“Seria FCT nu exista”就是全部答案。
npx tsx scripts/smoke.ts 会使用你的凭据运行构建好的服务。除非指定 --write-proforma <series>,否则它只读;指定后会开具一张金额为 0.01 的形式发票;它无法访问任何 money 工具。
限制
- 每个服务仅支持一家公司:公司 CIF 位于
app.json中。一个账户关联多家公司时,每家公司都需要单独配置。 - 不发送电子发票。 向 ANAF 发送发票是另一项操作;由
anaf-efactura服务执行。 - 送货单不在范围内,由送货单创建的发票也不在范围内。
- 部分 Oblio 文档记录的字段会被有意排除:
| Oblio 字段 | 原因 |
|---|---|
折扣行(discount、discountType、discountAllAbove) | Oblio 未说明金额折扣是否包含 VAT,也未说明如何舍入,因此无法准确确定你确认的总额。请将折扣计入行项目价格。 |
产品的 currency、exchangeRate | 其他币种的行项目需要经过 Oblio 转换后,总额才有意义。行项目使用单据的币种。 |
disableAutoSeries、number | 手动编号可能导致财政系列中出现编号缺漏或重复。由 Oblio 负责编号。 |
create_invoice 中的 referenceDocument | 参考单据是单独的操作,也有自己的确认行:reverse_invoice 用于红字发票,invoice_from_proforma 用于形式发票。 |
clientLocation(BT-71 至 BT-80)、deputyName、deputyIdentityCard、deputyAuto、selesAgent、noticeNumber | 商品交付字段:交付地点、代表人、车辆、销售代理、送货单。 |
issuerId | 开票人的个人身份号码(CNP),开具发票时不需要。已支持 issuer_name。 |
receptionNotice、projectNumber、buyerIdentifier、clientAccountReference、contractNumberDate | Oblio 的表格将前三个字段对应的电子发票字段编号错位,因此无法确定它们各自填充哪个字段;另外两个没有对应的电子发票字段。已支持 order_number(BT-13)和 contract_number(BT-12)。 |
spvExtern | 向 ANAF 发送是另一项操作(见上文)。 |
codeClient、codeEAN、nameTranslation、measuringUnitTranslation | 商品目录和翻译字段;已支持产品的 name 和 code。 |
list_invoices 不接受 Oblio 的 withProducts(列表行的结构未作说明,因此无法校验),也不接受其 id 和 number 筛选条件(get_invoice 可通过系列和编号读取单个单据)。
Oblio 的其他服务
搜索日期:2026-10-15。Oblio 未发布 MCP 服务:其 GitHub 账号提供 PHP、Node、Python、Go、Java 和 C# 的 API 客户端及商城插件,其网站也未提及 MCP。有两个社区服务支持的 Oblio API 功能比本服务更多:
oblio-mcp(位于 GitHub,未发布到 npm):仅支持 stdio;通过环境变量配置电子邮件和 API 密钥;在运行时通过set_cif选择公司;支持所有单据类型,包括送货单、单据列表、付款和 e-Factura 提交。- MCP Registry 中的
io.usefulapi/oblio:由第三方通过 HTTP 托管,第三方通过自己的 OAuth 登录流程保管你的 Oblio 凭据;支持的功能类似,另加 Webhook;每月前 100 次调用免费,之后收费。
本服务旨在实现它们都不具备的功能:按照 ANAF 验证 e-Factura 所用的规则计算发票总额,将该总额填入你确认的行项目,并核对已签发的单据;如果调用方未提供幂等键,则自动生成一个,避免重试时重复签发;通过控制位校验罗马尼亚买家的 CIF 或 CNP;仅操作配置中指定的那家公司;并且可以作为独立服务运行,密钥保存在客户端无法读取的文件中。本服务不会提交 e-Factura。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。