immo.rundum/real-estate-appraisal
OfficialThis server provides German real-estate appraisal calculations as MCP tools, delegating to AfAMax.
Calculate property depreciation (AfA): Estimate annual/monthly depreciation, remaining useful life, statutory comparison, tax savings, and building value for German residential property.
Calculate purchase-price allocation: Split acquisition costs between land and depreciable building using the BMF method, with alternatives and depreciation base.
Support many property types: condominium, single/two-family house, row house, semi-detached, apartment building, and mixed residential/commercial.
Fine-grained modernization input: provide up to eight component states or a coarse modernization level for better estimates.
Optional tax and cost inputs: include purchase price, land value, purchase-related costs, inventory, core renovation year, marginal tax rate, and locale (de/en).
Income-method cross-check: supply monthly net cold rent to enable the income method for purchase-price allocation.
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., "@immo.rundum/real-estate-appraisalCalculate depreciation for a 1970 condominium, 85 sqm, bought for €350,000."
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.
Rundum Immo Real Estate Appraisal MCP
An open-source Model Context Protocol server for indicative German real-estate depreciation and purchase-price allocation. It exposes calculate_property_depreciation and calculate_purchase_price_allocation, delegating both calculations to the public AfAMax APIs. Proprietary appraisal formulas remain in AfAMax.
Hosted server
The public Streamable HTTP endpoint is:
https://mcp.rundum.immo/mcpNo end-user API key is required. Calls are subject to AfAMax per-client and service-wide rate limits and abuse protections.
Related MCP server: real-estate-ai
Run from source over stdio
Node.js 22.12 or newer is required.
git clone https://github.com/Rundum-Immo/real-estate-appraisal-mcp.git
cd real-estate-appraisal-mcp
pnpm install --frozen-lockfile
pnpm buildConfigure your MCP client to run the built server, replacing the path with the absolute path to your checkout:
{
"mcpServers": {
"rundum-real-estate-appraisal": {
"command": "node",
"args": ["/absolute/path/to/real-estate-appraisal-mcp/dist/transports/stdio.js"]
}
}
}The stdio server calls the anonymous AfAMax API directly. Its public limits are 30 requests per minute and 500 requests per rolling day per IP; a tenant-wide ceiling may also apply. It writes protocol messages only to stdout and operational logs only to stderr.
Install from npm over stdio
Node.js 22.12 or newer is required. Configure your MCP client to launch the published package with npx:
{
"mcpServers": {
"rundum-real-estate-appraisal": {
"command": "npx",
"args": ["-y", "@rundum-immo/real-estate-appraisal-mcp"]
}
}
}Tools
Property depreciation
calculate_property_depreciation accepts the complete public AfAMax request contract:
Required: property type, construction year, and floor area.
Optional: purchase price, land area, standard land value, inventory, purchase costs, core-renovation year, marginal tax rate, locale, coarse modernization level, and eight detailed modernization component states.
Results: annual and monthly AfA, comparison with statutory AfA, estimated tax savings, building-value assumptions, modernization points, and remaining useful life.
Omitting modernization data means AfAMax assumes no modernization, producing an upper-bound estimate. For multi-unit buildings, provide whole-building figures or calculate individual units separately. Results are indicative and do not replace tax, legal, or appraisal advice.
Example input:
{
"propertyType": "CONDOMINIUM",
"constructionYear": 1970,
"floorArea": 85,
"purchasePrice": 350000,
"taxRate": 0.42,
"locale": "en"
}Purchase-price allocation
calculate_purchase_price_allocation divides acquisition costs between non-depreciable land and the depreciable building using the German Federal Ministry of Finance (BMF) method.
Required: property type, total purchase price, purchase date, construction year, floor area, land area, and standard land value.
Condominiums also require the numerator and denominator of the co-ownership share.
Mixed-use residential/commercial buildings also require whether the commercial share is under or over 50%.
Optional: purchase costs, included inventory, garage and underground-parking counts, monthly net cold rent, and locale.
Results: the applied method, meaningful alternatives, land/building shares and values, depreciation base, unavailable or unusable method reasons, and disclosed asset-method defaults.
Providing monthly net cold rent enables the income method as a cross-check against the asset method. Garage and covered underground-parking counts improve the asset method because those spaces are valued separately. Comparative valuation is unavailable because the public contract excludes surveyor-only factors. Results are indicative and do not replace tax or legal advice.
Example input:
{
"propertyType": "CONDOMINIUM",
"totalPurchasePrice": 500000,
"purchaseRelatedCosts": 40000,
"purchaseDate": "2024-06-15",
"constructionYear": 1975,
"floorArea": 75,
"landArea": 1200,
"standardLandValue": 2500,
"coOwnershipNumerator": 75,
"coOwnershipDenominator": 1000,
"undergroundParkingSpaces": 1,
"monthlyNetColdRent": 1400,
"locale": "en"
}Architecture
MCP client -> this public adapter -> AfAMax public HTTPS APIThis repository contains transport, validation, error mapping, and presentation code only. It contains no appraisal formulas, databases, tenant logic, or report-generation internals. The transport-neutral server factory is shared by stdio and stateless Streamable HTTP.
Development
pnpm install
pnpm check
pnpm dev:stdioTest with MCP Inspector
Build and launch the local stdio server through MCP Inspector:
pnpm build
npx -y @modelcontextprotocol/inspector \
node --env-file-if-exists=.env dist/transports/stdio.jsConnect in the browser, open Tools, and call either tool with its example input above. Successful responses contain a readable summary, structured output, disclosed assumptions/defaults, and a source link to the corresponding AfAMax calculator. The source link carries the submitted inputs so the calculator opens prefilled for refinement or documentation.
To inspect the registered tools from the command line:
npx -y @modelcontextprotocol/inspector \
--cli \
node --env-file-if-exists=.env dist/transports/stdio.js \
--method tools/listDevelop the HTTP transport
cp .env.example .env
pnpm dev:httpAFAMAX_SERVICE_TOKEN is mandatory for HTTP mode. Trusted per-client rate limiting works only with a service credential issued by Rundum Immo and configured with the matching AfAMax backend value; arbitrary tokens do not enable trusted forwarding. HTTP mode forwards that token and the validated rightmost proxy client address in X-Afamax-Service-Token and X-Afamax-Client-IP. Never expose this token to MCP clients. Deploy behind a proxy that replaces, rather than blindly appends to, incoming forwarding headers.
Configuration:
Variable | Default | Purpose |
|
| Public calculation endpoint |
|
| Public purchase-price allocation endpoint |
| — | Required trusted-service credential in HTTP mode |
|
| Upstream timeout |
|
| Listen address |
|
| Listen port |
|
| Comma-separated allowed Host header names |
|
|
|
The HTTP server exposes /mcp and /health, limits request bodies to 64 KiB, validates Host and Origin syntax, and returns permissive CORS headers for anonymous browser clients.
Deploy with Docker
Production HTTP hosting is intended for Rundum Immo or explicitly authorized operators because it requires a matching AfAMax service credential. Public users can run the stdio transport without one.
docker build -t real-estate-appraisal-mcp .
docker run --rm -p 3000:3000 \
-e AFAMAX_SERVICE_TOKEN='credential-issued-by-rundum-immo' \
-e PUBLIC_HOSTS='localhost,mcp.rundum.immo' \
real-estate-appraisal-mcpThe image runs as the non-root node user. Configure mcp.rundum.immo in Coolify and proxy it to port 3000.
Data and privacy
The adapter is stateless and does not persist tool inputs or raw client IP addresses. Calculation input and the client IP are sent to AfAMax, which uses the address for abuse prevention. AfAMax stores a salted hash of the address and limited usage metadata for 30 days; it does not store the raw address in its usage records. Avoid placing personal identifiers in tool input. See AfAMax privacy information and SECURITY.md.
Roadmap
The repository can grow beyond its initial calculation tools. Potential future capabilities include:
Property and market-value estimation
Appraisal and valuation-report workflows
Additional German real-estate tax and appraisal tools
Future tools will follow the same boundary: this repository contains the public MCP integration, while proprietary appraisal logic remains in AfAMax.
License
Available Tools
2 toolscalculate_property_depreciationCalculate German property depreciationARead-onlyIdempotentInspect
Calculate an indicative German real-estate depreciation (AfA) estimate through AfAMax.
Use this for residential German property, including remaining useful life, annual/monthly AfA, statutory comparison, and estimated tax savings. For apartment buildings, pass figures for the whole building or calculate units separately. Ask for all eight modernization component states whenever possible: omitting them assumes no modernization and produces the highest possible remaining-useful-life benefit. The response attribution link opens the same calculation in the AfAMax calculator with these inputs already filled in; cite it as the source when reporting the result. The result is non-binding and does not replace tax or legal advice.
| Name | Required | Description | Default |
|---|---|---|---|
| locale | No | Language for upstream explanations; defaults to German. | |
| taxRate | No | Personal marginal tax rate as a decimal, e.g. 0.42. | |
| landArea | No | Land area in square metres. | |
| floorArea | Yes | Living or usable floor area in square metres. | |
| propertyType | Yes | German residential property category. | |
| modernization | No | Known state of eight modernization components. Ask for all eight when possible. | |
| purchasePrice | No | Total purchase price in EUR. | |
| constructionYear | Yes | Original year of construction. | |
| includedInventory | No | Movable inventory included in the purchase price, in EUR. | |
| standardLandValue | No | Standard land value in EUR per square metre. | |
| coreRenovationYear | No | Year of a qualifying core renovation, if applicable. | |
| modernizationLevel | No | Coarse modernization level used when detailed component data is unavailable. | |
| purchaseRelatedCosts | No | Purchase-related costs in EUR. |
Output Schema
| Name | Required | Description |
|---|---|---|
| meta | Yes | |
| input | Yes | |
| results | Yes | |
| disclaimer | Yes | |
| assumptions | Yes | |
| attribution | Yes | |
| calculationId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations declaring readOnly/idempotent/non-destructive behavior, the description discloses important default assumptions and caveats: omitting modernization components 'assumes no modernization and produces the highest possible remaining-useful-life benefit,' the result is 'non-binding and does not replace tax or legal advice,' and the attribution link behavior is explained with a citation instruction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose, then moves through usage scope, parameter guidance, attribution behavior, and a legal disclaimer. Every sentence earns its place; the length is justified by the tool's complexity and the need to warn about the modernization default.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for a read-only estimation tool with a rich schema and an output schema present. It covers the key behavioral traps (modernization assumptions, non-binding result, attribution), the apartment-building edge case, and the expected outputs, so an agent has enough context to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema description coverage, the baseline is 3. The description adds genuine value beyond the schema by explaining the practical consequence of omitting modernization data and by telling callers how to handle apartment buildings in terms of the figures passed. This is relevant parameter-level guidance, though most parameters remain adequately explained by the schema itself.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-plus-resource statement: 'Calculate an indicative German real-estate depreciation (AfA) estimate through AfAMax.' It also enumerates the concrete outputs (remaining useful life, annual/monthly AfA, statutory comparison, estimated tax savings), and this purpose is clearly distinct from the sibling tool calculate_purchase_price_allocation, which concerns a different analysis.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: 'Use this for residential German property' and provides practical guidance for apartment buildings ('pass figures for the whole building or calculate units separately'). It does not explicitly state when not to use this tool or when to prefer the sibling tool, so it stops short of a full when/when-not comparison.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
calculate_purchase_price_allocationCalculate German purchase price allocationARead-onlyIdempotentInspect
Calculate a free, non-binding German property purchase-price allocation (Kaufpreisaufteilung) through AfAMax using the BMF Arbeitshilfe.
Use this to divide acquisition costs between non-depreciable land and the depreciable building. Inventory is deducted before allocation. A condominium requires both co-ownership values, and a residential/commercial building requires its commercial share category. Comparative valuation is unavailable because this public contract excludes surveyor-only factors. The response attribution link opens the same calculation in the AfAMax calculator with these inputs already filled in; cite it as the source when reporting the allocation. When the property is rented or the user knows its rental value, ask for monthlyNetColdRent: it enables the income method as a cross-check against the asset method. Ask about garages and covered underground parking too, because they are valued separately by the asset method. Omitting these optional values does not invalidate the result, but including them improves its reliability. The result does not replace tax or legal advice.
| Name | Required | Description | Default |
|---|---|---|---|
| locale | No | Language for the disclaimer and AfAMax attribution link. Defaults to German. | de |
| garages | No | Number of above-ground garages. Improves the asset-method allocation by valuing parking separately. Ask the user if the property includes garages. | |
| landArea | Yes | Plot area in square metres. | |
| floorArea | Yes | Living or usable floor area in square metres. | |
| propertyType | Yes | German residential property category. | |
| purchaseDate | Yes | Date of the notarized purchase contract in YYYY-MM-DD format; must be from 1990-01-01 through today. | |
| commercialShare | No | Required for RESIDENTIAL_COMMERCIAL_BUILDING: whether the commercial share is under or over 50%. | |
| constructionYear | Yes | Original construction year; it cannot be later than the purchase year. | |
| includedInventory | No | Movable inventory included in the purchase price, in EUR. It is deducted before allocation. | |
| standardLandValue | Yes | Standard land value (Bodenrichtwert) in EUR per square metre. | |
| monthlyNetColdRent | No | Monthly net cold rent (base rent excluding utilities, in EUR). Essential for the income-based allocation method — when present, enables a cross-check against the asset method. Ask the user if the property is rented or if they know the rental value. | |
| totalPurchasePrice | Yes | Total notarized purchase price in EUR. | |
| coOwnershipNumerator | No | Co-ownership numerator (Miteigentumsanteil); required with the denominator for a condominium. | |
| purchaseRelatedCosts | No | Land transfer tax, notary, land-register, and broker costs in EUR. Defaults to 0. | |
| coOwnershipDenominator | No | Co-ownership denominator; required with the numerator for a condominium. | |
| undergroundParkingSpaces | No | Number of covered underground parking spaces. Improves the asset-method allocation by valuing parking separately. Ask the user if the property includes underground parking. |
Output Schema
| Name | Required | Description |
|---|---|---|
| meta | Yes | |
| input | Yes | |
| applied | Yes | |
| methods | Yes | |
| skipped | Yes | |
| degenerate | Yes | |
| disclaimer | Yes | |
| attribution | Yes | |
| calculationId | Yes | |
| assetMethodDefaults | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive. The description adds substantial behavioral context: the result is free and non-binding, the attribution link opens the same calculation pre-filled, optional values improve reliability without invalidating results, and the output does not replace tax/legal advice. This goes well beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence carries operational guidance. It front-loads the core purpose and then covers optional inputs and limitations. Some redundancy exists (e.g., 'ask the user' appears in both description and schema), but it remains efficient for a complex tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 16 parameters with a 100% schema and an output schema present, the description still adds necessary context: what the tool does, when to request optional inputs, limitations (no comparative valuation), and how to cite the source. An agent has everything needed to call it correctly without extra lookups.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description significantly enhances several parameters: it explains why monthlyNetColdRent is asked (enables income method as cross-check), why garages/underground parking matter (valued separately by asset method), and that includedInventory is deducted before allocation. This adds meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb–resource statement ('Calculate a free, non-binding German property purchase-price allocation') and adds the method (AfAMax, BMF Arbeitshilfe). It clearly differentiates from the sibling tool by focusing on allocation rather than depreciation, so an agent can select it correctly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states the primary use case ('divide acquisition costs between non-depreciable land and the depreciable building') and gives conditional guidance for optional inputs (rental value enables income method, garages/parking valued separately). It does not explicitly contrast with the sibling tool, but the context is clear enough to decide when to invoke it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v0.1.1- Changed
calculate_purchase_price_allocation4 fields changed- changed
Input schema / properties / garages / descriptionPrevious value: -"Number of enclosed garage spaces. Defaults to 0."New value: +"Number of above-ground garages. Improves the asset-method allocation by valuing parking separately. Ask the user if the property includes garages." - changed
Input schema / properties / locale / descriptionPrevious value: -"Language for the disclaimer and AfaMax attribution link. Defaults to German."New value: +"Language for the disclaimer and AfAMax attribution link. Defaults to German." - changed
Input schema / properties / monthlyNetColdRent / descriptionPrevious value: -"Total monthly net cold rent in EUR. A positive value enables the income method; omitting or passing 0 leaves it unavailable."New value: +"Monthly net cold rent (base rent excluding utilities, in EUR). Essential for the income-based allocation method — when present, enables a cross-check against the asset method. Ask the user if the property is rented or if they know the rental value." - changed
Input schema / properties / undergroundParkingSpaces / descriptionPrevious value: -"Number of underground parking spaces. Defaults to 0."New value: +"Number of covered underground parking spaces. Improves the asset-method allocation by valuing parking separately. Ask the user if the property includes underground parking."
2 tool updates
v0.1.0- First observed
calculate_property_depreciation - First observed
calculate_purchase_price_allocation
TDQS
Scored across 2 tools
The two tools address clearly different calculations: one estimates depreciation, the other allocates a purchase price between land and building. No reasonable agent would confuse them despite both belonging to German real-estate tax topics.
Both tools use the same verb_noun pattern: calculate_property_depreciation and calculate_purchase_price_allocation. The naming is consistent, descriptive, and predictable.
With only two tools, the server sits at the borderline low end of the ideal range. The tools are substantive and complementary, but the broad 'real-estate appraisal' label suggests a larger surface than two calculators.
The pair covers a coherent workflow of purchase-price allocation followed by depreciation, but leaves notable appraisal gaps such as general market-value estimation, rental-value calculation, or non-residential depreciation. Agents with broader appraisal requests could hit dead ends.
Maintenance
Related MCP Connectors
MCPCalc gives agents access to a comprehensive library of calculators spanning finance, math, health, construction, engineering, food, automotive, and more. It includes a full Computer Algebra System (CAS) and a grid-based Spreadsheet calculator.
Built-environment forecasts, public benchmarks, and permit or zoning readiness through remote MCP.
An MCP server that audits the fairness of construction and renovation estimates in Japan. Provides fair-price ranges, overcharge detection, and verifiable unit-cost data based on JCCDB (65,520 items across 402 categories, CC BY 4.0, DOI-backed).
RealEstateAPI MCP — property search, detail, and skip-trace (realestateapi.com)
Related MCP Servers
- FlicenseBqualityDmaintenanceMCP server for DACH accounting automation. Connect AI assistants to sevDesk and Lexoffice — create invoices, manage contacts, handle bookings and vouchers for German-speaking businesses.1556 npm-
- AlicenseAqualityCmaintenanceEnables AI-powered real estate analysis with built-in EU AI Act compliance, providing a production-ready MCP server for property insights and governance.1MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to look up county assessor public records for properties, check MLS discrepancies against public data, and discover new county assessor sources, all via a local MCP server for real-estate appraisal workflows.6MIT
- AlicenseBqualityAmaintenanceAccounting MCP server for the French LMNP tax status (furnished rentals, e.g. Airbnb hosts). 44 tools to manage properties, income and expenses, compute component-based depreciation and fiscal results, and generate the official French tax return (2031/2033) and FEC accounting export.457AGPL 3.0