Skip to content

Repository files navigation

ANAF API Simulation Engine

CI License: MIT GitHub stars Badge

A NestJS-based high-fidelity simulator for building and testing integrations with Romanian ANAF APIs, including OAuth2, e-Factura, and VAT lookup workflows.

This service is designed for local development and CI environments where you want realistic API behavior without requiring a physical digital certificate, live ANAF credentials, or an actual ANAF developer account.

ANAF Mock Server Demo

Features

  • Full OAuth2 Flow: Authorization Code grant flow, Token exchange, and Refresh support.
  • e-Factura Simulation: 100% OpenAPI compliant implementations of /upload, /uploadb2c, /stareMesaj, /listaMesajeFactura, /listaMesajePaginatieFactura, and /descarcare.
  • ANAF-Specific Rate Limiting: Enforces official daily quotas (e.g., 1000 RASP/day, 100,000 paginated list queries/day) with exact ANAF error messages.
  • Strict Validation: Replicates ANAF's unique HTTP 200 XML/JSON error responses for file sizes (>10MB), invalid timestamps (60-day limits), and missing parameters.
  • Swagger API Documentation: Interactive Swagger UI at /swagger cross-referencing official ANAF URLs and fully documenting all simulation cheat headers.
  • MCP (Model Context Protocol) Server: Built-in MCP server at /mcp (Streamable HTTP transport) turning the mock into an AI-native tool. AI agents (Claude, Gemini, Cursor, Windsurf) can dynamically read ANAF schemas, understand cheat headers, and execute tools to generate valid integration code.
  • Fault Injection: Configurable latency, random 500/504 errors, and generic 429 rate-limiting modes for edge-case testing.
  • Traffic Generation: Background tasks to simulate active SPV inboxes with realistic inter-company invoice flow.
  • VAT Registry Simulation: Mock VAT lookup (v9 standard) with deterministic company data.
  • Developer Portal UI: Built-in dashboard at /console for app registration and identity management.
  • Flexible Storage: In-memory state by default, or Redis-backed for persistent simulation across restarts.

Getting Started

Local Development

  1. Install Dependencies:
    npm install
  2. Run in Watch Mode:
    npm run start:dev
    Open http://localhost:3003/console to manage the mock environment.

Docker Usage

The project is published as a multi-stage lightweight Docker image (Alpine-based) to GitHub Container Registry (GHCR).

1. Quick Start (Official Image)

Run the latest stable release directly from GHCR:

docker run -p 3003:3003 ghcr.io/aperta-sync/anaf-api-simulator:latest

2. Local Build

If you want to build the image locally from source:

docker build -t anaf-mock-server:latest .
docker run -p 3003:3003 anaf-mock-server:latest

3. Custom Simulation Settings

You can customize the simulation behavior via environment variables:

docker run -p 3003:3003 \
  -e ANAF_MOCK_LATENCY_MS=500 \
  -e ANAF_MOCK_ERROR_RATE=5 \
  -e ANAF_MOCK_STRICT_OWNERSHIP=true \
  ghcr.io/aperta-sync/anaf-api-simulator:latest

MCP Server Setup (AI Integration)

This mock server includes a built-in Model Context Protocol (MCP) server that turns the entire ANAF API simulation into a set of tools for AI agents. This allows LLMs (like Claude or Gemini) to dynamically generate, test, and debug your ANAF integration.

The server uses the Streamable HTTP transport (the current MCP standard) at a single endpoint: http://localhost:3003/mcp.

1. Claude Code

claude mcp add --transport http anaf-mock-server http://localhost:3003/mcp

To verify the server was added:

claude mcp list

To remove it:

claude mcp remove anaf-mock-server

2. Gemini CLI

Add the following to ~/.gemini/settings.json:

{
  "mcpServers": {
    "anaf-mock-server": {
      "httpUrl": "http://localhost:3003/mcp",
      "timeout": 30000
    }
  }
}

Note: The httpUrl key targets the Streamable HTTP transport. If your Gemini CLI version does not yet support httpUrl, try "url": "http://localhost:3003/mcp" instead — some tools accept both keys for the same transport.

3. Cursor / Windsurf / Other IDEs

For any IDE or tool that reads a generic MCP JSON config:

{
  "mcpServers": {
    "anaf-mock-server": {
      "url": "http://localhost:3003/mcp",
      "timeout": 30000
    }
  }
}

How it Works (AI Workflow)

Once connected, your AI agent can perform tasks like:

  1. "Check if my upload request matches the official ANAF schema." (Uses get_swagger_spec)
  2. "Generate a valid UBL XML for testing." (Uses generate_ubl_xml)
  3. "List all available simulation headers." (Uses list_cheat_headers)
  4. "Verify my rate-limit consumption for today." (Uses check_quota_usage)

