pricewise-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., "@pricewise-mcp calculate ISV for a 2019 petrol car, 1199cc, 125 g/km CO2"
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.
pricewise-mcp
An MCP server that lets Claude Desktop, Claude Code or any MCP client compute Portuguese vehicle taxes (ISV and IUC) and price ranges, using the tested code in pricewise-pt.
In 30 seconds
Three tools:
calculate_isv,calculate_iuc,estimate_price_range.Deterministic: same input, same output. No network calls and no file writes; the tests block all non-loopback network access and fail if a tool path opens a file for writing. The tax arithmetic lives in pricewise-pt, written from the legal articles and checked against hand-worked examples; this server adds typed inputs, validation, sources and error messages a language model can act on.
Every tax answer lists its assumptions (
flags), its legal sources and a not-tax-advice disclaimer.The price tool is a demo on synthetic data, labelled as such in every answer.
Resources for the versioned tax tables and a limitations document, plus one prompt.
stdio for local clients, Streamable HTTP for remote use.
Real transcript of every tool: docs/demo-transcript.md.
Related MCP server: Clara Carros MCP server
Install and connect
Needs uv. Nothing is published to PyPI; the commands install straight from GitHub.
1. Install once
uv tool install git+https://github.com/cardohso/pricewise-mcp
pricewise-mcp --version # run it once now: the first launch is slow, later ones take secondsInstall once instead of launching with uvx --from git+...: uvx contacts GitHub on
start and rebuilds the package after the repo changes, and a cold start can exceed the 30-second connect timeout
Claude Code applies (this happened while testing). The installed command starts offline. To
update later: uv tool upgrade pricewise-mcp.
2. Connect a client
Claude Code
claude mcp add pricewise -- pricewise-mcpClaude Desktop: add to claude_desktop_config.json (Settings, Developer, Edit Config):
{
"mcpServers": {
"pricewise": {
"command": "pricewise-mcp"
}
}
}Claude Desktop may not find the command on its PATH. If the server does not start, put the
full path from which pricewise-mcp in "command".
Streamable HTTP (remote or shared use):
pricewise-mcp --transport http --port 8000
claude mcp add --transport http pricewise http://127.0.0.1:8000/mcpHTTP is stateless, answers in JSON and binds to 127.0.0.1 by default. The server has no
authentication; if you bind another address it warns on stderr. Put it behind a reverse proxy
that authenticates callers before exposing it.
No install (slower and more fragile): replace pricewise-mcp in the commands above with
uvx --from git+https://github.com/cardohso/pricewise-mcp pricewise-mcp.
From a clone
git clone https://github.com/cardohso/pricewise-mcp && cd pricewise-mcp
python -m venv .venv && .venv/bin/pip install -e ".[dev]"
.venv/bin/pricewise-mcp --versionThe first valuation call after the server starts can take up to about 20 seconds: the model is fitted in a background thread at launch.
Tools
All three are read-only, idempotent and closed-world (tool annotations). Responses are
structured JSON matching the tool's output schema. Examples below are real server output;
sources and disclaimer are shortened here and complete in the
transcript.
calculate_isv
The one-off registration tax for a used passenger car brought in from another EU/EEA state.
Input: a vehicle (first registration date, fuel, engine cc, CO2 g/km, CO2 test standard, and
optional Euro class, diesel particles, electric range, hybrid base fuel), a required
declaration_date, and an optional tax_year.
{"vehicle": {"first_registration": "2019-06-15", "fuel": "petrol", "engine_cc": 1199,
"co2_g_km": 125, "co2_standard": "wltp"},
"declaration_date": "2026-10-01"}{
"total_eur": 211.3,
"engine_component_eur": 197.45,
"co2_component_eur": 13.85,
"age_reduction": 0.65,
"regime": "normal",
"minimum_applied": false,
"co2_standard_used": "wltp",
"co2_standard_assumed": false,
"flags": [],
"tax_year": 2026,
"sources": ["Código do Imposto sobre Veículos (Lei 22-A/2007), art. 7, tabela A ...", "..."],
"disclaimer": "Illustration only, not tax advice. ..."
}With the CO2 standard and a diesel's particle value left out, the same call still answers, with the costlier assumption made explicit:
{
"total_eur": 1717.64,
"particle_surcharge_eur": 500.0,
"co2_standard_assumed": true,
"flags": [
"CO2 standard (NEDC/WLTP) assumed from the registration date: confirm it on the certificate of conformity",
"diesel particle value unknown: check field V.5 of the registration document"
]
}(Other fields omitted. Input: a 2020-03-01 diesel, 1598 cc, 115 g/km.)
calculate_iuc
One year of the yearly circulation tax for a category B car (first registered on or after
1 July 2007). Same vehicle object; optional tax_year.
{"vehicle": {"first_registration": "2019-06-15", "fuel": "petrol", "engine_cc": 1199,
"co2_g_km": 125, "co2_standard": "wltp"}}{"total_eur": 111.46, "engine_component_eur": 31.77, "co2_component_eur": 65.15,
"co2_extra_eur": 0.0, "year_coefficient": 1.15, "diesel_extra_eur": 0.0,
"co2_standard_assumed": false, "flags": [], "tax_year": 2026}(sources and disclaimer omitted.) Cars registered before July 2007 get an error.
estimate_price_range
A used-car asking price with a 50% and an 80% range. Trained on synthetic, made-up listings:
it demonstrates calibrated uncertainty and says nothing about a real car or market. Input:
category (compact, hatchback, crossover, estate, electric), age_years, usage
(km), optional condition.
{"category": "compact", "age_years": 6, "usage": 90000, "condition": "good"}{
"point_eur": 10504.17,
"range_50": {"low_eur": 9362.4, "high_eur": 11535.41},
"range_80": {"low_eur": 8548.65, "high_eur": 12704.31},
"comparables_median_eur": 10190.0,
"data_source": "synthetic",
"flags": [],
"notice": "Trained on synthetic, made-up listings. ..."
}Inputs outside the synthetic training range add an extrapolation flag.
What a wrong call looks like
Invalid arguments for calculate_isv. Fix these and call again:
- vehicle.first_registration: input should be a valid date or datetime, invalid character in year (got '15/06/2019'). Hint: dates are YYYY-MM-DD; if '15/06/2019' is day/month/year, send '2019-06-15'
- vehicle.fuel: input should be 'petrol', 'diesel', 'hybrid', 'plugin_hybrid' or 'electric' (got 'gasoline'). Hint: use 'petrol' for 'gasoline'Resources and prompt
URI | What |
| Index of the available table years, with legal sources |
| The ISV rate tables exactly as the calculator uses them |
| The IUC rate tables |
| What the server does not do |
Prompt explain_tax_breakdown(vehicle_description, declaration_date): tells the model to call
both tax tools, ask for missing fields instead of guessing, explain each component, list the
flags and finish with the disclaimer.
Design decisions
Deterministic tools only. A model is good at conversation and bad at arithmetic on legal tables. These tools do the arithmetic; the model only gathers inputs and explains outputs. All tax logic stays in pricewise-pt, the server is a thin typed layer.
declaration_dateis required. ISV depends on the car's age on that date. A hidden default of "today" would make results change silently, so the model must pass it.Assumptions are data. Instead of refusing when the CO2 standard or a diesel's particle value is unknown, ISV computes the costlier case and returns the assumption in
flags, with the other standard's total inalternative_total_eurwhere both apply. IUC assumes the standard from the registration year and flags it. Tool descriptions tell the model to relay flags; engine size and CO2 are never guessed (the model is told to ask).Structured output plus provenance. Every tax result carries
sources(the articles the tables come from) and the disclaimer, so they survive however the model paraphrases.Errors written for a model, not a developer. pydantic's raw text (internal names, the echoed input, a docs URL) is replaced by one line per problem with the field, the value sent and a hint for common mistakes (
gasoline, day/month/year dates, litres for cm3). Domain errors say whether retrying makes sense. Unknown top-level arguments are rejected: the SDK would otherwise drop a misspelt optional argument silently.One nested
vehicleobject shared by the tax tools, so the model fills the same shape every time and a future multi-vehicle tool can reuse it.No
compare_coststool. A model can call the two tools and add the results. A multi-year total would assume today's IUC rates and coefficients hold for N years, which is false, and would look more precise than it is.Synthetic valuation, labelled everywhere. The model is fitted at startup from pricewise-pt's generator (about 15 s), so no data file ships and the output is reproducible.
Stateless HTTP. No sessions to store; any instance can answer any request.
Pinned library. pricewise-pt is not on PyPI, so it is pinned to a commit in
pyproject.tomland its tax tests remain the source of truth.
Limitations
Short version; the full text is the pricewise://limitations resource.
Not tax advice. 2026 tables only; confirm with the Autoridade Tributária e Aduaneira.
Used passenger cars from another EU/EEA state. Not covered: imports from outside the EU/EEA, commercial vehicles, motorcycles, exemptions beyond the hybrid regimes in the tables.
IUC is one year at the table year's rates; category A (before July 2007) is rejected.
The price model is trained on synthetic data and its ranges are calibrated only on that data.
HTTP has no authentication.
Tested with the MCP Python SDK's client over stdio and HTTP (in CI), and by hand on 2 November 2026 in two clients, asking for the ISV and IUC of the 2019 petrol car above and for a compact's price range:
Claude Code (terminal): called the three tools and reported €211.30, €111.46 and the synthetic range, with the disclaimer and the synthetic-data warning. That session also hit the cold-start timeout described under Install.
Claude Desktop chat: called the three tools and reported the same figures and the synthetic-data warning, but did not repeat the "not tax advice" disclaimer even though every tax result carries it and the tool descriptions ask the model to relay it. The server returns the disclaimer; whether a client shows it is up to the model.
Development
pip install -e ".[dev]"
ruff check . && ruff format --check .
pytest -q # about 30 s: the valuation model is fitted a few times
python examples/demo_client.py > docs/demo-transcript.md # regenerate the transcriptThe tests run offline (only loopback is reachable), assert no file is opened for writing in the ISV, IUC and valuation paths, list the tools through an in-process client, start the server as a real subprocess over stdio and HTTP, and reuse the hand-worked ISV and IUC cases from pricewise-pt as golden values.
Licence
MIT, see LICENSE.
Available Tools
3 toolscalculate_isvCalculate ISV (registration tax)ARead-onlyIdempotent
Compute ISV (Imposto sobre Veículos), Portugal's one-off registration tax, due when a used passenger car from another EU/EEA state is registered in Portugal ("legalizar um carro importado").
Inputs come from the car's documents: first-registration date (field B), fuel, engine cc (P.1) and CO2 g/km (V.7), plus the declaration date. If the user does not know engine_cc or co2_g_km, ask them; do not estimate. If the CO2 test standard (NEDC/WLTP) or a diesel's particle value is unknown, call anyway: the result assumes the costlier case and says so in flags.
Returns total_eur, its components and the legal sources. Always relay flags and disclaimer to the user: this is an illustration, not tax advice.
Inputs: vehicle (required), declaration_date (required), tax_year. Returns: flags, regime, sources, tax_year, +12 more
calculate_iucCalculate IUC (yearly circulation tax)ARead-onlyIdempotent
Compute one year of IUC (Imposto Único de Circulação, the "selo do carro"), Portugal's yearly circulation tax, for a passenger car first registered in the EU/EEA on or after 1 July 2007 (category B).
Same vehicle object as calculate_isv. If the user does not know engine_cc or co2_g_km, ask them; do not estimate. An unknown CO2 standard is assumed from the registration year and flagged. Cars first registered before 1 July 2007 return an error: tell the user this server cannot compute them, and do not retry with a different date.
Returns total_eur for one year at the tax_year rates. Always relay flags and disclaimer to the user: this is an illustration, not tax advice.
Inputs: vehicle (required), tax_year. Returns: flags, sources, tax_year, total_eur, +8 more
estimate_price_rangeEstimate price range (synthetic demo)ARead-onlyIdempotent
Demo of calibrated price ranges: estimate a used car's asking price from its body category, age and kilometres, with a range half of similar cars fall in (range_50) and one eight in ten fall in (range_80).
The model is trained on SYNTHETIC, made-up listings. Never present the result as the value of a real car or use it for a purchase or sale decision: say it comes from a synthetic demo market, and relay flags.
The first call after the server starts can take up to about 20 seconds while the model is fitted.
Inputs: usage (required), category (required), age_years (required), condition. Returns: flags, notice, range_50, range_80, +3 more
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 3 tools
The three tools serve clearly different purposes: one-off ISV registration tax, yearly IUC circulation tax, and synthetic price estimation. The two tax calculators share the same vehicle object and similar naming style, which could cause momentary confusion for an agent without Portuguese tax knowledge, but the descriptions explicitly distinguish them.
All names use snake_case and follow a verb_ noun-like pattern (calculate_isv, calculate_iuc, estimate_price_range). The mix of 'calculate' versus 'estimate' and acronym-based nouns versus a descriptive phrase is a minor deviation but remains readable and predictable.
Three tools is well-scoped for a narrow Portuguese car-tax and price-estimation server. Each tool maps to a distinct computational service and none feels redundant or extraneous.
The surface covers the core stated workflows: ISV, IUC, and a demo price range. Minor gaps exist around other vehicle categories and standalone rate/legal-source lookups, but the server is explicitly scoped to passenger cars and agents can work around those limits.
Maintenance
Related MCP Connectors
Free public tax MCP: GST/VAT, income, company & capital-gains tax for 50+ countries, source-cited.
Deterministic MLP tax engine with IRS citations. 6 tools: basis, §751, estate, projections.
SmartMoney77 MCP v0.6.0 — 14 public tools that turn financial questions into exact numbers and citable links. New: historical_investment_return and compare_investments, which compute "what if I had invested" results from real yearly price data. Also compound interest, FIRE number, credit-card payoff, emergency fund, inflation, latte factor, investment fees, cost of waiting, plus discovery/deep-link/share-pack tools for a catalog of calculators in 6 languages (he/en/ar/es/pt/in). Public, no login. Endpoint: https://smartmoney77.com/mcp
Sourced answers on FR/EU rules + French company search (SIREN, NAF) for agents, quoted and budgeted
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to provide Portuguese legal advice by exposing legal calculators, templates, and reference documents through the MCP protocol.MIT
- AlicenseAqualityCmaintenanceEnables AI assistants to search car inventory, estimate import taxes (ISV) and resale values, and request quotes from Clara Carros, a Portuguese used and imported cars marketplace.954 npm1MIT
- AlicenseAqualityCmaintenanceEnables AI assistants to search live used-car inventory, verify whether asking prices are fair market value, estimate annual road tax and running costs, and initiate contact with sellers for the Portuguese market.6246 npmMIT
- FlicenseCqualityCmaintenanceIt enables documented checks on Milan's Area B and Area C vehicle access, MoVe-In budget calculations, and anti-smog restriction status, returning structured MCP responses with references and clear limitations.41-