mcpField
A
ANAF SPV

ANAF SPV

本地服务
foreverworks.github.io金融数据22 天前更新

关于 ANAF SPV

ANAF SPV MCP 服务让个人账户通过 AI 助手读取 SPV 消息、请求文件并处理申报。它还可验证申报并提交 D212;提交申报属于写操作,客户端会逐次请求确认。

主要功能

  1. 01读取并筛选 SPV 消息
  2. 02下载并归档文件
  3. 03通过联系表单请求文件
  4. 04验证申报并查看状态
  5. 05提交 D212 申报

适用场景

  1. 01检查 ANAF 是否发布新通知
  2. 02保存尚未下载的 SPV 文件
  3. 03验证 D300 XML 并查看应缴 VAT
  4. 04查询已提交申报的状态

MCP 相关

向 MCP 客户端提供 SPV 会话、消息、文件请求及申报工具;登录验证码可由邮件 MCP 服务读取,也可手动输入。

配置

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

mcp.json · 通用配置
{
"mcpServers": {
"com-foreverworks-anaf-spv": {
"command": "npx",
"args": [
"-y",
"@foreverworks/mcp-anaf-spv"
],
"env": {
"ANAF_SPV_USERNAME": "<ANAF_SPV_USERNAME>",
"ANAF_SPV_PASSWORD_FILE": "<ANAF_SPV_PASSWORD_FILE>",
"ANAF_SPV_MAIL_MCP_URL": "<ANAF_SPV_MAIL_MCP_URL>",
"ANAF_SPV_MAIL_MCP_TOKEN_FILE": "<ANAF_SPV_MAIL_MCP_TOKEN_FILE>",
"ANAF_SPV_MAIL_MCP_COMMAND": "<ANAF_SPV_MAIL_MCP_COMMAND>"
}
}
}
}
启动命令npx -y @foreverworks/mcp-anaf-spv
需要配置的环境变量
ANAF_SPV_USERNAMEYour SPV user name, when the password comes from a file.
ANAF_SPV_PASSWORD_FILE密钥Path of a file holding your SPV password. The README also shows how to read it from a vault MCP server instead.
ANAF_SPV_MAIL_MCP_URLA mail MCP server over Streamable HTTP that reads the mailbox SPV sends its codes to, so a sign-in reads the code by itself. Without one (or a command below), every sign-in asks you for the code.
ANAF_SPV_MAIL_MCP_TOKEN_FILE密钥Path of a file holding that mail server's bearer token, if it wants one.
ANAF_SPV_MAIL_MCP_COMMANDInstead of a URL: a mail MCP server to start over stdio, as a JSON array such as ["npx","-y","some-mail-mcp"].

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

安装包
npm@foreverworks/mcp-anaf-spv0.1.2

工具

16

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

参数类型必填说明
downloadboolean否如果答案的文档存在于发件箱中,则将其保存到发件箱。
save_dirstring否下载发件箱内的文件夹(例如:"2026-10");留空表示发件箱本身。拒绝其外部的路径。
request_idstring是request_document 返回的 request_id。
wait_secondsinteger否持续检查的时长;0 表示只检查一次。

详细介绍

ANAF SPV 图标 ANAF SPV MCP 服务

通过 AI 助手阅读并保存 ANAF 发布到 Spațiul Privat Virtual (pfinternet.anaf.ro) 的内容: 决定、传票、通知、付款确认和答复。它还会申请文档,通过 SPV 的联系表单向 ANAF 写信(除非你另行说明,否则仅为试运行),验证申报表并提交 D212。这里的任何操作都不会转移资金;唯一的 money 工具 submit_declaration 会提交申报表,而且客户端每次调用前都会征求你的同意。

