关于 ANAF SPV
ANAF SPV MCP 服务让个人账户通过 AI 助手读取 SPV 消息、请求文件并处理申报。它还可验证申报并提交 D212;提交申报属于写操作,客户端会逐次请求确认。
主要功能
- 01读取并筛选 SPV 消息
- 02下载并归档文件
- 03通过联系表单请求文件
- 04验证申报并查看状态
- 05提交 D212 申报
适用场景
- 01检查 ANAF 是否发布新通知
- 02保存尚未下载的 SPV 文件
- 03验证 D300 XML 并查看应缴 VAT
- 04查询已提交申报的状态
MCP 相关
向 MCP 客户端提供 SPV 会话、消息、文件请求及申报工具;登录验证码可由邮件 MCP 服务读取,也可手动输入。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y @foreverworks/mcp-anaf-spvANAF_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+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
16收录的工具列表 · 更新于 2 天前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| download | boolean | 否 | 如果答案的文档存在于发件箱中,则将其保存到发件箱。 |
| save_dir | string | 否 | 下载发件箱内的文件夹(例如:"2026-10");留空表示发件箱本身。拒绝其外部的路径。 |
| request_id | string | 是 | request_document 返回的 request_id。 |
| wait_seconds | integer | 否 | 持续检查的时长;0 表示只检查一次。 |
详细介绍
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 的状态是什么?”
安装
使用 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 账户
- 检查该账户能否使用用户名和密码登录 pfinternet.anaf.ro。个人可在 anaf.ro 在线使用身份证件注册,也可前往 ANAF 办事处注册。
- 找出 SPV 发送验证码的邮箱(SPV「Editare profil」中的地址):该邮箱会收到来自
[email protected]的「Cod de siguranta」邮件。 - 让账户持有人将用户名和密码放入密码库条目中,或将密码存入只有服务的运行用户可读取的文件中;不要让他们把密码口述给助手。
- 授予邮件 MCP 服务读取该邮箱的权限,并将
ANAF_SPV_MAIL_MCP_URL(或_COMMAND)指向该服务。
首次运行
- 请助手运行 SPV 的
health检查(不联网)。正常结果会显示automatic_login: true,指出凭据来源和邮件驱动,并且problems列表为空。 - 请助手获取 SPV 消息(
list_messages)。首次调用会登录:SPV 会向账户持有人发送验证码,邮件驱动会读取该验证码,因此账户持有人可以忽略这封邮件。消息按最新优先的顺序返回,每条消息都有一个key。 - 如果工具返回
needs_login,请在五分钟内将最新验证码传给complete_login(参见故障排除);如果没有邮件服务,每次登录都会以这种方式结束。 - 下载一条消息(使用其
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 发布新版本时,就新增一行。
| 表单 | 软件包 | 期间 | 版本 | 发布日期 | 实现内容 |
|---|---|---|---|---|---|
| D212 | D212_20200622.zip | 2020 申报年度 | 2020-06-22 | ||
| D212 | D212_20210512_1607.zip | 2021 申报年度 | 2021-05-12 | ||
| D212 | D212_20220301.zip | 2022 申报年度 | 2022-03-01 | ||
| D212 | D212_20231002.zip | 2023 申报年度 | 2023-10-02 | ||
| D212 | D212_20240708.zip | 2024 申报年度 | 2024-07-08 | ||
| D212 | D212Validator_01082025.zip | 2025 申报年度 | J13.0.1, PDF P10.0.0 | 2025-08-01 | |
| D100 | D100_14092026.zip | 2024 年 01 月起 | J21.0.8, PDF P6.0.0 | 2026-09-14 | OPANAF 57/2026,自 2026 年 01 月起;义务代码 704,自 2026 年 08 月起 |
| D300 | D300Validator_11022026_2.zip | 2024 年 05 月起 | J12.0.1, PDF P9.0.0 | 2026-02-11 | OPANAF 174/2026,结构 v12,自 2026 年 01 月起 |
| D112 | D112_09102026.zip | 2025 年 01 月起 | J27.0.7, PDF P3.0.1 | 2026-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 更合适。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。