geneva-tax-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@geneva-tax-mcp Compare my 2023 and 2024 Geneva tax declarations."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Geneva Tax MCP
A strictly read-only local MCP server for Geneva (Switzerland) personal tax declarations (GeTax / Dr. Tax PDFs) and tax simulations via the official ESTV calculator.
No write, submit or send tool. Read-only by construction.
Quick examples
Show my 2024 salary and tax totals, including the source page and extraction confidence.
Compare my 2023 and 2024 declarations and show only recognized differences.
Estimate the tax for a hypothetical single household in Geneva, using only the income and deductions I provide explicitly.
Related MCP server: estv-tax
Features
MCP tool | Purpose |
| Years and documents available in the local folder |
| Normalized declaration (ICC/IFD totals, key fields, provenance, confidence) |
| Differences between two years on recognized fields |
| Tax simulation via the official ESTV calculator (Geneva included) |
| Resolve a municipality/postal code to an ESTV tax location id |
| ESTV deduction sheet for a household |
Every extracted value carries its provenance (document, original label, and page for text-layer PDFs) and a confidence level (exact / approx), and distinguishes zero / absent / unrecognized. Responses only expose paths relative to the tax folder.
Installation
Prerequisites: Python 3.11+, Tesseract (for OCR of scanned PDFs, optional).
git clone https://github.com/cyrusgch/geneva-tax-mcp.git mcp-taxes
cd mcp-taxes
py -m venv .venv # or python3 -m venv .venv
.venv/Scripts/python.exe -m pip install -e . # Windows
# .venv/bin/pip install -e . # macOS / Linux
# French language pack for OCR (optional, ~1.1 MB)
curl -L -o tessdata/fra.traineddata https://github.com/tesseract-ocr/tessdata_fast/raw/main/fra.traineddataMCP configuration
The tax folder is auto-detected (Windows: My Drive\Impots, Impots, Documents\Impots; macOS: Google Drive, Documents/Impots; Linux: ~/Impots...). Override:
export GENEVA_TAX_DATA_ROOT="/path/to/my/tax/folder" # optionalClaude Code
claude mcp add geneva-tax -s project \
-e "GENEVA_TAX_DATA_ROOT=C:\path\to\tax\folder" \
-- "/path/to/mcp-taxes/.venv/Scripts/python.exe" -m geneva_tax_mcp.serverCodex (OpenAI)
codex mcp add geneva-tax \
--env "GENEVA_TAX_DATA_ROOT=C:\path\to\tax\folder" \
-- "C:\path\to\mcp-taxes\.venv\Scripts\python.exe" -m geneva_tax_mcp.serverOr directly in ~/.codex/config.toml:
[mcp_servers.geneva-tax]
command = "C:/path/to/mcp-taxes/.venv/Scripts/python.exe"
args = ["-m", "geneva_tax_mcp.server"]
env = { GENEVA_TAX_DATA_ROOT = "C:/path/to/tax/folder" }Verify with codex mcp list.
Generic format (any stdio MCP client)
{
"mcpServers": {
"geneva-tax": {
"command": "/path/to/.venv/bin/python",
"args": ["-m", "geneva_tax_mcp.server"],
"env": { "GENEVA_TAX_DATA_ROOT": "/path/to/tax/folder" }
}
}
}Tests
.venv/Scripts/python.exe -m pip install -e ".[dev]" # installs pytest
.venv/Scripts/python.exe -m pytest tests/ -qAnonymized fixtures (Jean Dupont), no real data. Includes store, simulator (mocked HTTP), OCR, symlink and corrupted-PDF tests.
.venv/Scripts/ruff.exe check src tests scripts # lint
.venv/Scripts/ruff.exe format --check src tests scripts
.venv/Scripts/python.exe -m pytest tests/ -q --cov=geneva_tax_mcp --cov-fail-under=70A GitHub Actions workflow (.github/workflows/ci.yml) runs lint, format and the coverage-gated suite on every push and pull request (Ubuntu + Windows, Python 3.11/3.12/3.13).
Security and privacy
No writes into the data folder (PDFs opened read-only). The only writes are the technical ESTV cache, which is forced to the project
cache/folder (an externalESTV_MCP_CACHE_DIRcannot redirect it), gitignored, purged after 7 days, and contains only the explicit simulation parameters you sent and the returned estimates (no PDF content). Note: because the project lives in a cloud-synced folder (e.g. Google Drive), this cache is synchronized too — it is not encrypted.Simulations only send explicit parameters to the official ESTV calculator (
swisstaxcalculator.estv.admin.ch, whitelisted), and return the sent payload for audit.Simulation results = estimates produced by the official ESTV calculator, non-binding.
MCP responses expose paths relative to the tax folder (no username/machine layout).
Known limitations
2025 "Dr. Tax" PDF: partially badly encoded fonts (partial extraction).
Scanned forms: automatic OCR via Tesseract (
approxconfidence)..taxGeTax files: binarydvbern-taxformat, encrypted, not usable without GeTax (seescripts/spike_tax.py).Undocumented ESTV API: may change without notice; retry on rate limit.
Structure
src/geneva_tax_mcp/ MCP server, PDF parser, store, simulator, ESTV client, OCR
scripts/ tools (.tax spike)
tests/ anonymized fixtures + regression tests
ARCHITECTURE.md design decisions, trust boundaries and roadmap
AGENTS.md guide for AI agentsLicense
MIT — see LICENSE. The ESTV client (src/geneva_tax_mcp/estv_client.py) is vendored code from noaahh/estv-mcp (MIT), attribution kept.
Available Tools
6 toolscompare_tax_returnsA
Compare two declarations on the recognized fields (totals + key fields).
Returns the values for both years and the difference (year2 - year1). Only fields recognized with confidence are compared.
Inputs: year1 (required), year2 (required). Returns: object
find_locationB
Resolve a municipality name or postal code to an ESTV tax location id (for simulate).
Inputs: query (required), language, tax_year. Returns: object
get_tax_returnA
Return the normalized declaration for a year.
sections filters the detailed fields (e.g. ["salary", "movable_wealth"]).
Summary totals (ICC/IFD) are always included.
include_raw=True adds all raw PDF lines with their page number.
Inputs: year (required), sections, include_raw. Returns: object
list_deductions_estvC
List the ESTV deduction sheet for a household (ids to pass to simulate).
Inputs: income1 (required), location (required), age1, age2, +10 more. Returns: object
list_tax_returnsA
List the tax years and documents available in the local folder.
Returns, per year, the documents found (GeTax form, summary, supporting documents, scans) and whether a text-layer form is usable. Paths are relative to the tax folder.
Inputs: no named parameters. Returns: object
simulateA
Simulate the tax of a household with the official ESTV calculator.
EXPLICIT parameters (no data is injected automatically from the PDFs).
location: postal code or municipality name (e.g. '1201', 'Genève', 'Carouge').
deductions: ids from the ESTV sheet (see list_deductions_estv), e.g. {'PRAEMIEN3A': 7258}.
Returns the payload sent (audit) and a non-binding estimate.
Inputs: income1 (required), location (required), age1, age2, +12 more. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 6 tools
Each tool targets a distinct operation: listing available returns, retrieving a normalized declaration, comparing two declarations, listing deduction options, simulating tax, and resolving location IDs. Even the two list_* tools are clearly separated by their object.
Most tools follow a clear snake_case verb_noun pattern such as get_tax_return, list_tax_returns, and find_location. The single tool named simulate is the only mild deviation because it lacks an explicit object, but the pattern remains predictable overall.
Six tools is a well-scoped size for this domain. Each tool supports a distinct part of the tax workflow without redundancy or unnecessary surface area.
The toolset covers the full local workflow: discover available returns, retrieve normalized data, compare years, load deduction options, resolve locations, and run simulations. There are no apparent dead ends for an agent trying to analyze or estimate a household's Swiss tax situation.
Maintenance
Related MCP Connectors
Open, check and convert European e-invoices and bank statements. No document archive.
Convert PDF bank statements into structured transactions, accounts, and balances.
Convert PDF bank statements to checked Excel, CSV or JSON with balance validation.
PDF accessibility checks (veraPDF PDF/UA-1), auto-fix and Markdown conversion. EU-hosted.
Related MCP Servers
- AlicenseAqualityCmaintenanceMCP server for the Canton of Bern tax portal TaxMe/BE-Login that reads account statements and tax returns via Playwright browser automation.1313 npmMIT
- AlicenseAqualityCmaintenanceEnables AI assistants to calculate Swiss income, wealth, inheritance, capital payment, and corporate taxes for any municipality, compare tax burdens, and find cheapest locations without an API key.13MIT
- AlicenseAqualityCmaintenanceEnables parsing German bank statement PDFs into structured, validated transaction data, exporting all transactions as German-style CSV, and verifying statement totals via proof calculations, all locally within MCP-compatible clients.3MIT
- AlicenseNot gradedqualityBmaintenanceEnables an AI assistant to build and update an IRPF 2026 tax return entirely on your machine, reading and writing the official program's .DBK backup file, adding income and expenses, computing tax under both the simplified and complete models, explaining every calculation line by line, checking integrity and flagging pending items. Nothing is sent over the network, and the resulting file is restored and transmitted by the user in the official Receita Federal program.AGPL 3.0