mcpField
A
ANAF e-Factura

ANAF e-Factura

本地服务
foreverworks.github.io金融数据1今天更新

关于 ANAF e-Factura

ANAF e-Factura 是面向罗马尼亚企业的 MCP 服务,可读取、校验并提交电子发票及 e-Transport 申报。它还支持发票构建、解析、签章核验和 VAT 登记查询;提交操作会由客户端确认。

主要功能

  1. 01查询已发送和收到的发票
  2. 02下载发票并核验 ANAF 签章
  3. 03构建、解析和校验发票
  4. 04向 ANAF 提交发票及运输申报
  5. 05查询公司 VAT 登记信息

适用场景

  1. 01查看近期供应商发票及其明细
  2. 02提交发票前校验 CIUS-RO 格式
  3. 03核对发票是否带有有效 ANAF 签章
  4. 04查询企业 VAT 身份和适用情况

MCP 相关

作为 MCP 服务向客户端提供发票、申报、签章核验及公司查询工具。提交发票和 e-Transport 申报的工具会标记为需确认的操作。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"com-foreverworks-anaf-efactura": {
"command": "npx",
"args": [
"-y",
"@foreverworks/mcp-anaf-efactura"
],
"env": {
"ANAF_CONFIG": "<ANAF_CONFIG>"
}
}
}
}
启动命令npx -y @foreverworks/mcp-anaf-efactura
需要配置的环境变量
ANAF_CONFIGPath of app.json: the OAuth app you registered with ANAF (its client id and secret, the callback URL) and the company's CIF, as the README shows. lookup_company, validate_invoice and parse_invoice work without it.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@foreverworks/mcp-anaf-efactura0.1.0

工具

20

收录的工具列表 · 更新于 3 天前

参数类型必填说明
redirect_uristring否在 app.json 中注册的重定向 URI 之一。留空表示使用第一个。

详细介绍

ANAF e-Factura 图标 ANAF e-Factura MCP 服务

通过 AI 助手读取公司通过罗马尼亚 e-Factura 发送和接收的发票,检查发票上的 ANAF 印章,并向 ANAF 提交发票和 e-Transport 申报。它还可以验证、渲染和编写发票,并在 ANAF 的增值税登记簿中查询公司。它的三个 money 工具(upload_invoice、upload_invoice_b2c、etransport_file)提交的文件无法撤回:客户端会在每次调用前征求你的同意,除非你另有说明,否则每次提交都会发往 ANAF 测试环境。

你需要:一个在 ANAF 注册的 OAuth 应用(其客户端 ID、密钥和回调 URL)、公司的 CIF,以及一位拥有公司合格数字证书和 SPV 权限的人员,该人员需要在浏览器中登录一次。之后服务会自行续期授权;其 --health 检查会在需要该人员再次登录的两周前发出警告。验证、渲染、构建和读取发票,检查印章以及查询公司均无需账户。

你可以这样提问

  • “过去两周供应商发给我们的发票有哪些?”
  • “下载我们收到的最新发票,检查上面的 ANAF 印章,并列出发票明细。”
  • “RO87654329 是增值税纳税人吗?是否采用收款时缴纳增值税?”
  • “为 Client SRL 开具 10 小时咨询服务发票,单价为每小时 500 RON,另加 21% 增值税;让 ANAF 验证,并提交到测试环境。”
  • “我们的 ANAF 授权还剩多少天?”

安装

在 VS Code 中安装 在 Cursor 中安装 下载 Claude Desktop 版

使用 Claude Code:

claude mcp add anaf-efactura -e ANAF_CONFIG="<path to ANAF app.json>" -- npx -y @foreverworks/mcp-anaf-efactura

Claude Desktop(Settings、Developer、Edit Config)和大多数其他客户端都通过 JSON 读取相同的命令:

{
  "mcpServers": {
    "anaf-efactura": {
      "command": "npx",
      "args": ["-y", "@foreverworks/mcp-anaf-efactura"],
      "env": {
        "ANAF_CONFIG": "<path to ANAF app.json>"
      }
    }
  }
}

每种方式都会在 Node 22.19 或更高版本上运行已发布的包。VS Code 和 Claude Desktop 安装包会在添加服务时询问 ANAF_CONFIG。Cursor 则从环境变量读取它(${env:ANAF_CONFIG}),因此请在启动 Cursor 前设置该变量。配置介绍了其中应包含的内容。

从克隆仓库安装
git clone https://github.com/foreverworks/mcps.git && cd mcps
npm ci && npm run build
claude mcp add anaf-efactura -e ANAF_CONFIG="<path to ANAF app.json>" -- node "$PWD/servers/anaf-efactura/dist/index.js"

在 JSON 配置中,命令为 node,唯一的参数是 servers/anaf-efactura/dist/index.js 的完整路径。若要通过 HTTP 在多个客户端间共享同一个运行实例,请参阅 docs/deploying.md。

配置

变量必填含义
ANAF_CONFIG是app.json(如下)的路径,服务只会读取此文件。
ANAF_STATE_DIR否授权凭据、已开始的授权流程以及生产申报记录的存放位置;默认值见 docs/configuration.md。
ANAF_DOWNLOADS_DIR否下载的归档文件、PDF 和生成的发票的输出目录;默认为 <state dir>/invoices。

app.json 保存你在 ANAF 注册的应用(如下):

{
  "app_name": "<the name you gave it at ANAF, shown by health>",
  "client_id": "<Client ID>",
  "client_secret": "<Client Secret>",
  "redirect_uris": ["<the Callback URL you registered>"],
  "company_cif": "<the company's CIF, with or without RO>"
}

client_id 和 client_secret 为必填项,授权还需要 redirect_uris。company_cif(或 cif)是调用未指定公司时所操作的公司;一份授权凭据可以涵盖多家公司,因此 cif 参数可以覆盖此值。endpoints 可按名称覆盖 ANAF 的 URL(authorize、token、hello、fctelProd、fctelTest、etransportProd、etransportTest),而 api_base / api_test_base 可覆盖 e-Factura 的基础 URL。服务绝不会写入 app.json,错误信息只会指出错误字段,不会显示其值。未设置 ANAF_CONFIG 时,服务仍会启动,不需要授权凭据的工具也可以使用。

获取客户端 ID 和密钥

ANAF 将此过程称为在 OAuth 配置文件中注册应用;其流程说明 Oauth_procedura_inregistrare_aplicatii_portal_ANAF.pdf (罗马尼亚语)展示了各个页面。

  1. 确认将要登录的人员已通过其合格证书在 SPV 注册,并拥有公司的以下权利之一:法定代表人、指定代表或授权人(reprezentant legal、reprezentant desemnat、împuternicit)。
  2. 在 anaf.ro/InregOauth 创建开发者账号(在线服务、用户注册、应用开发者、“API 注册”);可以新建账号,也可以使用现有门户账号,并通过 ANAF 发送的“验证码”("Cod de verificare")确认电子邮箱。
  3. 登录(“用户身份验证”,"Autentificare utilizator"),打开“编辑 OAuth 配置文件”("Editare profil Oauth"),然后选择“管理应用”("Gestionare aplicații")。
  4. 为应用命名,选择其服务(E-Factura;若要使用 E-Transport 工具,还需选择 E-Transport),并填写你能控制的回调 URL,例如 https://example.com/anaf/callback;该地址无需有任何程序响应。点击“生成客户端 ID”("Generare Client ID")。
  5. 点击列表中的应用,将其 Client ID、Client Secret 和 Callback URL 复制到 app.json。

授权凭据只能执行应用所选服务和证书持有人 SPV 权限共同允许的操作;health 会显示其角色(EFACTURA、ETRANSPORT)。

输入和输出文件

