ANAF e-Factura

com.foreverworks由 foreverworks.com 發布v0.1.1更新於 Nov 3, 2026

Read, check and file a Romanian company's e-invoices and e-Transport declarations with ANAF.

發布方自己的服務:factura.bo

概覽

AI 產生的概覽

讀取、驗證、產生並向羅馬尼亞 ANAF 申報公司的 e-Factura 發票與 e-Transport 申報,包含簽章壓縮檔、PDF 和加值稅登記查詢。

可以做什麼
  • 列出、分頁瀏覽並下載 e-Factura 訊息,把簽章壓縮檔和 ANAF 產生的 PDF 存到本機寄件匣
  • 讀取、驗證和產生 UBL 發票與貸項通知,並核驗已存檔案上的 ANAF 印章
  • 向公司或個人申報發票,並追蹤每次上傳的處理狀態
  • 列出、申報並查詢 e-Transport 申報的狀態
  • 依 CIF 在 ANAF 公開加值稅登記中查詢公司
  • 檢查、更新並重新建立已儲存的 ANAF 授權
適用情境
適合已在使用 ANAF e-Factura 的羅馬尼亞公司,讓助理檢視收發發票、核驗 ANAF 印章、準備並驗證發票 XML,或申報發票與 e-Transport 申報。也適合希望作業留在本機、在本機核驗印章並預設先走測試環境的情境。
執行需求
透過 npx 以 stdio 在本機執行,需要 Node 22.19 或更新版本。需要向 ANAF 註冊的 OAuth 應用程式(client id、secret、回呼網址)和公司 CIF,寫在 app.json 中,其路徑由 ANAF_CONFIG 指定;可選 ANAF_STATE_DIR 和 ANAF_DOWNLOADS_DIR 指定權杖與檔案的存放位置。授權需要一位持有合格數位憑證並具備 SPV 權限的人在瀏覽器登入一次。需要能連上 ANAF 網路;e-Transport 工具需要 ETRANSPORT 角色。
安裝前請注意
upload_invoice、upload_invoice_b2c 和 etransport_file 三個工具會向 ANAF 申報檔案,檔案會送達對方且無法撤回;除非把 test 設為 false,否則只送往測試環境,用戶端應在每次呼叫前請求確認。app.json 含 ANAF 用戶端密鑰,須妥善保管。權杖和正式申報紀錄存放在狀態目錄中,更新會輪替 refresh token,授權失效後需憑證持有人重新操作。每則訊息每天最多下載 10 次。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 ANAF e-Factura,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

[ANAF e-Factura icon] ANAF e-Factura MCP server

Read the invoices your company sent and received through Romania's e-Factura, check ANAF's seal on them, and file invoices and e-Transport declarations with ANAF, from your AI assistant. It also validates, renders and writes invoices, and looks companies up in ANAF's VAT registry. Its three money tools (upload_invoice, upload_invoice_b2c, etransport_file) file a document that cannot be withdrawn: your client asks you before each call, and each goes to ANAF's test environment unless you say otherwise.

You need an OAuth application registered with ANAF (its client id, secret and callback URL), the company's CIF, and a person with a qualified digital certificate and SPV rights for the company, who signs in once in a browser. The server then renews the grant itself, and its --health check warns two weeks before it would need that person again. Validating, rendering, building and reading an invoice, checking a seal and looking up a company need no account.

What you can ask

  • "Which invoices did suppliers send us in the last two weeks?"
  • "Download the newest invoice we received, check ANAF's seal on it, and list its lines."
  • "Is RO87654329 a VAT payer, and does it apply VAT on collection?"
  • "Invoice Client SRL for 10 hours of consulting at 500 RON an hour plus 21% VAT, have ANAF validate it, and file it in the test environment."
  • "How many days are left on our ANAF authorization?"

Install

[Install in VS Code] [Install in Cursor] [Download for Claude Desktop]

With Claude Code:

bash
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) and most other clients read the same command as JSON:

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

