Skip to main content

anafpy — typed Python clients for Romania's ANAF tax web services

CI Coverage PyPI version Downloads Python versions Docs License

anafpy

Typed Python clients for Romania's ANAF tax-authority web services — e-Factura (electronic invoicing), e-Transport (goods transport), the SPV mailbox (certificate-authenticated, read-only), tax declarations (declarații — local authoring, validation, qualified signing, filing), and the public no-auth registries (VAT/taxpayer lookups, financial statements) — plus a local MCP server that puts all of it inside Claude.

anafpy is a thin transport client — no persistence, no accounting logic. Invoices file either as the XML your invoicing software produced (the strongly recommended path — anafpy never re-composes it) or composed from plain business fields by the built-in CIUS-RO authoring models. Either way, ANAF's SPV is not invoice storage (it purges filed messages after ~60 days) — the durable record stays on your side.

Status: beta (0.x), on PyPI as anafpy; the design rationale lives in DESIGN.md. Requires Python 3.12+; built on httpx2 and Pydantic v2.

Documentation: anafpy.readthedocs.io — the end-user setup walkthrough, the library guides, and the API reference.

Use it with Claude

With the MCP server connected, an accountant can ask Claude to:

  • Verify business partners — VAT status, e-Factura enrollment, financial statements — with no login at all.
  • Work the e-Factura inbox: list messages, save signed ZIPs and rendered PDFs to disk in batch, and file invoices — from your software's XML or composed from plain fields.
  • Declare goods transport in e-Transport and get the UIT code — from an email, a PDF invoice, a CMR — then correct, delete, confirm, or change the vehicle.
  • Read the SPV mailbox and pull official reports (fiscal vector, outstanding obligations, filing history, income certificates...).
  • Prepare, validate, sign, and file tax declarations — validated by ANAF's own DUKIntegrator, signed with your qualified certificate.

Every ANAF filing is two-step gated: Claude shows a preview and nothing is submitted until you explicitly confirm. The server runs locally on your machine; artifacts land on your own disk.

Getting started is one click: every release attaches self-contained Claude Desktop extensions — pick the one for your machine (anafpy-darwin-arm64.mcpb for Apple silicon, anafpy-darwin-x64.mcpb for Intel Macs, anafpy-win32-x64.mcpb for Windows), drag it into Claude Desktop's Settings → Extensions, and fill in three settings. The bundle carries its own Python — no terminal, nothing else to install. The setup walkthrough (also in Romanian) covers the ANAF side — registering your OAuth application, the certificate login — and the full tour of what you can do shows the rest.

Install

Using it with Claude? The Desktop extension above is the install — no Python, no pip, no venv on the machine.

As a Python library:

pip install anafpy               # or: uv add anafpy
pip install 'anafpy[mcp]'        # with the MCP server
pip install 'anafpy[declaratii]' # with declaration signing (pyHanko)

The anafpy CLI and a standalone anafpy-mcp server (for MCP clients other than the extension) install as a uv tool, outside any project environment: uv tool install "anafpy[mcp]" — the setup walkthrough's terminal route.

Use it as a Python library

ANAF uses OAuth2 gated by a qualified digital certificate; a one-time anafpy auth login opens the browser for the certificate step, then tokens refresh headlessly for ~a year from the OS credential store — the authentication guide has the details. From there the clients are async context managers:

from anafpy.auth import KeyringTokenStore, TokenProvider
from anafpy.efactura import EFacturaClient

provider = TokenProvider(
    client_id="<ID>",
    client_secret="<SECRET>",
    store=KeyringTokenStore(),  # OS credential store (the default backend)
)

async with EFacturaClient(provider) as efactura:
    result = await efactura.upload(invoice_xml, cif="RO12345678")
    status = await efactura.get_status(result.upload_id)
    # or, in one call: status = await efactura.upload_and_wait(invoice_xml, cif=...)

Discrete methods make a single call (no transport retry). HTTP/auth problems raise AnafError subclasses; business outcomes (a nok rejection, BR-RO findings) come back as typed values, not exceptions.

The clients at a glance page inventories every client; the worked examples live in the per-service guides — e-Factura, invoice authoring, e-Transport, public services, SPV, declarations, and the error model.