你需要一个个人("persoană fizică")SPV 账户,使用用户名和密码登录,而不是合格证书;一个保存其密码的文件或密码库 MCP 服务;以及一个能够读取 SPV 用于发送登录验证码的邮箱的邮件 MCP 服务(没有邮件 MCP 服务时,需要有人手动输入每个验证码)。验证申报表还需要 Java 8 或更高版本。ANAF 没有面向此类账户的 API,因此该服务会读取 SPV 网页。

你可以询问

  • “我的 SPV 里有 ANAF 发来的新内容吗?”
  • “把 ANAF 上周发布的决定下载到我的 2026-10 文件夹。”
  • “向 ANAF 申请我的 Obligatii de plata 对账单,收到后保存。”
  • “保存我还没有保存的所有 SPV 文档。”
  • “用 ANAF 的验证器检查 d300-2026-09.xml 中的 9 月 D300。应缴多少增值税?”
  • “申报 INTERNT-123456789-2026 的状态是什么?”

安装

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

使用 Claude Code:

claude mcp add anaf-spv -- npx -y @foreverworks/mcp-anaf-spv

Claude Desktop(Settings、Developer、Edit Config)和大多数其他客户端都以 JSON 格式读取同一条命令:

{
  "mcpServers": {
    "anaf-spv": {
      "command": "npx",
      "args": ["-y", "@foreverworks/mcp-anaf-spv"]
    }
  }
}

每种方式都会在 Node 22.19 或更高版本上运行已发布的软件包。VS Code 和 Claude Desktop 安装包会在添加服务时询问各项设置;可选项留空即可。Cursor 则从环境中读取这些设置(例如 ${env:ANAF_SPV_USERNAME}),因此请在启动 Cursor 前设置好。所有设置都是可选的;配置说明了哪些工具需要哪些设置。

从克隆开始
git clone https://github.com/foreverworks/mcps.git && cd mcps
npm ci && npm run build
claude mcp add anaf-spv -- node "$PWD/servers/anaf-spv/dist/index.js"

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

以下是完整配置:通过 HTTP 使用此仓库的 bitwarden 和 google 服务分别作为密码库和邮箱:

claude mcp add anaf-spv \
  -e ANAF_SPV_VAULT_MCP_URL=http://127.0.0.1:<vault port>/mcp \
  -e ANAF_SPV_VAULT_MCP_TOKEN_FILE=<path to the vault token> \
  -e ANAF_SPV_VAULT_ITEM=<item id> \
  -e ANAF_SPV_MAIL_MCP_URL=http://127.0.0.1:<mail port>/mcp \
  -e ANAF_SPV_MAIL_MCP_TOKEN_FILE=<path to the mail token> \
  -e ANAF_SPV_MAIL_ACCOUNT=<mailbox label> \
  -- npx -y @foreverworks/mcp-anaf-spv

docs/onboarding.md 介绍了设置流程,包括使用其他 密码库和邮件服务,或手动输入代码。通过 HTTP 运行时,同一个运行实例会为每个客户端保留一个会话,因此发送的验证码邮件会更少。

配置

所有变量都是可选的,服务均可启动;需要变量的工具会说明具体需求,health 会列出缺少的变量。

密码来源

密码库或文件。优先使用密码库:这样密码只需存放在一个地方,轮换密码时只需在那里更改。

