Iurii RoguliaIurii Rogulia
AboutServicesPricingProjectsStackReviewsPhrasesBlog
Contact
Iuriiย ships.

Iurii Rogulia, senior full-stack software engineer. Professionally building software since 2001.

Think of a number
PricingQuality checklistPrivacy PolicyCookie Policy

Business

TMI Iurii Rogulia
VAT ID: FI29845875
DUNS: 368664211
Lappeenranta, Finland ๐Ÿ‡ซ๐Ÿ‡ฎ

[email protected]
Back to projects

Iuriiย Connects: vatnode-mcp โ€” Official MCP Server for EU VAT Validation

May 20, 2026

Open-source MCP server that lets Claude Desktop, Cursor and other MCP clients validate EU VAT numbers and look up rates directly in chat.

Live Demo Source code

Stack

TypeScriptNode.js

Libraries

Zod

Services

vatnode API

Topics

MCPAI ToolingDeveloper ToolsOpen SourceTax/VAT

Key Results

  • Validate EU VAT numbers straight from Claude, Cursor and other AI assistants โ€” no coding
  • Free to try: 4 of 5 tools work with no account or API key
  • Open source (MIT) and auditable โ€” safe to install where an API key is involved
  • Every release cryptographically signed with public provenance โ€” no secrets in the pipeline
vatnode-mcp โ€” Official MCP Server for EU VAT Validation

The Business Problem

Anyone selling to businesses across the EU has to confirm their customers' VAT numbers are real โ€” it decides whether an invoice is charged VAT or zero-rated, and getting it wrong is an accounting and audit problem. The official EU checking service (VIES) is awkward to work with, and until recently the only way to reach it was to write software or wire up an API.

Meanwhile, people increasingly work inside AI assistants like Claude Desktop and Cursor. There was no way to ask an assistant "is this EU VAT number valid, and who is the company behind it?" and get an audit-grade answer. vatnode, my SaaS API for EU VAT validation, could answer that question โ€” but only through code. A new distribution channel was opening up: AI assistants that look for "tool servers" the same way developers look for packages.

The window was narrow. The catalogues where these tools get discovered reward early, polished entries, and third parties had already started using the "vatnode" name on unofficial servers. An official one had to ship before the brand fragmented.

The Solution

I built and shipped an official vatnode tool server for AI assistants โ€” end-to-end in a single day. Now a user can ask Claude, Cursor, or another compatible assistant to check an EU VAT number and get back whether it's valid, the company name and address behind it, and, when configured, an audit-grade proof-of-validation reference.

Two decisions made it trustworthy and easy to adopt. First, four of the five tools work with no account and no API key at all โ€” rate lookups and format checks run entirely offline โ€” so anyone can try it before committing. Only the live VIES validation needs a key. Second, the entire package is open source under a permissive license. That matters because an AI assistant hands the server an API key, and trust there comes from being able to read the code, not from marketing. Every release is cryptographically signed with a public, auditable record proving it was built from a specific version of the public source, and the build pipeline holds no secrets at all.

Installation is a single command with no global install, and the server is listed in the catalogues where AI assistants discover tools, so it shows up as the official option rather than the unofficial copies.

Results

MetricValue
Tools exposed5 (4 offline / 1 live)
npm bundle8.5 KB packed, 15 KB unpacked
Source251 lines TypeScript, single file
Dependencies3 runtime (SDK, Zod, eu-vat-rates-data)
Tests13 stdio JSON-RPC smoke tests on Node 24
CI secrets0 โ€” npm Trusted Publishing via OIDC
ProvenanceSigstore-signed, publicly auditable per release
LicenseMIT

Released as [email protected] on 2026-05-20. Companion to the closed-source vatnode SaaS โ€” the open-source positioning is deliberate: an AI agent receives an API key, and trust there comes from auditability, not marketing copy.

Distribution

A package on npm is not enough โ€” AI assistants discover tool servers through catalogues and through the model's own knowledge of which servers exist:

  • Official MCP Registry โ€” server.json manifest with namespace io.github.vatnode/vatnode-mcp, submitted via mcp-publisher CLI
  • Smithery, Glama, mcp.so โ€” auto-pull from public GitHub within 24-48 hours of a public repo with valid manifest
  • vatnode.dev cross-marketing โ€” feature card on the homepage, callout on pricing ("included on every plan"), full setup guide at /docs/mcp, case-study blog post at /blog/vat-validation-in-claude-desktop, mention in /guides/vies-api-alternative and /stripe-tax-alternative
  • llms.txt โ€” section for LLM agents indexing the site, pointing them at the MCP server as the canonical agent-facing entry point

Under the Hood

For the technically curious, here is how the core pieces are built.