文档必须逐字节输入,绝不能由模型重新输入为文本,因为 ANAF 的印章涵盖确切的字节内容:可以通过服务的文件根目录中的路径输入(MCP_FILE_ROOTS;使用 stdio 时为客户端文件夹或工作目录),也可以由脚本以 { "content_base64": "...", "sha256": "..." } 的形式输入。链接、根目录之外的文件、校验和错误的文件或非 UTF-8 文档都会在发送任何内容之前被拒绝。输出目录中的路径也会被接受,因此 build_invoice 生成的文件可直接传给 validate_invoice 和 upload_invoice。

文件会以 0640 权限完整写入输出目录,要么全部写入,要么完全不写入;绝不会覆盖含有其他字节的文件(此时会使用下一个编号名称,例如 5001-2.zip);save_dir 必须是其中的文件夹。状态目录中的 tokens.json、authorization.json 和 uploads.json 权限为 0600。状态目录和输出目录都不能位于 app.json 所在目录中。所有服务共用的变量见 docs/configuration.md。

首次运行

读取或向 ANAF 提交文件的工具需要授权,且只有证书持有者才能授予授权。请让你的助手通过 ANAF 为服务器授权:

  1. begin_authorization 会返回应用的 ANAF 登录页面(authorizeUrl),该页面开放 30 分钟;redirect_uri 会从多个回调 URL 中选择一个。能够自行显示链接的客户端(MCP URL 引导:通过 stdio,或通过协议版本为 2026-07-28 的 HTTP,例如 Claude Code)会向你提供该页面;如果你不是证书持有者,请拒绝并将地址转交给持有者。
  2. 证书持有者在安装了证书的浏览器中打开该页面,选择证书并登录。
  3. 浏览器会跳转到回调 URL,地址中带有 ?code=...&state=...。页面可能无法加载;重要的是地址。
  4. 立即将整个地址传给 complete_authorization(redirect_url):ANAF 的授权码在签发 60 秒后失效。服务器会检查 state、交换授权码、写入 tokens.json,并且只返回两个过期日期;不会有任何令牌进入对话。
  5. 请求 health:查看授权的角色以及每个令牌的剩余天数。
保持授权有效

ANAF 的流程(第 28 和 33 页)规定,访问令牌有效期为 90 天(或其声明的 exp 时间),刷新令牌有效期为 365 天。在访问令牌到期前 3 天内调用会先刷新令牌(使用 force 调用 refresh_token 可立即刷新),每次刷新都会生成一个新的刷新令牌,其有效期为 365 天。如果刷新令牌过期或 ANAF 拒绝该令牌(invalid_grant),只有证书持有者才能通过重复上述步骤恢复授权。对于不常使用的服务器,请设置定时任务每天刷新一次。从克隆目录中的 servers/anaf-efactura 运行:

node dist/index.js --health            # greet ANAF with the stored token; the days left
node dist/index.js --refresh           # refresh when the access token has under 14 days left
node dist/index.js --refresh --force   # refresh now

每条命令都会输出一行 ANAF: OK|WARN|FAIL ...,绝不会输出令牌;成功时退出码为 0,失败时为 1(需要人工处理:授权失效或配置损坏),警告时为 2(ANAF 状态异常,或刷新令牌将在 14 天内过期)。

工具

read 不会更改 ANAF 中的内容(有些工具会将文件保存到 outbox);write 会更改已存储的授权;money 会向 ANAF 提交文件,并且客户端会在每次调用前询问你。