变量必需说明
ANAF_SPV_VAULT_MCP_URL一个来源通过 Streamable HTTP 连接的密码库 MCP 服务,其中存有 SPV 登录信息。
ANAF_SPV_VAULT_MCP_TOKEN_FILE如果密码库需要存放其 bearer token 的文件(本地运行时使用 ANAF_SPV_VAULT_MCP_TOKEN)。
ANAF_SPV_VAULT_MCP_COMMAND替代 URL通过 stdio 启动的密码库 MCP 服务:可以是 JSON 数组(["npx","-y","some-vault-mcp"]),也可以是命令词。该服务会获得此进程的环境变量,但不包括 ANAF_SPV_* 和 MCP_* 变量以及 CREDENTIALS_DIRECTORY。
ANAF_SPV_VAULT_ITEM使用密码库时存放 SPV 登录信息的密码库条目(其 id)。
ANAF_SPV_VAULT_TOOL否用于提供密码的工具。默认值为 get_password(此仓库的 bitwarden 服务)。
ANAF_SPV_VAULT_ARGS否工具的参数,为包含 {{item}} 的 JSON 模板。默认值为 {"id":"{{item}}"}。
ANAF_SPV_VAULT_PASSWORD_FIELD否密码在其 JSON 答案中的位置,以点分隔路径表示。默认值为 password;. 表示使用整个答案。
ANAF_SPV_VAULT_USERNAME_FIELD否用户名所在的位置。默认值为 username。
ANAF_SPV_PASSWORD_FILE另一个来源存放 SPV 密码的文件,权限模式为 0600(本地运行时使用 ANAF_SPV_PASSWORD)。
ANAF_SPV_USERNAME使用文件时SPV 用户名。使用密码库时,它会覆盖条目中的用户名。
邮件验证码来源

邮件 MCP 服务,每次登录时由选定的驱动读取 (邮件驱动)。如果未配置,则每次登录都会等待 complete_login。

变量必需说明
ANAF_SPV_MAIL_MCP_URL自动登录时通过 Streamable HTTP 连接的邮件 MCP 服务,用于读取 SPV 发送验证码的邮箱。
ANAF_SPV_MAIL_MCP_TOKEN_FILE如果需要存放其 bearer token 的文件(本地运行时使用 ANAF_SPV_MAIL_MCP_TOKEN)。
ANAF_SPV_MAIL_MCP_COMMAND替代 URL通过 stdio 启动的邮件 MCP 服务,方式与密码库相同。
ANAF_SPV_MAIL_DRIVER否auto(配置邮件服务时的默认值)、google、text 或 manual(未配置邮件服务时的默认值)。
ANAF_SPV_MAIL_ACCOUNT否指定要使用的邮箱,适用于持有多个邮箱的服务(google 驱动的 account;模板中的 {{account}})。
ANAF_SPV_MAIL_QUERY否搜索条件,默认使用 Gmail 语法:from:[email protected] subject:"Cod de siguranta" newer_than:1d。
ANAF_SPV_MAIL_SEARCH_TOOL否text 驱动使用的搜索工具。默认值:服务中名称类似邮件搜索的工具。
ANAF_SPV_MAIL_SEARCH_ARGS否搜索工具的参数,为包含 {{query}} 和 {{account}} 的 JSON 模板,适用于除查询条件外还需要其他参数的工具。
ANAF_SPV_CODE_WAIT_SEC否登录等待验证码到达邮箱的时长。默认值为 90,最多 280(SPV 的验证码有效期为 300)。
其他所有内容
变量必需含义
ANAF_SPV_KEEPALIVE_MIN否在会话保存期间,每隔 N 分钟加载一个页面,防止 SPV 空闲超时结束会话(每次重新登录都会通过电子邮件发送验证码)。默认值 0 表示关闭。
ANAF_SPV_STATE_DIR否session.json、pending.json、synced.json、contact.json、cui-only.json、declarations.json 和 formularespv-pf 的 forms-session.json 的存放位置,文件权限均为 0600;默认位置见 docs/configuration.md。其中保存着有效会话:请确保只有服务的运行用户可以读取。
ANAF_SPV_DOWNLOADS_DIR否收件箱下载文件的存放位置。默认为 <state dir>/downloads。
ANAF_SPV_JAVA用于申报ANAF 的 DUKIntegrator 所使用的 Java 运行时(8 或更高版本)。默认为 java。
ANAF_SPV_DUK_DIR否DUKIntegrator 工具包的构建和保存位置,每种表格和软件包各一份。默认为 <state dir>/duk。
ANAF_SPV_PORTAL否门户网站。默认为 https://pfinternet.anaf.ro。
ANAF_SPV_FORMS_PORTAL否个人提交申报的门户网站,需要单独登录。默认为 https://formularespv-pf.anaf.ro。
ANAF_SPV_STATUS_SERVICE否ANAF 的申报公开状态服务。默认为 https://stare.anaf.ro/StareD112。