Each runs the published package on Node 22.19 or newer. VS Code and the Claude Desktop bundle ask for ANAF_CONFIG as they add the server. Cursor reads it from your environment instead (${env:ANAF_CONFIG}), so set it before you start Cursor. Configuration says what it holds.

From a clone

bash
git clone https://github.com/foreverworks/mcps.git && cd mcpsnpm ci && npm run buildclaude mcp add anaf-efactura -e ANAF_CONFIG="<path to ANAF app.json>" -- node "$PWD/servers/anaf-efactura/dist/index.js"

In a JSON configuration, the command is node and its one argument the full path of servers/anaf-efactura/dist/index.js. To share one running copy between several clients over HTTP, see docs/deploying.md.

Configuration

VariableRequiredMeaning
ANAF_CONFIGyesPath of app.json (below), which the server only reads.
ANAF_STATE_DIRnoWhere the grant, a begun authorization and the ledger of production filings go; the default is in docs/configuration.md.
ANAF_DOWNLOADS_DIRnoThe outbox for downloaded archives, PDFs and built invoices; default <state dir>/invoices.

app.json holds the application you register with ANAF (below):

json
{  "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 and client_secret are required, and authorizing needs redirect_uris. company_cif (or cif) is the company a call acts on when it names none; one grant can cover several companies, so a cif argument overrides it. endpoints overrides ANAF's URLs by name (authorize, token, hello, fctelProd, fctelTest, etransportProd, etransportTest), and api_base / api_test_base the e-Factura bases. The server never writes app.json, and its errors name a bad field, never a value. Without ANAF_CONFIG the server still starts, and the tools that need no grant work.

Getting the client id and secret

ANAF calls this registering an application in an OAuth profile; its procedure, Oauth_procedura_inregistrare_aplicatii_portal_ANAF.pdf (in Romanian), shows each screen.

  1. Check that the person who will sign in is registered in SPV with their qualified certificate and one of the company's rights: legal representative, designated representative or empowered person (reprezentant legal, reprezentant desemnat, împuternicit).
  2. Create a developer account at anaf.ro/InregOauth (Servicii Online, Înregistrare utilizatori, Dezvoltatori aplicații, "Înregistrare pentru API-uri"), new or from a portal account you have, and confirm your e-mail with the "Cod de verificare" ANAF sends.
  3. Sign in ("Autentificare utilizator"), open "Editare profil Oauth", then "Gestionare aplicații".
  4. Name the application, choose its services (E-Factura, and E-Transport for the e-Transport tools), and give a Callback URL you control, such as https://example.com/anaf/callback; nothing has to answer there. Press "Generare Client ID".
  5. Click the application in the list, and copy its Client ID, Client Secret and Callback URL into app.json.

The grant may do only what both the application's services and the certificate holder's SPV rights allow; health shows its roles (EFACTURA, ETRANSPORT).

Files in and out

A document goes in byte for byte, never as text a model retyped, because ANAF's seal covers the exact bytes: by path from the server's file roots (MCP_FILE_ROOTS; over stdio, the client's folders or the working directory), or as { "content_base64": "...", "sha256": "..." } from a script. A link, a file outside the roots, a wrong checksum or a document that is not UTF-8 is refused before anything is sent. A path in the outbox is taken too, so build_invoice's file goes straight to validate_invoice and upload_invoice.

Files come out into the outbox at mode 0640, whole or not at all, and never over a file holding other bytes (that one gets the next numbered name, such as 5001-2.zip); a save_dir must be a folder inside it. The state dir holds tokens.json, authorization.json and uploads.json at 0600. Neither the state dir nor the outbox may sit inside app.json's directory. The variables every server shares are in docs/configuration.md.

First run

The tools that read or file at ANAF need a grant, which only the certificate holder can give. Ask your assistant to authorize the server with ANAF:

  1. begin_authorization answers ANAF's sign-in page for your application (authorizeUrl), open for 30 minutes; redirect_uri picks one of several callback URLs. A client that shows links itself (MCP URL elicitation: over stdio, or over HTTP with a client of protocol 2026-07-28, as Claude Code is) offers you the page; if you do not hold the certificate, decline and pass the address on.
  2. The certificate holder opens it in the browser where the certificate is installed, picks the certificate, and signs in.
  3. The browser lands on the callback URL, with ?code=...&state=... in the address. The page may fail to load; the address is what counts.
  4. Pass that whole address to complete_authorization (redirect_url) at once: ANAF's code dies 60 seconds after it is issued. The server checks the state, exchanges the code, writes tokens.json, and answers only the two expiry dates; no token reaches the conversation.
  5. Ask for health: the grant's roles and the days left on each token.

Keeping the grant alive

ANAF's procedure (pp. 28 and 33) gives the access token 90 days (or the exp it states) and the refresh token 365. A call within 3 days of the access token's end refreshes it first (refresh_token with force refreshes now), and each refresh brings a refresh token good for another 365 days. If the refresh token runs out or ANAF refuses it (invalid_grant), only the certificate holder can bring the grant back, by repeating the steps above. For a server used rarely, refresh daily from a timer. From a clone, in servers/anaf-efactura:

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

Each prints one ANAF: OK|WARN|FAIL ... line, never a token, and exits 0 for OK, 1 for FAIL (a person has to act: a dead grant, a broken configuration) or 2 for WARN (ANAF unwell, or the refresh token ends within 14 days).

Tools

read changes nothing at ANAF (some save files to the outbox); write changes the stored grant; money files a document with ANAF, and your client asks you before each call.

ToolAccessWhat it does
healthreadGreets ANAF with the stored token: the application, the default CIF, the grant's roles, the days left on each token. Only the greeting's first line comes back, because ANAF echoes the bearer token in it.
token_statusreadThe stored grant's expiries and roles, without calling ANAF.
refresh_tokenwriteA new access token when the current one is within 3 days of its end, or now with force.
begin_authorization / complete_authorizationwriteA new grant: ANAF's page for the certificate holder, then the address their browser landed on.
list_invoicesreade-Factura messages from the last zile days, at most 60: sent, received, errors and buyer messages, with the id download_invoice takes.
list_invoices_windowreadThe same over a date range of at most 60 days, a page at a time, filtered by filtru (E errors, T sent, P received, R awaiting a response).
download_invoicereadSaves one signed ZIP to the outbox once it opens, every entry matches its checksum, and ANAF's seal holds. ANAF allows 10 downloads a day per message.
upload_invoicemoneyFiles an invoice XML (UBL, CII, CN or RASP) to a company. Test environment unless test is false.
upload_invoice_b2cmoneyFiles an invoice to a person through ANAF's /uploadb2c, otherwise as upload_invoice.
upload_statusreadHow an upload was processed: ok (with its download id), processing, or failed with ANAF's reasons.
etransport_listreade-Transport declarations from the last zile days, at most 60: UIT, declarant, partner, carrier, vehicle, and ANAF's reasons for one it refused.
etransport_filemoneyFiles a declaration XML (schema v2): a new transport, a correction, a deletion, a confirmation or a vehicle change. Test environment unless test is false.
etransport_statusreadHow a declaration was processed: ok (the UIT is valid from now), processing, or failed.
build_invoicereadWrites a CIUS-RO invoice (UBL) from fields into the outbox, totals computed exactly and the draft checked first. Files nothing.
parse_invoicereadA UBL invoice or credit note (a file, or an archive in the outbox) as JSON, every value the document's own text. Calls nothing.
validate_invoicereadANAF's own validation of a UBL invoice or credit note (schema, EN 16931 and CIUS-RO rules), without filing it.
invoice_pdfreadANAF's PDF of a UBL document, or of a filed invoice by message_id, saved to the outbox.
verify_signaturereadWhether an invoice is the file ANAF stored, under ANAF's seal: checked locally against a pinned CA, ANAF asked only when that cannot decide.
lookup_companyreadUp to 100 CIFs in ANAF's VAT registry, as of a date: identity, registered office, VAT payer and period, VAT on collection, split VAT, inactive, RO e-Factura registry.

The last six need no grant, except invoice_pdf and verify_signature given a message_id; the e-Transport tools need the ETRANSPORT role. The tools that call ANAF take cif (by default app.json's) and test: listings and downloads read production unless test is true, while the three filing tools and the two status tools use the test environment unless test is false, so a status is asked where its filing went.

Money

upload_invoice, upload_invoice_b2c and etransport_file file a legal or fiscal document with ANAF, which reaches the counterparty and cannot be withdrawn (undoing an invoice takes a credit note). They are marked money in tools/list, and your client asks you to approve each call (Claude Code does, in every permission mode). Whoever confirms, three rules hold:

  • Test unless you say otherwise. Each goes to ANAF's test environment, where a filing has no legal effect, unless test is false.
  • The same bytes are not filed twice in production unless refile is true. The SHA-256 of a production filing's exact bytes goes into a ledger (uploads.json) before it is sent; a filing ANAF refused, or one that never left, does not count.
  • A lost answer is never resent. A dropped connection, a 5xx or an undocumented answer fails as outcome_unknown, because the filing may have happened (Troubleshooting).

The file is read once, before you are asked, so the line you confirm and the filing come from the same bytes. With MCP_CONFIRM=elicit the server asks you itself, in one line read from the XML and ending with the file's 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 3f1c0a9e27b4anaf-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

A test upload's line starts TEST upload to ANAF's test environment (no legal effect), an invoice to a person reads B2C invoice, and a refiling adds AGAIN (refile). Amounts are the document's own decimal strings; the e-Transport value is the exact sum of the goods' valoareLeiFaraTva. A document the server cannot read says UNREADABLE XML: answer no.

Before you are asked, the check digits must hold on every IBAN an invoice names for payment (BT-84, BT-91), the seller's CIF, an e-Transport declarant's CIF or CNP, and every UIT (whose check digits, by ANAF's rule BR-019, catch a wrong character but not two swapped ones). A new UIT counts only once etransport_status says ok.

Troubleshooting

config: "tokens at ... are missing or unparseable". No grant is stored yet, or the file is damaged: authorize as in First run.

config naming ANAF_CONFIG, a field of app.json, company_cif, or "... is inside app.json's directory". Fix the variable or field, pass cif, or move ANAF_STATE_DIR / ANAF_DOWNLOADS_DIR away from app.json.

auth with invalid_grant, refresh_expired, invalid_client or unauthorized_client. The grant is dead: authorize again. Any other auth code is ANAF failing for now: retry later.

input: "the state in that address is not the one begin_authorization issued", or "begun more than 30 minutes ago". The address is from an older tab, or the window closed: call begin_authorization again, and pass the new address at once (a code older than 60 seconds fails as auth).

api with status 401 or 403. ANAF refused the token for this CIF or role (token_status shows the roles). The e-Transport tools need ETRANSPORT: add the service to the application at ANAF, then authorize again.

api with reason: "outcome_unknown", or input: "this exact file ... was already sent to ANAF production". The filing may have reached ANAF, or these bytes already did. Look first (upload_status with test: false, list_invoices, etransport_status or etransport_list), and pass refile: true only to file the same bytes again on purpose.

input: "the invoice was not sent", "the declaration was not sent" or "the invoice was not built". A check digit or a rule failed; the message names each. Fix the document, or build_invoice's fields.

validate_invoice finds only ERRIdentif "nu a fost identificat cui cumparator". The buyer is foreign, which ANAF's validator cannot be told, so this finding is expected. Upload with extern: true, which build_invoice answers for such a buyer.

checksum_mismatch. The bytes that arrived are not the file sha256 names, as when a model retypes base64. Nothing was sent: send the file by path, or let a script encode it.

api with status 0: ANAF was unreachable, or its answer lacked a field the call needs; retry later. "... answered in a shape ANAF does not document": ANAF's answer changed and the server refuses to guess; please report it.

How it works

What comes back. ANAF's wire shape stays inside the server: a listed message has a kind (sent, received, error, buyerMessage, unknown) and details with the upload id and both CIFs, lifted out of ANAF's prose. createdAtLocal is zoneless on purpose, because ANAF stamps Bucharest time without saying so; a date window is UTC, so it reads the same anywhere. notice is set when ANAF refused with HTTP 200 and an eroare key ("no messages in this period" included): reading that as an empty list would be the most expensive kind of wrong. cui, on a real answer the certificate holder's CNP, is never echoed.

ANAF's seal. download_invoice keeps an archive only once every entry matches its CRC and ANAF's seal (semnatura_<id>.xml) holds: a detached XML-DSig signature whose digest is the SHA-256 of the invoice file's raw bytes (so a re-indented copy is not the sealed file), by a certificate issued to Ministerul Finanțelor by "Trans Sped Electronic Seal QCA G3". verify_signature checks that locally: the certificate must come from the pinned CA (src/infra/sealTrust.ts) and not have expired before the invoice's date, the RSA signature must verify, and then the digest decides. So a swapped certificate fails the CA check, and a digest rewritten for a changed invoice fails the signature. Anything short of a verified signature goes to ANAF's public /api/validate/signature, and checkedBy says who answered. npx tsx scripts/check-seals.ts <folder> runs the check offline.

Building an invoice. build_invoice totals by EN 16931's rule, which ANAF checks (each line rounded to 2 decimals, VAT once per category and rate on the sum of its lines, half away from zero), with the toolkit's invoiceTotals.ts, as the oblio server does. Before writing, it names every problem ANAF would refuse:

  • check digits: the CIF in a Romanian VAT id or CUI, a person's CNP, the IBAN;
  • the address: a Romanian one needs its county (CJ or RO-CJ), and in Bucharest the city is the sector (Sector 3 is written SECTOR3);
  • VAT: S needs a rate and the others have none; E needs a reason (AE, G and O default to their VATEX code); reverse charge needs the buyer's id; O names no VAT id and mixes with no other category;
  • money: an amount due needs a due date or payment terms, a credit transfer the IBAN, and an invoice in another currency vat_exchange_rate (RON per unit, from the bnr server), because CIUS-RO states VAT in RON too;
  • CIUS-RO's lengths and counts, and a number with at least one digit.

The tests hold every built file to ANAF's own verdict on its exact bytes, recorded by scripts/record-validation.ts --send from seven invented invoices (test/fixtures/validation).

Reading an invoice. parse_invoice spends none of ANAF's downloads, and 400.0000 stays 400.0000: a faithful view, not a verdict, which is validate_invoice's job.

Validation, PDF and the VAT registry. validate_invoice and invoice_pdf call ANAF's public host, webservicesp.anaf.ro, which takes no token (the same operations on api.anaf.ro answer 401 without one), so they work after the grant runs out. Anything over 5 MB is refused before the call. A filed invoice's PDF is made without validating it again, so today's rules cannot refuse a document filed under older ones; any other is validated first unless validate is false. lookup_company checks each CIF's control digit, then asks PlatitorTvaRest v9 one request a second, as ANAF requires; a status ANAF did not send is absent, not false.

Rotation. A refresh retires the old refresh token, so the new pair is written to tokens.json, under a lock every process on the state dir shares, before the access token is used. --refresh keeps no backup, since a copy from before a rotation would hold a dead refresh token.

ANAF's endpoints live in src/infra/anafApi.ts. npm run gen:types regenerates their types from the OpenAPI documents in ANAF's Swagger UI pages (-- --offline from the snapshots in openapi/; mfinante.gov.ro resets connections from outside Romania, so ANAF_SPEC_MIRROR=http://web.archive.org/web/2025id_/ reads an archived copy). What ANAF documents wrongly or not at all is modelled by hand in src/domain/schema.ts, and every answer is parsed at the boundary, so drift fails loudly.

Smoke test. npx tsx scripts/smoke.ts drives the built server with your configuration, read-only (--public-only for the tools that need no grant) unless given --allow-writes, which adds refresh_token without force and begin_authorization. It never files anything, and spends two of the newest message's daily downloads.

Limitations

  • build_invoice writes invoices, not credit notes (a storno is an invoice with negative quantities), with no document-level allowances or charges, no attachments, and no intra-EU supply of goods (VAT category K, which needs a delivery country).
  • e-Transport files a declaration you wrote. It does not build one from fields, nor read /info (what others declared with you as the transport organiser).
  • Reading, validating and rendering take UBL only, as ANAF's validator does; upload_invoice also files CII.
  • Seal revocation (Trans Sped's CRL and OCSP) is not checked locally.
  • The ledger lives in one state dir: deployments with separate state dirs do not see each other's production filings.
  • No SPV mailbox and no tax declarations.

Other servers for ANAF e-Factura

Searched 2026-10-15. ANAF publishes none: its one public GitHub repository is a 2019 Java sample client for SPV, and the MCP Registry lists nothing for e-Factura. Three community servers talk to ANAF directly:

  • anafpy on PyPI, the broadest: Python, a stdio server of 48 tools (its mcp extra) for e-Factura, e-Transport filing, the SPV mailbox through a qualified certificate, tax declarations and the public registries, every filing through a prepare and confirm step bound to the document's bytes.
  • @florinszilagyi/anaf-mcp on npm (stdio): lists, downloads, validates and uploads, B2C included; it takes the XML as a text argument, with no confirmation step of its own.
  • anaf-efactura-mcp on npm (stdio or HTTP): builds and uploads invoices, on the test environment by default.

Others found only upload and poll through a hosted service, reach e-Factura through another invoicing account, or validate files offline.

None of them combines a local seal check against a pinned CA, documents taken only as files or checksummed bytes, test-first filing after a line read from the XML, check digits, no second filing of the same bytes or blind resend, and no token in the client. It does not reach the SPV mailbox or file tax declarations, as anafpy does.

來源:servers/anaf-efactura/README.md,提交 cbd1121

工具

20

begin_authorization

Begin ANAF authorization

Start (re)authorizing this server with ANAF when the grant is dead or about to end. Returns authorizeUrl for the CERTIFICATE HOLDER to open in a browser with the qualified digital certificate; you cannot do that step. Then call complete_authorization with the address the browser lands on, within 60 seconds of it landing. Starting again replaces an earlier begun authorization.

輸入參數redirect_uri

build_invoice

Build a CIUS-RO invoice

Write a Romanian e-Factura invoice (UBL 2.1, CIUS-RO) from fields: seller and buyer, lines with their net price, quantity and VAT category, the currency, the payment terms. Totals are computed exactly (each line rounded to 2 decimals, VAT once per category and rate), and the draft is checked first: CIF, CNP and IBAN check digits, the county and Bucharest sector, the VAT rules per category, CIUS-RO's lengths, every problem named at once. The file goes to the outbox; the answer gives its path, sha256 and totals. Nothing is sent to ANAF: next, validate_invoice with xml: { path }, then upload_invoice with the same path to file it. An invoice in another currency needs vat_exchange_rate (RON per unit), so its VAT is stated in RON too.

輸入參數buyer必填lines必填notesnumber必填seller必填paymentcurrencydue_datesave_dirfile_nametype_codeissue_date必填另有 8 個

complete_authorization

Complete ANAF authorization

Finish what begin_authorization started: exchanges ANAF's code for tokens and stores them where this server keeps them. Pass the whole address the browser landed on as redirect_url (or code and state). Answers only the two expiry dates; no token ever appears in the result. ANAF's code dies 60 seconds after it is issued, so call this at once.

輸入參數codestateredirect_url

download_invoice

Download a signed invoice archive

Download the signed ZIP for a message id from list_invoices and save it to the downloads outbox (a name holding another file gets a number, never overwritten). The archive is checked first: it must open with every entry matching its checksum and hold the document with ANAF's seal (semnatura_*.xml), and the seal is checked against the document. Returns the path, bytes, sha256 and md5 of the archive, each entry's name, bytes and sha256, the seal's verdict, and what the invoice says.

輸入參數testsave_dirmessage_id必填

etransport_file

File an e-Transport declaration

File an e-Transport declaration XML (ANAF's schema v2) with ANAF: a new transport (notificare), its correction (notificare with corectie), a deletion (stergere), a receiver's confirmation (confirmare) or a vehicle change (modifVehicul), whichever the file holds. The XML as xml: { path } for a file, or { content_base64, sha256 } from a script. Goes to ANAF's TEST environment unless test is explicitly false. A money tool (a fiscal declaration): the client asks the user to approve each call, on a line read out of the file (operation, UIT, route, vehicle, goods value in RON, environment). The declarant's code and any UIT must pass their check digits. Returns accepted, the uploadId etransport_status takes and the UIT, or accepted=false with ANAF's reasons; the UIT counts only once etransport_status says ok. The same bytes are not filed in production twice unless refile is true. Needs the ETRANSPORT role on the grant. Moves money or makes a legal document: the client asks the user to approve each call.

輸入參數cifxml必填testrefile

etransport_list

List e-Transport messages

List e-Transport declarations from the last N days (at most 60): UIT code, declarant, trading partner, carrier, vehicle, and refused=true with ANAF's messages for a declaration it rejected. A notice field means ANAF refused or had nothing. Separate from e-Factura: it needs the ETRANSPORT role on the same grant.

輸入參數ciftestzile

etransport_status

Check an e-Transport filing

How an e-Transport declaration filed with etransport_file was processed, by its uploadId: state ok (the UIT is valid from now), processing, or failed with ANAF's reasons. Ask the environment it was filed in: test unless test is false.

輸入參數testid_incarcare必填

health

Health

Check that the integration is alive and say so in detail: the ANAF app it authenticates as, the CIF it defaults to, the roles the grant carries, and how many days are left on each token. Run this before concluding the MCP is broken.

無需輸入參數。

invoice_pdf

Render an invoice as ANAF's PDF

Have ANAF render an invoice as its official PDF and save it to the downloads outbox. Give message_id (from list_invoices) for a filed invoice, or a UBL document as xml ({ path } for a file, or { content_base64, sha256 } from a script). A filed invoice is not validated again; a document is validated first unless validate is false, and when it fails nothing is saved and findings say why. Returns saved, path, bytes and sha256 of the PDF. The PDF itself needs no grant; fetching a filed invoice by message_id does.

輸入參數xmltestsave_dirvalidatemessage_id

list_invoices

List e-Factura messages

List e-Factura messages from the last N days (ANAF allows at most 60). Each message has a kind (sent, received, error, buyerMessage), an id that download_invoice takes, a zoneless local timestamp, and details: the upload id, issuer CIF and beneficiary CIF lifted out of ANAF's prose. A notice field means ANAF refused rather than returned nothing.

輸入參數ciftestzile

list_invoices_window

List e-Factura messages over a date window

List messages over an inclusive YYYY-MM-DD window, paginated, in the same shape as list_invoices plus page counters. The window may span at most 60 days and is read as UTC. filtru narrows by type: E errors, T sent, P received, R awaiting a response.

輸入參數cifpagetestfiltruend_date必填start_date必填

lookup_company

Look up Romanian companies

Look up companies in ANAF's public VAT registry by CIF: name, trade register number, registered office, CAEN code, and the statuses an invoice depends on (vatPayer with its current period, vatOnCollection, splitVat, inactive, and eFacturaRegistry for the RO e-Factura registry). notFound lists the CIFs ANAF does not know. A status ANAF did not report is absent, not false. Needs no grant.

輸入參數cifs必填date

parse_invoice

Read an invoice as JSON

Read a UBL invoice or credit note into plain JSON: seller and buyer (names, VAT and legal ids, address, contact), every line (quantity, unit, price, net amount, VAT category and rate), the VAT breakdown, the totals, and the payment terms (due date, terms, IBAN). Every value is the document's own text, amounts included, never a number; a field the document does not fill is absent. Give xml ({ path } for a file, or { content_base64, sha256 } from a script) or archive, a .zip download_invoice saved to the outbox. Reads only: nothing goes to ANAF. To have ANAF check the document, use validate_invoice.

輸入參數xmlarchive

refresh_token

Refresh the access token

Mint a new access token. Does nothing while the current one still has its three-day cushion unless force is set, because every refresh also ROTATES the refresh token and the old one dies with it. Safe to call on a schedule; pointless to call in a loop.

輸入參數force

token_status

Token status

Report on the stored OAuth tokens without contacting ANAF and without refreshing. Watch refreshTokenRemainingDays: once it reaches zero the grant can only be restored by hand, at a browser, with the qualified certificate.

無需輸入參數。

upload_invoice

Upload an invoice XML

Submit an invoice (UBL or CII XML) to ANAF, given as xml: { path } for a file, or { content_base64, sha256 } from a script. Every IBAN in it must pass its check digits. Goes to the TEST environment unless test is explicitly false, because a production upload is a filing that cannot be recalled. A money tool: the client asks the user to approve each call, on a line read out of the XML itself (number, date, buyer, amount due, the file's sha256). Returns accepted plus the uploadId that upload_status takes, or accepted=false with ANAF's reasons; sha256 and bytes of what was filed; invoice is what the XML says, and raw is ANAF's answer verbatim. The same bytes are not filed in production twice unless refile is true. Moves money or makes a legal document: the client asks the user to approve each call.

輸入參數cifxml必填testexternrefilestandardexecutareautofactura

upload_invoice_b2c

Upload an invoice to a person (B2C)

Submit an invoice issued to a PERSON, not a company (B2C), through ANAF's /uploadb2c: the same as upload_invoice in every other way. The XML as xml: { path } (build_invoice's path works) or { content_base64, sha256 } from a script; every IBAN must pass its check digits. Goes to the TEST environment unless test is explicitly false. A money tool: the client asks the user to approve each call, on a line read out of the XML and marked B2C. Returns accepted plus the uploadId upload_status takes, or accepted=false with ANAF's reasons. The same bytes are not filed in production twice, by either upload tool, unless refile is true. Moves money or makes a legal document: the client asks the user to approve each call.

輸入參數cifxml必填testexternrefilestandardexecutareautofactura

upload_status

Check an upload

Check how an earlier upload was processed, by the uploadId that upload_invoice or upload_invoice_b2c returned. Answers a state of ok, processing or failed, with a downloadId once it is ok. Must be asked of the same environment the upload went to.

輸入參數testid_incarcare必填

validate_invoice

Validate an invoice with ANAF

Check a UBL invoice or credit note against ANAF's own schema and CIUS-RO rules without filing it. Answers valid, and when not, findings: each with the rule it broke (e.g. BR-RO-001), where in the document, and ANAF's text. invoice is what the XML says it is, and file which file was read (name, size, sha256). Needs no grant. CII is not accepted: ANAF validates UBL only. The document goes as xml: { path } for a file, or { content_base64, sha256 } from a script.

輸入參數xml必填

verify_signature

Verify ANAF's seal on an invoice

Check that an invoice is the file ANAF stored, under ANAF's seal (semnatura_*.xml). Give ONE of: message_id (downloads the archive: ANAF allows 10 downloads a day per message), archive (a .zip already in the downloads outbox, from download_invoice; costs nothing), or the two files from an archive kept elsewhere (costs nothing): xml and signature, each { path } or { content_base64, sha256 }, read byte for byte, since the seal covers the invoice's exact bytes. Checked locally first: the certificate against Trans Sped's seal CA and the Ministry of Finance, the signature, and the digest of the invoice's raw bytes. Only when that cannot decide is ANAF asked. Answers valid, checkedBy (local or anaf), a reason when not valid, and the certificate. Revocation is not checked locally.

輸入參數xmltestarchivesignaturemessage_id

版本歷史

2
  1. v0.1.1最新Oct 31, 2026
  2. v0.1.0Oct 26, 2026

評分

已滿足適用檢查項的 90%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分
  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具必需15 分
  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分

其他 Factura 整合