工具访问权限功能
healthread使用已存储的令牌向 ANAF 打招呼:应用、默认 CIF、授权的角色,以及每个令牌的剩余天数。由于 ANAF 会在问候语中回显 bearer token,因此只会返回问候语的第一行。
token_statusread查看已存储授权的到期时间和角色,不调用 ANAF。
refresh_tokenwrite当当前访问令牌将在 3 天内到期时,获取新的访问令牌;也可以使用 force 立即刷新。
begin_authorization / complete_authorizationwrite获取新的授权:先访问证书持有者的 ANAF 页面,然后提供其浏览器跳转到的地址。
list_invoicesread列出过去 zile 天内的 e-Factura 消息,最多 60 条:已发送、已接收、错误和买方消息,并提供 download_invoice 所需的 id。
list_invoices_windowread按日期范围分页列出相同消息,范围最多 60 天,并按 filtru 筛选(E 错误、T 已发送、P 已接收、R 等待回复)。
download_invoiceread只有在 ZIP 文件能够打开、每个条目都与其校验和匹配且 ANAF 印章有效时,才会将一个已签名 ZIP 保存到 outbox。ANAF 允许每天下载每条消息 10 次。
upload_invoicemoney向公司提交发票 XML(UBL、CII、CN 或 RASP)。除非 test 为 false,否则使用测试环境。
upload_invoice_b2cmoney通过 ANAF 的 /uploadb2c 向个人提交发票,其他行为与 upload_invoice 相同。
upload_statusread查看上传的处理情况:成功(附下载 id)、处理中,或失败并附 ANAF 给出的原因。
etransport_listread列出过去 zile 天内的 e-Transport 声明,最多 60 条:UIT、申报方、合作方、承运方、车辆,以及 ANAF 拒绝某项声明的原因。
etransport_filemoney提交声明 XML(schema v2):新运输、更正、删除、确认或车辆变更。除非 test 为 false,否则使用测试环境。
etransport_statusread查看声明的处理情况:成功(UIT 从现在起有效)、处理中,或失败。
build_invoiceread根据字段生成 CIUS-RO 发票(UBL)并写入 outbox,准确计算总额,并先检查草稿。不会提交任何内容。
parse_invoiceread将 UBL 发票或贷项通知单(文件或 outbox 中的压缩包)解析为 JSON,所有值均取自文档本身的文本。不会调用任何服务。
validate_invoiceread使用 ANAF 自身的规则验证 UBL 发票或贷项通知单(schema、EN 16931 和 CIUS-RO 规则),但不提交。
invoice_pdfread获取 ANAF 提供的 UBL 文档 PDF,或通过 message_id 获取已提交发票的 PDF,并保存到 outbox。
verify_signatureread检查发票是否为 ANAF 存储的文件且带有 ANAF 印章:先在本地根据固定 CA 验证;只有本地无法判定时才询问 ANAF。
lookup_companyread按指定日期查询 ANAF 增值税登记册中的最多 100 个 CIF:身份信息、注册办事处、增值税纳税人身份及所属期间、收款增值税、拆分增值税、非活跃状态和 RO e-Factura 登记信息。

最后六项无需授权,但 invoice_pdf 和 verify_signature 在提供 message_id 时除外;e-Transport 工具需要 ETRANSPORT 角色。调用 ANAF 的工具接受 cif(默认使用 app.json 中的值)和 test:列表和下载默认读取生产环境,除非 test 为 true;而三个提交工具和两个状态工具默认使用测试环境,除非 test 为 false,因此状态会在对应文件提交的环境中查询。

Money

upload_invoice、upload_invoice_b2c 和 etransport_file 会向 ANAF 提交法律或税务文件。文件会送达交易对方,且无法撤回(撤销发票需要开具贷项通知单)。它们在 tools/list 中标记为 money,并且客户端会要求你批准每次调用(Claude Code 在所有权限模式下都会这样做)。无论由谁确认,以下三条规则都适用:

  • 除非你另有说明,否则一律使用测试环境。 每次提交都会发送到 ANAF 的测试环境,在该环境中,提交没有法律效力;除非 test 为 false。
  • 除非 refile 为 true,否则生产环境中不会重复提交相同字节。 生产环境提交的精确字节的 SHA-256 会在发送前写入账本(uploads.json);被 ANAF 拒绝或从未发出的提交不计入其中。
  • 丢失的响应绝不会重新发送。 连接中断、5xx 响应或未记录的响应都会导致失败,状态为 outcome_unknown,因为提交可能已经完成(参见故障排除)。