工具接收的文件(申报 XML、附件)会按字节原样传入,并且只能通过路径指定,路径必须位于服务的文件根目录(MCP_FILE_ROOTS)中。文件会以 0640 权限写入发件箱,要么完整写入,要么完全不写入;绝不会覆盖含有其他字节的文件(此时会使用下一个编号的文件名);save_dir 必须是其中的文件夹。在 MCP_EGRESS_ALLOW 中允许 pfinternet.anaf.ro、formularespv-pf.anaf.ro、static.anaf.ro、stare.anaf.ro,以及密码库和邮件服务的主机名。所有服务共用的变量见 docs/configuration.md。

准备好 SPV 账户
  1. 检查该账户能否使用用户名和密码登录 pfinternet.anaf.ro。个人可在 anaf.ro 在线使用身份证件注册,也可前往 ANAF 办事处注册。
  2. 找出 SPV 发送验证码的邮箱(SPV「Editare profil」中的地址):该邮箱会收到来自 [email protected] 的「Cod de siguranta」邮件。
  3. 让账户持有人将用户名和密码放入密码库条目中,或将密码存入只有服务的运行用户可读取的文件中;不要让他们把密码口述给助手。
  4. 授予邮件 MCP 服务读取该邮箱的权限,并将 ANAF_SPV_MAIL_MCP_URL(或 _COMMAND)指向该服务。

首次运行

  1. 请助手运行 SPV 的 health 检查(不联网)。正常结果会显示 automatic_login: true,指出凭据来源和邮件驱动,并且 problems 列表为空。
  2. 请助手获取 SPV 消息(list_messages)。首次调用会登录:SPV 会向账户持有人发送验证码,邮件驱动会读取该验证码,因此账户持有人可以忽略这封邮件。消息按最新优先的顺序返回,每条消息都有一个 key。
  3. 如果工具返回 needs_login,请在五分钟内将最新验证码传给 complete_login(参见故障排除);如果没有邮件服务,每次登录都会以这种方式结束。
  4. 下载一条消息(使用其 key 调用 download_message),然后每天运行 sync_messages:SPV 通常会在发布约两个月后删除大多数文件。

工具

读取不会更改 ANAF 中的任何内容(某些工具会将文件保存到发件箱);写入会更改此服务持有的会话(登录会促使 SPV 发送验证码),或向 ANAF 发送非税务文件;资金操作会提交申报,客户端会在每次调用前征求你的确认。

会话
工具访问权限功能
health读取凭据和验证码的来源、是否已存储会话,以及登录是否在等待验证码。不联网。
session_status读取已存储的会话、存储时间、上次正常工作的时间;probe 会加载页面以确认会话仍有效。
login写入立即登录(任何工具在需要时都会执行);code_by_hand 会在验证码处停止。
complete_login写入完成正在等待邮件验证码的登录。
logout写入在 SPV 登出并忘记会话。
消息
工具访问权限功能
list_messages读取按类型、日期、税号、请求或关键词筛选的消息列表,按最新优先排序;每条消息都包含 key、发布时间以及 SPV 将其归档的时间。
download_message读取下载一条消息的文档,将其保存到发件箱并附上 SHA-256。
sync_messages读取按从最早到最新的顺序保存之前尚未保存的所有消息:SPV 不会保留的存档。
posting_dates读取从 SPV 的提醒邮件中获取 SPV 发布文档的时间:SPV 将其归档后仍可留存的记录。
请求与联系表单
工具访问权限功能
list_document_types读取查看实时请求表单提供的文档类型,以及每种类型需要填写的字段。
request_document写入向 SPV 请求文档;免费,答复会以消息形式送达。
await_reply读取等待请求的答复(每次调用最多 120 秒),并保存答复。
submit_contact_form写入通过 SPV 的联系表单向 ANAF 发信;默认执行试运行,发送后会返回登记号。
申报表
工具访问权限功能
validate_declaration读取使用 ANAF 自有验证器验证 D212、D100、D300 或 D112 及其所属期间:逐字返回错误、应缴金额,以及经检查确认包含 XML 的申报 PDF。
submit_declaration资金操作在 formularespv-pf 提交 D212 的 PDF:返回 index de depunere,然后返回 SPV 的 RECIPISA。D100、D300 或 D112 的 PDF 会经过检查,但在发送任何内容前会被拒绝。
declaration_status读取根据申报编号,通过 ANAF 的公开状态页面查询申报在 ANAF 的状态及其签名回执。无需登录。

资金操作

submit_declaration 会以账户持有人的名义提交申报表,无法撤回,只能更正。它在 tools/list 中标记为 money,并且客户端会要求你批准每次调用(Claude Code 在所有权限模式下都会这样做)。它只会提交由 validate_declaration 生成并 检查过的 PDF(通过 SHA-256、文件大小和嵌入的 XML 检查),只会在 confirm: true 时提交;除非 refile 为 true,否则相同字节内容只会提交一次 (即使提交后始终未收到答复,也算作已提交)。设置 MCP_CONFIRM=elicit 时, 服务会直接询问你确认:从 PDF 中读取一行,列出将要发送的字节内容对应的 表格类型、所属期间和纳税人。

anaf-spv: File D212 for reporting year 2025 for 2990101999999 at ANAF (D212_an-2025_0123456789ab.pdf, 123456 bytes, sha256 abcdef012345); a filed declaration cannot be withdrawn, only rectified

对于公司的表格,这一行还会列出公司名称以及申报表所列的应缴金额:

anaf-spv: File D100 for 09.2026 for 99999909 (EXEMPLU TEST SRL) at ANAF, to pay 1850 lei (121: 1250, 150: 600) (D100_2026-09_fedcba987654.pdf, 34567 bytes, sha256 0123456789ab); a filed declaration cannot be withdrawn, only corrected by a D710

ANAF 只接受通过 e-guvernare.ro 提交的 D100、D300 或 D112,并且必须由有权 代表公司申报的人使用合格证书签名,而本服务不持有此类证书。因此, submit_declaration 会检查此类 PDF,然后在发送任何内容前返回 unsupported; 该 PDF 已可供签名并上传至该网站。

故障排除

needs_login,状态为 awaiting_code 或 code_not_received。 没有驱动程序读取邮件(manual、code_by_hand),或未能在 ANAF_SPV_CODE_WAIT_SEC 内收到新验证码。请在答案中的 expires_at 到期前,将最新验证码传给 complete_login。如果驱动程序本应读取验证码,请检查邮箱、搜索结果是否显示邮件正文,以及 ANAF_SPV_MAIL_QUERY 的语法。

needs_login,状态为 pending_expired,或 login_refused,阶段为 step: code。 验证码是在 SPV 的五分钟有效期后才收到的,或验证码错误、已过期。请再次调用 login,并且只传入最新验证码。

login_refused,阶段为 step: password。 SPV 拒绝了用户名或密码(错误信息中会说明原因)。修正凭据来源的 health 名称,然后调用 login。不要循环重试:多次失败可能会锁定账户。

upstream。 密钥库或邮件服务(source)发生故障。请检查它是否有响应,以及密钥库是否包含 ANAF_SPV_VAULT_ITEM。即使没有邮件服务,也可以使用 code_by_hand: true 调用 login,然后调用 complete_login 完成登录。

config 并指出某个变量。 按照配置设置该变量,然后重试;请求尚未到达 SPV。

not_found。 没有该键对应的消息,或尚未收到回复。list_messages 会列出所有键;调用 request_document 后,通常一两分钟就会收到回复。