The Model Context Protocol stabilized in late 2024, and AI agents (Claude Desktop, Cursor, Cline, Continue, plus ChatGPT Plus/Pro via Custom Connectors) now look for tool servers the same way developers look for npm packages. The server is a single-file TypeScript MCP server, bundled with tsup, published to npm with OIDC-based provenance:

  • Five tools, free/paid split โ€” list_eu_vat_rates, get_country_vat_rates, check_vat_format, list_supported_countries run fully offline from the bundled eu-vat-rates-data package; only validate_vat_number calls the vatnode API and needs a key
  • stdio transport โ€” the format every desktop MCP client supports, no SSE/HTTP server to host
  • npx -y vatnode-mcp โ€” no global install, ~50ms cold start, 15 KB unpacked
  • User-Agent attribution โ€” every outgoing request to vatnode API carries vatnode-mcp/0.2.0 (+https://vatnode.dev) so MCP traffic is measurable in the backend logs
  • MIT + public repo โ€” github.com/vatnode/vatnode-mcp, every release signed via GitHub Actions OIDC

Tool descriptions are prompts for the LLM, not docs

The description field on each MCP tool is the input prompt the model reads when deciding which tool to call. With five tools whose names overlap (check_vat_format vs validate_vat_number), documentation-style copy makes the LLM pick the wrong one โ€” users got "format looks valid" when they wanted a real VIES lookup.

// Documentation style โ€” the model has no "when to use"
description: "Validates an EU VAT number against VIES.";
 
// Decision-aiding style โ€” the model sees triggers and constraints
description: "Verifies an EU VAT number against the official VIES service and returns " +
  "validity, company name, address, registration date and other metadata. " +
  "When the requester (your own VAT) is configured on the vatnode account, " +
  "also returns a VIES consultation number โ€” audit-grade proof of validation. " +
  "Use whenever the user wants to confirm a VAT is real, look up the company " +
  "behind a VAT, or needs evidence for accounting/compliance. " +
  "Requires a vatnode API key (free tier available). Only EU-27 + XI " +
  "(Northern Ireland) are supported by VIES.";

Result: the model routes correctly between the offline check_vat_format (cheap, no key) and the live validate_vat_number (paid, audit-grade).

npm Trusted Publishing โ€” zero secrets in CI

Every release is published from GitHub Actions with no NPM_TOKEN, no long-lived credential. npm verifies the workflow identity via OIDC and writes a provenance record to a public sigstore transparency log โ€” auditable proof that a given tarball was built from a specific commit in a specific repo.

# .github/workflows/release.yml
jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write # OIDC token for npm
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-node@v5
        with:
          # Node 22 ships npm 10.x โ€” can sign provenance but cannot
          # use the same OIDC token to authenticate the registry PUT.
          # Trusted Publishing requires npm >= 11.5.1, so Node 24.
          node-version: "24"
          registry-url: "https://registry.npmjs.org"
      - run: npm install
      - run: npm test
      - run: npm publish --provenance --access public

The pitfall that cost three CI iterations: Signed provenance statement succeeds, immediately followed by 404 PUT โ€ฆ or you do not have permission. Diagnosis โ€” npm version. npm install -g npm@latest on top of Node 22 trips an incompatible promise-retry inside npm itself. Clean fix is Node 24.

Testing a stdio MCP server without mocks

The MCP test runner spawns the real bundled binary as a child process, talks JSON-RPC over its stdin/stdout, and asserts on the actual wire protocol โ€” no SDK mocks, no fake transport.

// test/smoke.mjs
const server = spawn("node", ["dist/index.js"], {
  stdio: ["pipe", "pipe", "inherit"],
});
 
async function rpc(method, params) {
  const id = ++requestId;
  server.stdin.write(JSON.stringify({ jsonrpc: "2.0", id, method, params }) + "\n");
  return waitForResponse(id);
}
 
test("validate_vat_number returns auth error without API key", async () => {
  const result = await rpc("tools/call", {
    name: "validate_vat_number",
    arguments: { vatId: "IE6388047V" },
  });
  assert.equal(result.isError, true);
  assert.match(result.content[0].text, /VATNODE_API_KEY/);
});

13 cases cover the handshake, every tool's happy path, missing-key errors, malformed input. Runs on every PR via GitHub Actions on Node 24.

Iurii RoguliaAvailable

Need something similar?

I build custom solutions โ€” from APIs to full products. Let's talk about your project.

View all projects

Related projects

n8n Verified Community Node โ€” EU VAT Validation in Workflows
n8n Verified Community Node โ€” EU VAT Validation in Workflows
August 6, 2026
n8n Verified Community Node โ€” EU VAT Validation in Workflows

Verified n8n node that puts VIES VAT validation and EU rate lookups inside a workflow, so onboarding or invoicing can decide on a real VAT number instead of a

Stack

TypeScriptNode.jsn8n

Services

npmGitHub Actionsvatnode API

Topics

Workflow AutomationNo-CodeIntegrationsDeveloper ToolsOpen SourceTax/VAT
vatnode โ€” EU VAT Validation API
vatnode โ€” EU VAT Validation API
January 19, 2026
vatnode โ€” EU VAT Validation API

Developer-first SaaS API for EU VAT validation via VIES with Redis caching, change monitoring, and webhook notifications.

Stack

Next.jsReactTypeScriptHonoNode.jsTurborepoDockerCaddy

Libraries

Drizzle ORMBullMQZodBetter AuthTanStack QueryZustand

Databases

PostgreSQLRedis

Services

StripeResendGoogle Analytics

Topics

SaaSAPIAuthFintechTax/VATMonorepoWebhooksSEOSchema.org

Related posts

linkinator Tutorial: Find Broken Links in Next.js Sites
April 29, 2026ยท 11 min
linkinator Tutorial: Find Broken Links in Next.js Sites

Use linkinator to catch broken links before production: local URL rewriting, --silent flag, GitHub Actions integration, and false positive patterns for

Stack

Node.jsTypeScript

Topics

Developer ToolsSEOCI/CDProcess
Publishing One Package to Five Registries with GitHub Actions
March 27, 2026ยท 10 min
Publishing One Package to Five Registries with GitHub Actions

How to publish one dataset to npm, PyPI, Go Module, RubyGems, and Packagist automatically with GitHub Actions โ€” architecture, versioning, and per-ecosystem

Stack

TypeScriptPythonPHPGoRuby

Services

GitHub ActionsnpmPyPIPackagistRubyGems

Topics

Open SourceTax/VATAutomation