文件会在询问你之前读取一次,因此你确认的内容和提交的文件来自同一组字节。使用 MCP_CONFIRM=elicit 时,服务端会自行向你询问,并从 XML 中读取一行内容,以文件的 SHA-256 结尾:

anaf-efactura: FILE with ANAF e-Factura PRODUCTION (legal filing, cannot be withdrawn): invoice EX-0042 of 2026-09-28, buyer Client SRL (87654329), payable 1234.50 RON, seller Exemplu SRL (RO92345672); UBL, file sha256 3f1c0a9e27b4
anaf-efactura: File e-Transport declaration for a new UIT, Cluj-Napoca (county 12) to Iasi (county 22), vehicle CJ12ABC + trailer CJ34DEF, 1800.50 RON, environment prod; declarant 92345672, file sha256 5d0e7b2a91c4

测试上传的提示行以 TEST upload to ANAF's test environment (no legal effect) 开头;向个人开具的发票会显示 B2C invoice;重新提交时会添加 AGAIN (refile)。金额采用文件自身的十进制字符串;e-Transport 的金额是商品 valoareLeiFaraTva 的精确总和。若服务端无法读取文件,则会显示 UNREADABLE XML:请回答否。

在询问你之前,必须验证以下各项的 IBAN 校验位:发票中指定的所有付款 IBAN(BT-84、BT-91)、卖方的 CIF、e-Transport 申报人的 CIF 或 CNP,以及所有 UIT(根据 ANAF 的规则 BR-019,UIT 校验位可以发现错误字符,但无法发现两个字符互换)。只有当 etransport_status 显示 ok 时,新的 UIT 才计为有效。

故障排除

config:"... 处的令牌缺失或无法解析"。 尚未存储授权,或文件已损坏:按照首次运行中的说明授权。

config 指出 ANAF_CONFIG、app.json 的字段、company_cif,或“……位于 app.json 的目录中”。 修复变量或字段,传入 cif,或将 ANAF_STATE_DIR / ANAF_DOWNLOADS_DIR 移出 app.json 所在目录。

auth 出现 invalid_grant、refresh_expired、invalid_client 或 unauthorized_client。 授权已失效:重新授权。其他任何 auth 错误代码都表示 ANAF 暂时无法处理:稍后重试。

input:“该地址中的状态与 begin_authorization 签发的状态不一致”,或“开始时间已超过 30 分钟”。 该地址来自较早打开的标签页,或窗口已关闭:再次调用 begin_authorization,并立即传入新地址(超过 60 秒的代码会导致 auth 失败)。

api 状态码为 401 或 403。 ANAF 拒绝了此 CIF 或角色对应的令牌(token_status 会显示角色)。e-Transport 工具需要 ETRANSPORT:在 ANAF 将该服务添加到应用,然后重新授权。

api 返回 reason: "outcome_unknown",或 input:“这个文件……已发送到 ANAF 生产环境”。 申报可能已送达 ANAF,或者这些字节之前已经发送过。先查询(使用 test: false 调用 upload_status,或调用 list_invoices、etransport_status 或 etransport_list),只有在确实要再次提交相同字节时才传入 refile: true。

input:“未发送发票”、“未发送申报”或“未构建发票”。 校验位或规则校验失败;消息会列出具体问题。修正文档或 build_invoice 的字段。

validate_invoice 只发现了 ERRIdentif:“nu a fost identificat cui cumparator”。 买方是外国实体,而无法告知 ANAF 的验证器买方属于外国实体,因此这是预期结果。使用 extern: true 上传;对于此类买方,build_invoice 会返回该值。

checksum_mismatch。 收到的字节与 sha256 所指的文件不符,例如模型重新输入了 base64。没有发送任何内容:通过路径发送文件,或让脚本对文件进行编码。