refused。 SPV 用其自己的措辞拒绝了请求,或拒绝了 formularespv-pf 文件。对于请求,list_document_types 会列出每种类型需要的字段。

wrong_document。 SPV 返回的文件名称对应另一条消息;没有保存任何内容。请重新下载同一个键;如果问题再次出现,请报告此问题。

unsupported。 该申报需要本服务不具备的功能(Money)。没有发送任何内容;错误信息会说明 PDF 可以发送到哪里。

api。 状态码为 0:无法连接 SPV。其他状态码:SPV 发生故障,这种情况在夜间维护期间和周末时常出现。请稍后重试。

drift。 SPV 的页面发生了变化,导致本服务无法正常工作。服务需要更新;请报告此问题。

工作原理

登录

SPV 的入口是 F5 访问策略(/my.policy),包含两个表单:先输入用户名和密码,再输入通过电子邮件发送的验证码;验证码有效期为 300 秒。随后会话仅由 Cookie 维持,并以 0600 权限存储。页面将客户端重定向回 /my.policy 时,说明会话已结束:工具会重新登录并再次调用。多个调用方同时遇到这种情况时,只会触发一次验证码发送,而不是两次(每个状态目录同时只进行一次登录)。每次登录时都会读取凭据,但绝不会保存;凭据和验证码都不会出现在答案、审计日志或状态目录中。

邮件驱动程序

只能通过 MCP 服务访问邮箱;驱动程序决定如何查询邮箱。

  • google:适配为类似本仓库 Google 服务的 MCP 服务(search_threads、get_thread)。它会从 SPV 的 Gmail 邮件会话中,选取登录开始后(为应对时钟偏差,时间范围提前一分钟)收到的最新验证码,且该验证码此前未出现过。
  • text:使用带有搜索工具的任意邮件服务。它会在发送密码前记录搜索结果中显示的验证码,然后持续搜索,直到出现新的验证码。除非 ANAF_SPV_MAIL_SEARCH_TOOL 和 _ARGS 指定工具及其参数,否则它会根据 tools/list 推断工具和查询参数。
  • auto:如果服务具备上述两个工具,则使用 google;否则使用 text。
  • manual:每次登录都会停在 awaiting_code 状态。

如果驱动程序未能及时发现新验证码,就会保留待完成的登录状态,以便调用 complete_login;邮箱响应慢只会导致需要手动输入验证码,不会丢失登录状态。

消息和下载

消息由 key 命名,它是对消息行所示内容计算出的哈希值:SPV 不会为行分配 ID,只提供一个下载链接,表示该行在最近一次渲染的列表中的位置。因此,下载时会先获取列表,并确保列表及其下载全部完成后,才允许同一状态目录下的任何进程访问门户(portal.lock);否则,中途发布的回复会导致行位置变化,使某个请求的 PDF 被保存到另一条消息的元数据下。

文件名会与对应的行进行核对。 文件名包含其他行的 ID 时,会以 wrong_document 失败,且不会保存任何内容;文件名不含此类 ID(例如决定书的 SV<number>.pdf)时,则会被接受。

文件字节由 SPV 提供。 SPV 每次都会提供相同的已签名 PDF,因此再次下载时会命中首次下载的文件。行会在其 Data Arhivare 到期后永久从列表中移除,该时间通常是发布后约两个月(缴款记录为十年)。

发布日期

在 SPV 发布的法案,以其可供查阅之日视为已送达,该日期也开始计算提出异议的期限(《财政程序法典》第 47 条第(15)款);行从列表中消失后,SPV 就不再显示该日期。SPV 的“Documente noi SPV”提醒邮件由 [email protected] 发出,是长期保存的记录:posting_dates 会通过一个与此代码库的 Google 邮件服务器格式相同的邮件服务器读取这些邮件。

请求