This drastically reduces the time needed to build robust e-Factura integrations by letting the AI "know" the API better than a human.


Documentation

The project maintains a high-fidelity sync with official ANAF documentation.

  • Manual Guides: Human-readable summaries of API endpoints, OAuth2 registration, and the complete e-Factura integration workflow.
  • Scraped Assets:
    • Swagger JSONs: docs/anaf/scraped/technical/swagger/ contains automated OpenAPI extractions.
    • Technical Specs: docs/anaf/scraped/technical/ contains text limit files.

Automated ANAF Watchdog (Backblaze B2 & GitHub Actions)

To keep the repository lean, our scraper automatically offloads heavy ANAF assets (>200MB of PDFs and ZIPs) and its execution state directly to a Backblaze B2 bucket.

Our daily GitHub Action Check ANAF Documentation Parity (docs-sync.yml) runs the scraper. If ANAF updates their API, the action uses gh issue create to automatically open a tracked Issue alerting maintainers to update the mock code. Furthermore, any Pull Request (ci.yml) will fail if code is pushed that is out-of-sync with ANAF's documentation.

To update the scraped documentation locally, run:

node scripts/anaf-scraper.mjs

Simulating Edge Cases (Cheat Headers)

You can trigger specific ANAF error responses by sending custom HTTP headers with your requests. This is useful for testing your application's error-handling logic.

Header Value Description
X-Simulate-Upload-Error true Returns a generic upload validation error XML.
X-Simulate-Xml-Validation true Returns a SAXParseException (invalid XML) error XML.
X-Simulate-No-Spv true Returns "Nu exista niciun CIF pentru care sa aveti drept in SPV".
X-Simulate-Wrong-Certificate true Returns an ANAF_CUI_MISMATCH 403 error.
X-Simulate-Technical-Error true Returns a "Cod: SIM-001" technical error XML.

Configuration Reference

The server behavior is controlled by environment variables. These can be set in a .env file or passed directly to Docker.

Core Server Settings

Variable Default Description
ANAF_MOCK_PORT 3003 HTTP port the server listens on.
ANAF_MOCK_STORE memory State backend: memory or redis.
ANAF_MOCK_VERSION 0.1.0 Injected version string shown in the UI.

Simulation Settings

Variable Default Description
ANAF_MOCK_LATENCY_MS 200 Artificial delay (ms) for every API response.
ANAF_MOCK_ERROR_RATE 0 Probability (0-100) of random 500/504 failures.
ANAF_MOCK_RATE_LIMIT_MODE off Throttle strategy: off, deterministic, or windowed.
ANAF_MOCK_STRICT_OWNERSHIP true When enabled, OAuth tokens must "own" the target CIF to download invoices.
ANAF_MOCK_STRICT_VAT false When enabled, only explicitly seeded companies are found.
ANAF_MOCK_AUTO_TRAFFIC false Automatically generates random invoices every minute.

Redis Settings (Required if store is redis)

Variable Default Description
REDIS_URL Full connection string (e.g. redis://user:pass@host:port).
REDIS_HOST 127.0.0.1 Fallback host if REDIS_URL is missing.
REDIS_PORT 6379 Fallback port if REDIS_URL is missing.

Bootstrap & Seeding

Variable Default Description
ANAF_MOCK_BOOTSTRAP_PRESET anaf-core Startup seed dataset: anaf-core, anaf-large, or none.
ANAF_MOCK_BOOTSTRAP_CUIS Comma-separated Romanian CUIs to seed on startup.

Advanced Usage

Runtime Configuration API

You can change the simulation behavior on the fly without restarting:

curl -X PATCH http://localhost:3003/simulation/config \
  -H "Content-Type: application/json" \
  -d '{ "latencyMs": 500, "errorRate": 10 }'

Testing

  • Unit Tests: npm run test
  • E2E Tests: npm run test:e2e (Uses an in-memory server to verify full flows).

Contributing

We welcome contributions from the community to make this simulator more robust! To maintain stability, our master branch is protected. Please follow this standard workflow:

  1. Open an Issue: Before writing code, please open an issue using our Bug Report or Feature Request templates to discuss your proposed changes.
  2. Create a Branch: Check out a new feature branch from master (e.g., git checkout -b feat/new-spv-endpoint).
  3. Commit & Push: Make your changes and push them to your branch. Ensure your code passes all linting and local tests (npm run test).
  4. Open a Pull Request: Submit a PR against the master branch using the provided PR template.
  5. CI/CD Validation: Our automated CI pipeline will trigger to run tests and validate the Docker build. The CI status must be green before a maintainer can review and merge your PR.

This tool is intended for development and testing only.

About

The high-fidelity digital twin for Romanian ANAF APIs. A standalone simulator for OAuth2, e-Factura (UBL 2.1), and VAT registry workflows, featuring a built-in developer portal for local integration testing.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages