estv-tax
Click on "Install 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., "@estv-taxCalculate income tax for a single person earning 120k in Zurich for 2026."
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.
Swiss Tax Calculator — MCP Server & Python API
Licensed under MIT by Aiyatullah Saiyed.
A dual-purpose Swiss tax toolkit: use it as a Python API client in your applications, or run it as an MCP server for AI assistants like Claude. Wraps the official ESTV Swiss Federal Tax Calculator — no API key or authentication required.
Covers income, wealth, lump-sum capital, inheritance/gift, and corporate taxes for every Swiss municipality across tax years 2010–2026.
Features
Category | Tools |
Household tax |
|
Compare places |
|
Tax planning |
|
Other taxes |
|
Reference |
|
Related MCP server: Swiss Health MCP Server
Quick Start
Install
# Clone the repository
git clone https://github.com/aiyatullah/swiss-tax-calculator-mcp.git
cd swiss-tax-calculator-mcp
# Install dependencies
uv syncUsage as Python API
Import EstvClient directly in your Python code to query the ESTV tax calculator programmatically.
Basic Example — Find a Location
from estv_mcp import EstvClient
client = EstvClient()
# Search for a municipality by name or postal code
locations = client.search_location("Zug", tax_year=2026)
for loc in locations[:3]:
print(f"{loc['City']} ({loc['Canton']}) — ID: {loc['TaxLocationID']}")Calculate Income Tax
from estv_mcp.api import EstvClient, RELATIONSHIP, CONFESSION, INCOME_TYPE
client = EstvClient()
# Step 1: Find the tax location
locations = client.search_location("8001", tax_year=2026)
location_id = locations[0]["TaxLocationID"]
# Step 2: Get the tax budget (deduction sheet)
budget = client.tax_budget({
"SimKey": None,
"TaxYear": 2026,
"TaxLocationID": location_id,
"Relationship": RELATIONSHIP["single"],
"Confession1": CONFESSION["none"],
"Confession2": 0,
"Children": [],
"Age1": 35,
"RevenueType1": INCOME_TYPE["employed"],
"Revenue1": 120_000,
"Age2": 0,
"RevenueType2": 0,
"Revenue2": 0,
"Fortune": 50_000,
})
# Step 3: Calculate detailed taxes
result = client.detailed_taxes({
"SimKey": None,
"TaxYear": 2026,
"TaxLocationID": location_id,
"Relationship": RELATIONSHIP["single"],
"Confession1": CONFESSION["none"],
"Confession2": 0,
"Children": [],
"Age1": 35,
"RevenueType1": INCOME_TYPE["employed"],
"Revenue1": 120_000,
"Age2": 0,
"RevenueType2": 0,
"Revenue2": 0,
"Fortune": 0,
"Budget": budget,
})
print(f"Total tax: CHF {result['TotalTax']:,.0f}")
print(f"Federal: CHF {result.get('IncomeTaxFed', 0):,.0f}")
print(f"Cantonal: CHF {result.get('IncomeTaxCanton', 0):,.0f}")
print(f"Municipal: CHF {result.get('IncomeTaxCity', 0):,.0f}")Compare Municipalities
from estv_mcp.api import EstvClient, RELATIONSHIP, CONFESSION, INCOME_TYPE, GROUP_CAPITALS
client = EstvClient()
# Compare tax burden across all 26 cantonal capitals
rows = client.many_simple_taxes({
"SimKey": None,
"TaxYear": 2026,
"TaxGroupID": GROUP_CAPITALS,
"Relationship": RELATIONSHIP["single"],
"Confession1": CONFESSION["none"],
"Confession2": 0,
"Children": [],
"Age1": 35,
"RevenueType1": INCOME_TYPE["employed"],
"Revenue1": 100_000,
"Age2": 0,
"RevenueType2": 0,
"Revenue2": 0,
"Fortune": 0,
})
ranked = sorted(rows, key=lambda r: r["TotalTax"])
print("Top 5 cheapest cantonal capitals:")
for r in ranked[:5]:
loc = r["Location"]
print(f" {loc['City']} ({loc['Canton']}): CHF {r['TotalTax']:,.0f}")Inheritance Tax
from estv_mcp.api import EstvClient, BENEFICIARY, GROUP_CAPITALS
client = EstvClient()
# Inheritance tax for a sibling across cantonal capitals
rows = client.many_inheritance_taxes({
"SimKey": None,
"TaxYear": 2026,
"TaxGroupID": GROUP_CAPITALS,
"OnlyGroupID": BENEFICIARY["sibling"][0],
"OnlyPersonID": BENEFICIARY["sibling"][1],
"Donation": False,
"Amount": 500_000,
})
ranked = sorted(rows, key=lambda r: r["TaxTotal"])
print(f"Cheapest: {ranked[0]['Location']['City']} — CHF {ranked[0]['TaxTotal']:,.0f}")
print(f"Most expensive: {ranked[-1]['Location']['City']} — CHF {ranked[-1]['TaxTotal']:,.0f}")Available API Operations
Method | Description |
| Find municipalities by name or postal code |
| Find municipalities within a radius |
| Get the deduction/budget sheet for a household |
| Full tax calculation with breakdown |
| Tax from pre-computed taxable amounts |
| Compare tax across many municipalities |
| Lump-sum capital withdrawal tax across municipalities |
| Inheritance/gift tax across municipalities |
| Corporate tax across municipalities |
| Raw tax bracket tables |
| Supported year range per calculator |
| Current ESTV data version |
Enum Reference
from estv_mcp.api import (
RELATIONSHIP, # single=1, married=2, concubinage=3, registered_partnership=4
CONFESSION, # reformed=1, roman_catholic=2, christ_catholic=3, none=4, other=5
INCOME_TYPE, # employed=1, self_employed=2, pensioner=3, other=4
GENDER, # male=1, female=2
LANGUAGE, # de=1, fr=2, it=3, en=4
CANTON_GROUP, # AG=1 ... ZH=26
GROUP_CAPITALS, # 88 — all 26 cantonal capitals
GROUP_SWITZERLAND, # 99 — every municipality (~2100)
CALCULATOR, # income_wealth=1, capital_payment=2, legal_entity=3, inheritance=5
BENEFICIARY, # spouse, child, sibling, unrelated, etc. → (GroupID, PersonID)
)Caching
Responses are cached under ~/.cache/estv-mcp for one week. Control via environment variables:
Variable | Effect |
| Disable caching entirely |
| Custom cache directory |
| Cache lifetime in seconds |
Usage as MCP Server
Run this project as an MCP server to give AI assistants (Claude, etc.) access to all Swiss tax tools.
Register with Claude Code
# Project-local (this repo only)
claude mcp add estv-tax -- uv run --directory "$PWD" estv-mcp
# User-wide (available in every project)
claude mcp add -s user estv-tax -- uv run --directory "$PWD" estv-mcpMCP Client Config (JSON)
For any MCP-compatible client, add to your config:
{
"mcpServers": {
"estv-tax": {
"command": "uv",
"args": ["run", "--directory", "/path/to/swiss-tax-calculator-mcp", "estv-mcp"]
}
}
}What the AI Can Do
Once connected, the AI assistant can:
"How much tax would I pay in Zurich on CHF 150,000?" — calls
find_location+calculate_tax"Compare Zug vs Schwyz for a married couple with 2 kids" — calls
compare_locations"Where's the cheapest place within 30km of Zurich HB?" — calls
find_cheapest_nearby"Should I split my pillar 2 withdrawal over multiple years?" — calls
plan_capital_withdrawals"What's the inheritance tax for a sibling in Geneva?" — calls
calculate_inheritance_tax"How much would my company pay in Zug vs Lucerne?" — calls
calculate_company_tax
Development
uv sync # Install dependencies (including dev)
uv run pytest -q # Run tests (hits live ESTV API)
uv run python scripts/stdio_smoke.py # MCP stdio handshake test
uv run ruff check . && uv run ruff format --check . # Lint & format checkGolden Values
tests/golden.json pins known tax figures for closed tax years. The weekly CI run re-checks them against the live API to detect upstream changes.
uv run python scripts/update_golden.py # Update golden values (prints diffs)CI
Tests run on Python 3.11/3.12/3.13 on every push, plus a weekly schedule to catch ESTV data changes.
Important Notes
All amounts are CHF per year
income_type='employed'means gross salary — social contributions (AHV/IV/EO, ALV, NBU, BVG) are derived automaticallyOverride deductions via
deductions={id: value}using IDs fromlist_deductions(e.g.PRAEMIEN3Afor pillar 3a,SCHULDZINSENfor mortgage interest)compare_locations(scope='switzerland')covers ~2,100 municipalities; results are summarized to stay readableChurch tax only applies when
confessionis notnoneFigures are from the official ESTV model — not a binding tax assessment
License
MIT License — see LICENSE.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseBqualityDmaintenanceEnables AI assistants to calculate French individual income tax and retrieve current tax brackets using official government data. Supports household composition calculations and provides up-to-date tax information for French residents.1114
- AlicenseBqualityDmaintenanceProvides AI assistants access to 1.6 million Swiss health insurance premium records from 55 insurers across 11 years (2016-2026), enabling price comparisons, historical analysis, and finding the cheapest insurance options based on location, age, and coverage preferences.4561MIT
- AlicenseAqualityAmaintenanceProvides AI-native access to Swiss Federal Statistical Office datasets through 9 tools for querying education, population, and cross-cantonal comparisons without authentication.152MIT
- AlicenseBqualityCmaintenanceEnables AI assistants to answer tax compliance questions (VAT, sales tax, GST) and validate EU VAT numbers in real time via the VIES registry.212MIT
Related MCP Connectors
Current source-cited 2026 US tax constants and calculators for AI agents; every answer cites IRS.
Free public tax MCP: GST/VAT, income, company & capital-gains tax for 50+ countries, source-cited.
Validate EU, UK, AU VAT numbers for AI agents. EU ViDA e-invoicing compliance.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Aiyatullah/swiss-tax-calculator-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server