请求表单自身的脚本决定每种类型使用年份、月份、登记号和 PUI 中的哪些字段;src/domain/requests.ts 与之保持一致。SPV 通常会在几分钟内回复已登记的请求,并发送一条带有其 ID 的 RASPUNS SOLICITARE 消息。个人列表中的某些类型仅适用于公司,SPV 会拒绝 CNP 对这些类型的请求。list_document_types 会在 cui_only 下列出这些类型,request_document 则会拒绝它们:“Notificare”以及 SPV 以这种方式拒绝的其他类型(cui-only.json)。不会逐一探测类型,因为有些请求会生成真实文件。

联系表单

SPV 联系表单要求提供身份信息、类别(类别 1、2 和 5 还需选择子类别)、最多 1,500 个字符的内容,以及一个附件(pdf、tiff、rtf、zip、jpeg、jpg、gif 或 png,最大 10 MB)。ANAF 之后会在 SPV 中回复已发送的消息。

  • cif 为必填项,并会回读:表单会预选第一个身份;对于同时代表一家公司的用户,会预选该公司。
  • 类别 3 为默认类别(“Asistență și îndrumare de specialitate în domeniul fiscal”),会得到实质性答复;请愿(类别 1)则会被转交。
  • 默认执行试运行,展示消息实际发送时的内容:去除变音符号,将排印符号转换为普通字符,并显示附件名称和 SHA-256。
  • 同一条消息不会发送两次,除非设置 again: true;即使帖子始终没有收到回复也是如此(contact.json)。没有登记号的页面会被视为 refused:表单会原样返回一条无效帖子的回复。
申报

往年申报没有网页表单(Declarația unică 应用只支持当前年度),公司的申报则使用 ANAF 自己的程序。因此,服务会按 ANAF 为 Linux 记录的方式运行 ANAF 的“soft J”:使用对应期间软件包中的验证器和 PDF JAR 文件,通过 DUKIntegrator 处理(曾使用虚构的 D100、D300 和 D112 申报进行测试)。

  • 每种表格和软件包只构建一次工具包,存放于 ANAF_SPV_DUK_DIR;每个文件的来源和 SHA-256 都记录在 kit.json 中。没有软件包覆盖的期间会被拒绝,不会使用最接近期间的软件包进行验证。
  • D212 每个申报年度都有一个软件包(申报年度,即提交的年份:2023 年申报 2022 年的收入);使用其他年度的软件包会导致验证失败。D100、D300 和 D112 的一个软件包可覆盖多个期间,因此最新的软件包也能验证较早月份的申报。
  • 验证结果取自 DUKIntegrator 的输出,因为它无论结果如何都会以 0 退出;错误会原样返回。
  • PDF 内嵌 XML 文件,只有确认内嵌文件与已验证的 XML 逐字节完全一致后,才会保存 PDF。
ANAF 的软件包

来源为 static.anaf.ro 上的表单页面(D212 对应 Declaratii_R/declaratie_unica.html, 以及 100.html、300.html、112.html),每个验证器的期间表,以及 update5 的 versiuni.xml 中的版本信息。测试会将此表与 src/domain/declarations/kits.ts 比对;ANAF 发布新版本时,就新增一行。

表单软件包期间版本发布日期实现内容
D212D212_20200622.zip2020 申报年度2020-06-22
D212D212_20210512_1607.zip2021 申报年度2021-05-12
D212D212_20220301.zip2022 申报年度2022-03-01
D212D212_20231002.zip2023 申报年度2023-10-02
D212D212_20240708.zip2024 申报年度2024-07-08
D212D212Validator_01082025.zip2025 申报年度J13.0.1, PDF P10.0.02025-08-01
D100D100_14092026.zip2024 年 01 月起J21.0.8, PDF P6.0.02026-09-14OPANAF 57/2026,自 2026 年 01 月起;义务代码 704,自 2026 年 08 月起
D300D300Validator_11022026_2.zip2024 年 05 月起J12.0.1, PDF P9.0.02026-02-11OPANAF 174/2026,结构 v12,自 2026 年 01 月起
D112D112_09102026.zip2025 年 01 月起J27.0.7, PDF P3.0.12026-10-09联合命令 605/95/928/2314/2026,结构 v7,自 2026 年 07 月起
申报表的应付款项

对于 D100、D300 或 D112,根据表单自身规则(“Anexa validari”)从 XML 中读取金额, 以整列伊计算并精确求和:D100 按义务代码读取 suma_plata(应付款)和 suma_rest(应退款),其根节点的 totalPlata_A 仅为校验总和;D300 读取 R41_2(应缴增值税)和 R42_2(负余额;若 solicit_ramb 为 D,则退款,否则结转); D112 按义务代码读取 A_plata,其总和必须等于 totalPlata_A,否则文件会在验证前被拒收。

提交 D212

submit_declaration 使用 SPV 用户名、密码和通过电子邮件发送的验证码登录 formularespv-pf.anaf.ro,并在独立会话中操作(两者共用一个地址发送验证码,因此同一时间只能登录一个)。 文件获接受后会获得一个 index de depunere。几秒内,SPV 会发布一份 DECLARATIE (<index>_depunere.pdf)和一份 RECIPISA;工具会下载两者,并告知 DECLARATIE 是否包含该索引。 RECIPISA 中会列出 index de încărcare,这是一个无关的编号,ANAF 的状态服务通过它识别申报。 declarations.json 会记录生成的每份 PDF 及其后续状态。

申报状态

declaration_status 无需登录即可读取 ANAF 的公开状态页面 stare.anaf.ro/StareD112(旧的 www.anaf.ro 地址会重置连接)。对于 index de încărcare 和税号,它会列出最近三个月内的最后 200 份申报:ANAF 状态(processing、 not_registered、附有回执错误信息的 validation_errors,或 valid)、登记编号 INTERNT-<index>-<year>,以及有效期为 60 天的已签名回执(工具会保存该回执)。 它也接受登记编号或 index de depunere。

scripts/smoke.ts 会驱动已构建的服务连接真实 SPV。除非传入 --request "<type>", 否则不会在 ANAF 执行任何操作;该参数会登记一项免费的文件请求。

限制

  • 仅支持用户名、密码和电子邮件验证码。 不支持使用合格证书登录的账户。
  • 这里只提交 D212。 四种表单都会在上述软件包覆盖的期间内进行验证;D100、D300 或 D112 需通过 e-guvernare.ro 提交(资金)。不提供申诉功能。
  • declaration_status 仅能查看三个月内的记录,这是 ANAF 状态页面列出的最早日期; 更早的申报需通过“Duplicat Recipisa”请求查询。
  • 不会读取文件内容。 它会返回 SPV 的元数据和文件;读取 PDF 是调用方的工作 (目前试过的每份文件都可用 pdftotext 读取)。
  • 每个服务仅支持一个账户。 如果某人也代表一家公司,当 SPV 将两者关联到同一登录名时, 同一个列表(cif)中会显示两者。

ANAF SPV 的其他服务

搜索日期:2026-10-15。ANAF 未发布任何服务,其 SPV Web 服务(SPVWS2,仅在其 2019 年示例客户端 MfpAnaf/ClientSPV 中有文档说明)只接受合格证书。只有一个社区服务使用了它;在 npm、PyPI、GitHub 或 MCP Registry 上均未发现其他相关项目:

  • anafpy(PyPI,Python,stdio):列出消息、保存消息的 PDF、请求报告并等待报告生成;登录时使用操作系统密钥库中的合格证书和 PIN。

本服务面向 anafpy 无法处理的账户,这些账户使用用户名、密码和通过电子邮件发送的代码登录:它会自动登录,逐字节保存每份文档并记录其 SHA-256,保留归档,并通过 HTTP 为每个客户端维持一个会话。若有合格证书,anafpy 更合适。

评论

支持 Markdown

第一次接触 MCP?

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

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