api 状态码为 0:ANAF 无法访问,或其响应缺少此次调用所需的字段;稍后重试。“……返回的数据格式与 ANAF 文档不符”:ANAF 的响应发生了变化,服务拒绝猜测;请报告此问题。

工作原理

返回内容。 ANAF 在线路上的数据格式会保留在服务内部:列出的消息具有 kind(sent、received、error、buyerMessage、unknown),以及一个从 ANAF 的文本中提取的 details,其中包含上传 ID 和双方的 CIF。createdAtLocal 特意不带时区,因为 ANAF 使用布加勒斯特时间戳,却不说明这一点;日期范围使用 UTC,因此无论身在何处,读取结果都相同。ANAF 使用 HTTP 200 拒绝请求且带有 eroare 键时(包括“此期间没有消息”),会设置 notice:若将这种情况当作空列表处理,可能会造成最严重的错误。对于真实响应中的 cui(证书持有者的 CNP),绝不会回传。

ANAF 的密封签名。 download_invoice 只有在所有条目的 CRC 与 ANAF 的密封签名(semnatura_<id>.xml)均通过校验后,才会保留归档。该密封签名是分离式 XML-DSig 签名,其摘要为发票文件原始字节的 SHA-256(因此重新缩进的副本不是已密封的文件),由发给 Ministerul Finanțelor 的证书签署,证书颁发者为 "Trans Sped Electronic Seal QCA G3"。verify_signature 会在本地检查该签名:证书必须来自固定的 CA(src/infra/sealTrust.ts),且有效期不得早于发票日期;RSA 签名必须通过验证,最后由摘要决定结果。因此,替换证书会导致 CA 检查失败,而为已更改的发票重写摘要会导致签名验证失败。凡未通过签名验证的情况,都会交由 ANAF 的公共 /api/validate/signature 验证;checkedBy 会说明响应来自何处。npx tsx scripts/check-seals.ts <folder> 可离线运行检查。 构建发票。 build_invoice 按 EN 16931 的规则汇总金额(ANAF 会检查):每行四舍五入到 2 位小数;每个税率类别的 VAT 按该类别所有行的合计金额计算一次;恰好一半时远离零舍入。它使用工具包的 invoiceTotals.ts,与 oblio 服务相同。写入前,它会列出 ANAF 会拒收的所有问题:

  • 校验位:罗马尼亚 VAT 编号或 CUI 中的 CIF、个人的 CNP、IBAN;
  • 地址:罗马尼亚地址需要县代码(CJ 或 RO-CJ);在布加勒斯特,城市应填写区(Sector 3 写作 SECTOR3);
  • VAT:S 类别需要税率,其他类别不能有税率;E 类别需要原因(AE、G 和 O 默认使用其 VATEX 代码);反向征税需要买方编号;O 类别不能填写 VAT 编号,也不能与其他类别混用;
  • 金额:应付金额需要到期日或付款条款;银行转账需要 IBAN;另一种币种的发票需要 vat_exchange_rate(由 bnr 服务提供的每单位 RON 汇率),因为 CIUS-RO 也要求以 RON 标示 VAT;
  • CIUS-RO 规定的长度和数量限制,以及至少包含一个数字的编号。

测试会根据 ANAF 对每个生成文件确切字节内容的判定进行检查;该判定由 scripts/record-validation.ts --send 对七张虚构发票记录(test/fixtures/validation)。

读取发票。 parse_invoice 不会消耗 ANAF 的下载次数,400.0000 也会保持为 400.0000:它提供忠实视图,而不作判定;判定由 validate_invoice 负责。