MCP server

The anafpy[mcp] extra ships a local stdio MCP server wrapping the clients. The surface is read-first: the public lookups and efactura_validate need no credentials at all, reads need the one-time login, and every filing goes through the two-step prepare→submit confirmation gate. The compiled ANAF reference is served as resources and the workflow playbooks as prompts. The Desktop extension is this same server, packaged; any other MCP client registers a uv tool-installed anafpy-mcp directly — e.g. with Claude Code:

claude mcp add anafpy \
  -e ANAFPY_CLIENT_ID=... -e ANAFPY_CLIENT_SECRET=... -e ANAFPY_CIF=... \
  -- anafpy-mcp

The tools overview and workflow skills document the full surface. The server is best-effort: configuring it — including registering your own OAuth application on ANAF's portal — is your responsibility, and the setup walkthrough covers every step.

Contributing

Dev setup, the four gates, live smokes, and the generated-code rules are in CONTRIBUTING.md; repository conventions live in CLAUDE.md.

Privacy Policy

anafpy runs entirely on your own computer and collects nothing — no telemetry, no analytics, no author-operated server. Your data moves only between your machine and ANAF; tokens and downloaded documents are stored locally, and your certificate's private key is never touched. When used through an AI assistant, tool results become part of that conversation under your AI provider's own policy. The full policy: anafpy.readthedocs.io/en/latest/privacy/.

License

Apache-2.0. Independent / unofficial — not affiliated with ANAF.

anafpy is free to use and provided as-is, with no warranty: it moves documents to and from ANAF, it does not give tax advice, and filing outcomes are your responsibility. The MCP server is best-effort — configuring it, provisioning your own OAuth application on ANAF's portal, and holding the qualified certificate are up to you (the setup walkthrough covers all of it).

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

anafpy-0.12.2.tar.gz (6.2 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

anafpy-0.12.2-py3-none-any.whl (965.0 kB view details)

Uploaded Python 3

File details

Details for the file anafpy-0.12.2.tar.gz.

File metadata

  • Download URL: anafpy-0.12.2.tar.gz
  • Upload date:
  • Size: 6.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for anafpy-0.12.2.tar.gz
Algorithm Hash digest
SHA256 fa5fe578b9a3550298f862d2bb8ec5d7fac09d46e8d68a30f49167dd265d9ec4
MD5 ab22adf7809d1fc9e045298f8372782b
BLAKE2b-256 9989b157a4fbed2413d7bf662c0c7e8704ecc8bf3e5b6eb6dba6f0a4f4b2f493

See more details on using hashes here.

Provenance

The following attestation bundles were made for anafpy-0.12.2.tar.gz:

Publisher: release.yml on robert-malai/anafpy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file anafpy-0.12.2-py3-none-any.whl.

File metadata

  • Download URL: anafpy-0.12.2-py3-none-any.whl
  • Upload date:
  • Size: 965.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for anafpy-0.12.2-py3-none-any.whl
Algorithm Hash digest
SHA256 5267391485313a228a358c057c6157b02c32bd02021a36613cd4a712638c48d9
MD5 55d05827d9a5e59ad2f148d48d1c63af
BLAKE2b-256 279d93e45e642b70ab55a2dd888a89a10dab5370ce6bb75d4ffcc260d458b9d7

See more details on using hashes here.

Provenance

The following attestation bundles were made for anafpy-0.12.2-py3-none-any.whl:

Publisher: release.yml on robert-malai/anafpy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.13.2

2 files

0.13.1

2 files

0.13.0

2 files

This release

0.12.2 This release

2 files

0.12.1

2 files

0.12.0

2 files

0.11.0

2 files

0.10.0

2 files

0.9.0

2 files

0.8.1

2 files

0.8.0

2 files

0.7.2

2 files

0.7.1

2 files

0.7.0

2 files

0.6.2

2 files

0.6.1

2 files

0.6.0

2 files

0.5.3

2 files

0.5.2

2 files

0.5.1

2 files

0.5.0

2 files

0.4.3

2 files

0.4.2

2 files

0.4.1

2 files

0.4.0

2 files

0.3.1

2 files

0.3.0

2 files

0.2.1

2 files

0.2.0

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page