ANAF e-Factura について
ANAF e-Factura は、ルーマニア企業向けに電子請求書と e-Transport 申告を読み取り、検証、提出する MCP サーバーです。請求書の作成・解析、ANAF 署名の確認、VAT 登録情報の検索にも対応し、提出操作はクライアントの確認を要します。
主な機能
- 01送受信した請求書の一覧表示
- 02請求書のダウンロードと ANAF 署名の検証
- 03請求書の作成・解析・検証
- 04請求書と輸送申告の ANAF への提出
- 05企業の VAT 登録情報の検索
活用シーン
- 01最近の仕入先請求書と明細の確認
- 02提出前の CIUS-RO 請求書の検証
- 03請求書の ANAF 署名の有効性確認
- 04企業の VAT 状況と適用条件の確認
MCP 対応
MCP サーバーとして、請求書、申告、署名検証、企業検索のツールをクライアントに提供します。請求書と e-Transport の提出ツールは確認が必要な操作として扱われます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y @foreverworks/mcp-anaf-efacturaANAF_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 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
20掲載時のツール一覧 · 3 日前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| redirect_uri | string | いいえ | app.json に登録されているリダイレクト URI のいずれかです。空の場合は最初の URI が使われます。 |
詳細
ANAF e-Factura MCP サーバー
AI アシスタントから、ルーマニアの e-Factura を通じて会社が送受信した請求書を読み取り、請求書に付された ANAF の電子署名を確認し、請求書や e-Transport の申告書をANAFに提出できます。また、請求書の検証、レンダリング、作成を行い、ANAF の VAT 登録簿で会社を検索できます。3 つのmoneyツール(upload_invoice、upload_invoice_b2c、etransport_file)は、取り消せない書類を提出します。クライアントは呼び出しのたびに確認を求め、別途指定がない限り、いずれも ANAF のテスト環境に提出されます。
必要なもの: ANAF に登録した OAuth アプリケーション(クライアント ID、シークレット、コールバック URL)、会社の CIF、および会社の SPV 権限を持つ有資格デジタル証明書の所有者です。この所有者は、ブラウザーで一度サインインする必要があります。その後、サーバーが認証許可を自動更新します。また、--healthチェックでは、その所有者による再認証が必要になる 2 週間前に警告が表示されます。請求書の検証、レンダリング、作成、読み取り、電子署名の確認、会社の検索には、アカウントは必要ありません。
できること
- 「過去 2 週間に、仕入先から送られてきた請求書はどれですか?」
- 「受信した最新の請求書をダウンロードし、ANAF の電子署名を確認して、明細を一覧表示してください。」
- 「RO87654329 は VAT 納税者ですか? また、入金時に VAT を適用しますか?」
- 「Client SRL に、1 時間あたり 500 RON、VAT 21% でコンサルティング 10 時間分を請求し、ANAF で検証して、テスト環境に提出してください。」
- 「ANAF の認証の有効期限はあと何日ですか?」
インストール
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のフルパスです。複数のクライアントで 1 つの実行中のコピーを 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)は、呼び出し時に指定されなかった場合に対象となる会社です。1つの認可情報で複数の会社を対象にできるため、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 プロファイルでのアプリケーション登録と呼びます。手順を説明したマニュアル(ルーマニア語)では、各画面が示されています。
- サインインする担当者が、資格証明書と会社における次のいずれかの権限(法定代表者、指定代表者、委任を受けた担当者:reprezentant legal、reprezentant desemnat、împuternicit)を使って SPV に登録されていることを確認します。
- anaf.ro/InregOauth(Servicii Online、Înregistrare utilizatori、Dezvoltatori aplicații、「Înregistrare pentru API-uri」)で開発者アカウントを作成します。新規作成するか、お持ちのポータルアカウントを使い、ANAF から送信される「Cod de verificare」でメールアドレスを確認します。
- サインイン(「Autentificare utilizator」)し、「Editare profil Oauth」を開いてから「Gestionare aplicații」を開きます。
- アプリケーションに名前を付け、サービス(E-Factura ツールには E-Factura、e-Transport ツールには E-Transport)を選択し、管理している Callback URL(例:
https://example.com/anaf/callback)を入力します。そこに応答するものを用意する必要はありません。「Generare Client ID」を押します。 - リスト内のアプリケーションをクリックし、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 でサーバーを認可するよう依頼してください。
begin_authorizationは、アプリケーション用の ANAF サインインページ(authorizeUrl)を返します。このページは 30 分間有効です。redirect_uriでは複数あるコールバック URL のいずれかを指定します。リンクを独自に表示するクライアント(標準入出力経由の MCP URL elicitation、または Claude Code のようにプロトコル 2026-07-28 の HTTP 経由のクライアント)では、ページが表示されます。証明書をお持ちでない場合は、認可を拒否して URL を証明書の保有者に渡してください。- **証明書の保有者が、**証明書がインストールされているブラウザーでページを開き、証明書を選択してサインインします。
- **ブラウザーがコールバック URL に移動すると、**アドレスに
?code=...&state=...が表示されます。ページが読み込めない場合もありますが、重要なのはアドレスです。 - **そのアドレス全体を、すぐに
complete_authorizationのredirect_urlに渡してください。**ANAF のコードは発行から 60 秒で無効になります。サーバーはstateを検証し、コードを交換してtokens.jsonに書き込み、有効期限の日付だけを返します。トークンが会話に渡ることはありません。 - **
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 ... の形式で 1 行だけ出力し、トークンは出力しません。終了コードは、OK が 0、FAIL が 1(権限付与の無効化や設定の破損など、人による対応が必要)、WARN が 2(ANAF の不調、またはリフレッシュトークンの有効期限まで 14 日以内)です。
ツール
read は ANAF に何も変更を加えません(一部のファイルは送信ボックスに保存します)。write は保存済みの grant を変更します。money は ANAF に書類を提出し、クライアントは呼び出しごとに確認を求めます。
| ツール | アクセス | 内容 |
|---|---|---|
health | read | 保存済みトークンを使って ANAF に挨拶します。アプリケーション、デフォルトの CIF、grant のロール、各トークンの残り日数を確認します。ANAF が挨拶の最初の行にベアラートークンを含めて返すため、その行だけが返されます。 |
token_status | read | ANAF を呼び出さずに、保存済み grant の有効期限とロールを確認します。 |
refresh_token | write | 現在のアクセストークンの有効期限が切れるまで3日以内の場合、または force を指定した場合に、新しいアクセストークンを取得します。 |
begin_authorization / complete_authorization | write | 新しい grant を取得します。証明書の保有者向け ANAF ページを開き、その後、ブラウザーが移動したアドレスを渡します。 |
list_invoices | read | 過去 zile 日間の e-Factura メッセージを最大60件取得します。送信、受信、エラー、購入者メッセージが含まれ、download_invoice が使用する ID も含まれます。 |
list_invoices_window | read | 最大60日間の日付範囲から、ページごとに同じ内容を取得します。filtru(E はエラー、T は送信、P は受信、R は回答待ち)で絞り込みます。 |
download_invoice | read | ZIP を開けること、すべてのエントリがチェックサムと一致すること、ANAF のシールが有効であることを確認した後、署名済み ZIP を1つ送信ボックスに保存します。ANAF では、メッセージごとに1日10回までダウンロードできます。 |
upload_invoice | money | 請求書の XML(UBL、CII、CN、RASP)を企業に提出します。test が false でない限り、テスト環境を使用します。 |
upload_invoice_b2c | money | ANAF の /uploadb2c を通じて個人に請求書を提出します。それ以外は upload_invoice と同じです。 |
upload_status | read | アップロードの処理状況を確認します。成功(ダウンロード ID を含む)、処理中、または ANAF の理由を伴う失敗のいずれかです。 |
etransport_list | read | 過去 zile 日間の e-Transport 申告を最大60件取得します。UIT、申告者、取引先、運送業者、車両、拒否された申告に対する ANAF の理由が含まれます。 |
etransport_file | money | 申告の XML(schema v2)を提出します。新しい輸送、修正、削除、確認、または車両の変更に対応します。test が false でない限り、テスト環境を使用します。 |
etransport_status | read | 申告の処理状況を確認します。成功(UIT は現在から有効)、処理中、または失敗のいずれかです。 |
build_invoice | read | フィールドから CIUS-RO 請求書(UBL)を作成して送信ボックスに書き込み、合計額を正確に計算し、下書きを最初に検証します。提出は行いません。 |
parse_invoice | read | UBL 請求書またはクレジットノート(ファイル、または送信ボックス内のアーカイブ)を JSON として解析します。すべての値は書類の本文から取得します。何も呼び出しません。 |
validate_invoice | read | UBL 請求書またはクレジットノートを、提出せずに ANAF 独自の検証で確認します(スキーマ、EN 16931、CIUS-RO のルール)。 |
invoice_pdf | read | UBL 書類の ANAF PDF、または message_id で指定した提出済み請求書の PDF を送信ボックスに保存します。 |
verify_signature | read | 請求書が ANAF のシールのもとで ANAF に保存されたファイルかどうかを確認します。ピン留めされた CA に対してローカルで検証し、それだけでは判定できない場合に限り ANAF に問い合わせます。 |
lookup_company | read | 指定日の ANAF VAT 登録簿から最大100件の CIF を検索します。事業者情報、登録事務所、VAT 納税者かどうかとその期間、現金主義 VAT、分割 VAT、非アクティブ状態、RO e-Factura 登録簿を確認できます。 |
最後の6つは、message_id を指定した invoice_pdf と verify_signature を除き、grant は不要です。e-Transport ツールには ETRANSPORT ロールが必要です。ANAF を呼び出すツールは cif(デフォルトでは app.json の値)と test を受け取ります。リスト取得とダウンロードは test が true の場合を除き本番環境を読み取ります。一方、提出を行う3つのツールとステータスを取得する2つのツールは test が false の場合を除きテスト環境を使用するため、ステータスは提出先の環境で確認されます。
金銭
upload_invoice、upload_invoice_b2c、etransport_file は、ANAF に法的または税務上の書類を提出します。書類は取引先に届き、取り消すことはできません(請求書を取り消すにはクレジットノートが必要です)。これらは tools/list で money としてマークされ、クライアントは呼び出しごとに承認を求めます(Claude Code はすべての権限モードでそうします)。誰が確認する場合でも、次の3つのルールが適用されます。
- 特に指定がない限り、テスト環境を使います。
testが false でない限り、各書類は ANAF のテスト環境に送信され、提出しても法的効力はありません。 refileが true でない限り、本番環境では同じバイト列を二度提出しません。 本番環境への提出に使う正確なバイト列の SHA-256 は、送信前に台帳(uploads.json)に記録されます。ANAF に拒否された提出や、送信されなかった提出は対象外です。- 失われた応答は再送しません。 接続切断、5xx、または仕様に記載のない応答があった場合、提出が完了している可能性があるため、
outcome_unknownとして失敗します(トラブルシューティング)。
ファイルは確認を求める前に一度だけ読み込まれるため、確認する内容と提出される内容は同じバイト列に基づきます。MCP_CONFIRM=elicit の場合、サーバー自身が XML から読み取った内容を1行で尋ねます。行末にはファイルの 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) が追加されます。金額は書類に記載された10進数文字列です。e-Transport の金額は、商品の valoareLeiFaraTva の正確な合計です。サーバーが読み取れない書類には UNREADABLE XML と表示されます。「いいえ」と答えてください。
確認を求められる前に、支払い用として請求書に記載されているすべての IBAN(BT-84、BT-91)、販売者の CIF、e-Transport の申告者の CIF または CNP、すべての UIT のチェックデジットが有効である必要があります(ANAF のルール BR-019 による UIT のチェックデジットは、文字の誤りは検出できますが、2文字の入れ替わりは検出できません)。新しい UIT は、etransport_status が ok を返した場合にのみ有効とみなされます。
トラブルシューティング
config:「tokens at ... are missing or unparseable」。 まだ認可が保存されていないか、ファイルが破損しています。初回実行の手順で認可してください。
config が ANAF_CONFIG、app.json のフィールド、company_cif、または「... is inside app.json's directory」を示す場合。 変数またはフィールドを修正するか、cif を渡すか、ANAF_STATE_DIR/ANAF_DOWNLOADS_DIR を app.json の場所から移動してください。
auth が invalid_grant、refresh_expired、invalid_client、または unauthorized_client を返す場合。 認可が無効になっています。再度認可してください。それ以外の auth コードは、現在 ANAF 側で問題が発生していることを示します。後でもう一度お試しください。
input:「そのアドレスの state は 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 に届いている可能性があるか、これと同じバイト列がすでに送信されています。まず確認してください(upload_status に test: false を指定するか、list_invoices、etransport_status、または etransport_list を使用)。同じバイト列を意図的に再申告する場合に限り、refile: true を渡してください。
input:「請求書は送信されませんでした」、「申告は送信されませんでした」、または「請求書は作成されませんでした」。 チェックディジットまたはルールの検証に失敗しています。メッセージにそれぞれの内容が示されます。書類または build_invoice のフィールドを修正してください。
validate_invoice が ERRIdentif「nu a fost identificat cui cumparator」だけを検出する場合。 買い手は外国企業です。ANAF のバリデーターにはその旨を指定できないため、この検出結果は想定どおりです。このような買い手に対して build_invoice が設定する extern: true を指定してアップロードしてください。
checksum_mismatch。 到着したバイト列が、sha256 に記載されたファイルと一致しません。たとえば、モデルが base64 を再入力した場合に発生します。何も送信されていません。ファイルパスを指定して送信するか、スクリプトでエンコードしてください。
api のステータスが 0 の場合:ANAF に接続できなかったか、呼び出しに必要なフィールドが応答にありませんでした。後でもう一度お試しください。「... answered in a shape ANAF does not document」:ANAF の応答形式が変更され、サーバーは推測による処理を拒否しています。報告してください。
仕組み
返される内容。 ANAF のワイヤ形式はサーバー内部にとどまります。一覧表示されるメッセージには kind(sent、received、error、buyerMessage、unknown)と、ANAF の文章から抽出したアップロード ID および両方の CIF を含む details があります。createdAtLocal にタイムゾーンがないのは意図的です。ANAF はブカレスト時間でタイムスタンプを付けますが、そのことを明示しないためです。日付の範囲は UTC なので、どこでも同じように読み取れます。ANAF が HTTP 200 と eroare キーを伴って拒否した場合(「この期間にメッセージはありません」も含む)、notice が設定されます。この応答を空の一覧として扱うのは、最も重大な誤りになり得るためです。実際の応答に含まれる、証明書保有者の CNP である cui は返されません。
ANAF の封印。 download_invoice は、すべてのエントリーの CRC が一致し、ANAF の封印(semnatura_<id>.xml)が有効な場合に限り、アーカイブを保持します。この封印は、添付された XML-DSig 署名です。そのダイジェストは請求書ファイルの未加工バイト列の SHA-256 です(そのため、インデントを変更したコピーは封印されたファイルではありません)。この署名は、「Trans Sped Electronic Seal QCA G3」により Ministerul Finanțelor に発行された証明書によるものです。verify_signature はこれをローカルで検証します。証明書はピン留めされた CA(src/infra/sealTrust.ts)から発行され、請求書の日付より前に有効期限が切れていない必要があります。RSA 署名を検証した後、ダイジェストを照合します。そのため、証明書を差し替えると CA のチェックに失敗し、請求書を変更してダイジェストを書き換えると署名に失敗します。署名が検証できない場合はすべて、ANAF の公開エンドポイント /api/validate/signature に送信され、誰が応答したかは checkedBy に示されます。npx tsx scripts/check-seals.ts <folder> を実行すると、オフラインで検証できます。
請求書の作成。 build_invoice は、ツールキットの invoiceTotals.ts を使い、ANAFが確認するEN 16931のルールに従って合計します(各明細を小数点以下2桁に丸め、税率区分ごとに明細の合計額に対してVATを一度だけ計算し、ちょうど中間の値はゼロから遠い方に丸めます)。これはoblioサーバーと同じ方式です。書き込む前に、ANAFが拒否するすべての問題を列挙します。
- チェックディジット:ルーマニアのVAT IDまたはCUIのCIF、個人のCNP、IBAN。
- 住所:ルーマニアの住所には県が必要です(
CJまたはRO-CJ)。ブカレストでは市区が市名となり(Sector 3はSECTOR3と記載します)、住所に含めます。 - VAT:Sには税率が必要で、その他の区分には税率を指定できません。Eには理由が必要です(AE、G、OはVATEXコードが既定値です)。リバースチャージには買い手のIDが必要です。OにはVAT IDを指定できず、他の区分と併用できません。
- 金額:支払額がある場合は支払期日または支払条件が必要です。銀行振込にはIBANが必要です。また、別の通貨での請求書には
vat_exchange_rateが必要です(bnrサーバーから取得するRONの単位あたり為替レート)。CIUS-ROではVATもRONで記載するためです。 - CIUS-ROの文字数と件数の制限、および少なくとも1桁を含む番号。
テストでは、scripts/record-validation.ts --send を使って7つの架空の請求書(test/fixtures/validation)から記録した、各ファイルの正確なバイト列に対するANAF独自の判定を確認します。
請求書の読み取り。 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の要件どおり、1秒に1リクエストの頻度でPlatitorTvaRest v9に問い合わせます。ANAFが送信しなかったステータスは、false ではなく存在しない値として扱います。
ローテーション。 リフレッシュすると古いリフレッシュトークンは無効になるため、新しいトークンのペアはアクセストークンを使用する前に tokens.json に書き込まれます。ロックは、同じ状態ディレクトリを共有するすべてのプロセスで共通です。--refresh ではバックアップを保持しません。ローテーション前のコピーには無効になったリフレッシュトークンが含まれるためです。
ANAFのエンドポイントは src/infra/anafApi.ts にあります。npm run gen:types は、ANAFのSwagger UIページにあるOpenAPIドキュメントから型を再生成します(-- --offline を指定すると openapi/ のスナップショットから生成します。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 が追加されます。書類の提出は行わず、直近のメッセージで利用できる日次ダウンロード枠を2件消費します。
制限事項
build_invoiceが作成するのは請求書であり、クレジットノートではありません(ストルノは数量を負数にした請求書です)。書類レベルの値引きや手数料、添付ファイル、EU域内の商品供給(VAT区分K。配送先の国が必要です)には対応していません。- e-Transportは、作成済みの申告書を提出します。 項目から申告書を作成する機能も、
/info(あなたを輸送手配者として他者が申告した内容)を読み取る機能もありません。 - 読み取り、検証、PDF生成で受け付けるのはUBLのみです(ANAFのバリデーターと同じです)。
upload_invoiceはCIIも提出できます。 - 封印の失効(Trans SpedのCRLとOCSP)はローカルで確認しません。
- 台帳は1つの状態ディレクトリに保存されます。状態ディレクトリが別々のデプロイメント間では、互いの本番提出データを参照できません。
- SPVのメールボックスと税務申告には対応していません。
ANAF e-Factura 向けのその他のサーバー
2026-10-15 に検索しました。ANAF は何も公開していません。唯一の公開 GitHub リポジトリは、SPV 向けの 2019 年の Java サンプルクライアントで、MCP Registry にも e-Factura 向けのものは登録されていません。コミュニティ製のサーバーが 3 つ、ANAF に直接接続します。
anafpyは PyPI で公開されており、最も幅広い機能を備えています。Python 製の stdio サーバーで、e-Factura、e-Transport の申告、適格証明書を使った SPV メールボックスへのアクセス、税務申告、公的登録簿向けに 48 個のツール(mcpエクストラ)を提供します。すべての申告は、文書のバイト列に紐付けられた準備・確認ステップを経て行われます。@florinszilagyi/anaf-mcpは npm で公開されており(stdio)、一覧表示、ダウンロード、検証、アップロードに対応し、B2C も含みます。XML はテキスト引数として渡し、独自の確認ステップはありません。anaf-efactura-mcpは npm で公開されており(stdio または HTTP)、請求書を作成してアップロードします。デフォルトではテスト環境を使用します。
ほかに見つかったものは、ホスト型サービスを介してアップロードとポーリングのみを行うもの、別の請求アカウントを介して e-Factura に接続するもの、ファイルをオフラインで検証するものだけでした。
これらのいずれも、固定した CA に対するローカルなシール検証、ファイルまたはチェックサム付きバイト列のみでの文書受け渡し、XML から読み取った明細に基づくテスト優先の申告、チェックディジット、同じバイト列の二重申告や無条件の再送信の禁止、クライアントへのトークン非保存をすべて組み合わせてはいません。anafpy のように SPV メールボックスにアクセスしたり、税務申告を行ったりする機能もありません。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。