验证、PDF 和 VAT 注册信息。 validate_invoice 和 invoice_pdf 会调用 ANAF 的公共主机 webservicesp.anaf.ro,该主机无需令牌(在 api.anaf.ro 上执行相同操作时,没有令牌会返回 401),因此授权到期后仍可使用。超过 5 MB 的内容会在调用前被拒绝。已申报发票的 PDF 不会重新验证,因此当前规则不会拒绝按旧规则申报的文档;其他发票都会先验证,除非 validate 为 false。lookup_company 会检查每个 CIF 的校验位,然后按 ANAF 要求,每秒向 PlatitorTvaRest v9 发送一个请求。ANAF 未返回的状态会被视为不存在,而非 false。

轮换。 刷新操作会使旧的刷新令牌失效,因此新令牌对会先写入 tokens.json,并在所有共享状态目录的进程共用的锁保护下完成,然后才使用访问令牌。--refresh 不保留备份,因为轮换前的副本中会包含已失效的刷新令牌。

ANAF 的端点位于 src/infra/anafApi.ts。npm run gen:types 会根据 ANAF Swagger UI 页面中的 OpenAPI 文档重新生成类型(使用 openapi/ 中的快照时运行 -- --offline;从罗马尼亚境外访问时,mfinante.gov.ro 会重置连接,因此 ANAF_SPEC_MIRROR=http://web.archive.org/web/2025id_/ 会读取存档副本)。ANAF 文档错误或未说明的内容会在 src/domain/schema.ts 中手动建模;每个响应都会在边界处解析,因此接口变更会立即报错。

冒烟测试。 npx tsx scripts/smoke.ts 会使用你的配置驱动已构建的服务,并以只读方式运行(对于无需授权的工具,使用 --public-only),除非提供 --allow-writes;该选项会启用不带 force 的 refresh_token 和 begin_authorization。它绝不会申报任何内容,并会消耗最新一条消息的两次每日下载次数。

限制

  • build_invoice 创建的是发票,而不是贷项通知单(storno 是数量为负数的发票);不支持单据级折让或费用、附件,以及欧盟内部货物供应(VAT 类别 K,需要填写交货国家)。
  • e-Transport 只会申报你已编写的声明。 它不会根据字段创建声明,也不会读取 /info(其他人与你作为运输组织者共同申报的内容)。
  • 读取、验证和渲染仅接受 UBL,与 ANAF 的验证器相同;upload_invoice 也支持申报 CII。
  • 本地不会检查印章吊销情况(Trans Sped 的 CRL 和 OCSP)。
  • 账本位于单个状态目录中:使用独立状态目录的部署无法看到彼此的生产申报记录。
  • 不支持 SPV 邮箱和纳税申报。

ANAF e-Factura 的其他服务

检索日期:2026-10-15。ANAF 未发布任何相关项目:其唯一公开的 GitHub 仓库是一个用于 SPV 的 Java 示例客户端,发布于 2019 年;MCP Registry 中也没有 e-Factura 相关项目。以下三个社区服务可直接连接 ANAF:

  • anafpy(PyPI),功能最全面:Python 编写,包含 48 个工具的 stdio 服务(通过 mcp extra 安装),支持 e-Factura、e-Transport 申报、通过合格证书访问 SPV 邮箱、税务申报和公共登记库;每次申报都必须先准备,再根据与文档字节绑定的确认步骤完成提交。
  • @florinszilagyi/anaf-mcp(npm,stdio):可列出、下载、验证和上传文件,也支持 B2C;它将 XML 作为文本参数接收,且没有自己的确认步骤。
  • anaf-efactura-mcp(npm,stdio 或 HTTP):可生成并上传发票,默认使用测试环境。

其他项目仅支持通过托管服务上传并轮询、通过其他开票账户访问 e-Factura,或离线验证文件。

这些项目都无法同时做到:使用固定 CA 进行本地印章检查、仅以文件或校验过哈希的字节作为文档、读取 XML 中的一行后先在测试环境中提交、检查校验位、防止对相同字节重复提交或盲目重发,以及不在客户端中保存令牌。它也无法访问 SPV 邮箱或提交税务申报,而 anafpy 可以。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。