Salary answers for AI agents via MCP
Connect an AI agent to the salary calculator over MCP so it answers "what would I take home?" questions with the official German and UK payroll algorithms and cites the rule for every deduction, instead of estimating tax from memory.
The use case
A relocation assistant, an HR chatbot or a personal-finance agent gets questions like: "I earn 70,000 EUR a year in Berlin. What would 62,000 GBP in Manchester leave me, and what UK salary would keep my current net?" Language models are unreliable at this: they mix up tax years, forget the solidarity surcharge exemption or the NI upper earnings limit, and cannot show their work. With MCP the agent calls tools that return the exact figures with the rule and source per line and a disclaimer.
The MCP server is at https://syntropicapi.com/mcp/salary-net/mcp (Streamable HTTP) and has five tools:
calculate_net_salary: gross → net with every deduction (same body asPOST /net).calculate_gross_salary: net → gross (same body asPOST /gross).compare_net_salaries: up to 8 scenarios side by side (same body asPOST /compare).get_payroll_parameters: the allowances, bands, rates and ceilings in use for a country and year.list_salary_countries: coverage, tax years and profile fields.
Listing the tools is free. Each tool call costs 1 credit.
Step 1: Get an API key
Buy credits at https://syntropicapi.com/pricing and export the key:
export SYNTROPIC_API_KEY="your-key"
Step 2: Add the server to your MCP client
Claude Code:
claude mcp add --transport http salary-net https://syntropicapi.com/mcp/salary-net/mcp --header "X-API-Key: $SYNTROPIC_API_KEY"
Other clients that support remote Streamable HTTP servers with custom headers need the same two things: the URL above and the header X-API-Key: <your key>. After that, ask the agent a salary question, and it will pick the tools itself.
Step 3: Call the tools from your own agent code
If you build your own agent, connect with an MCP client library. This Python example uses fastmcp (pip install fastmcp). It does what an agent does for the question above: it compares both salaries, then asks for the UK gross that keeps the German net. The tool arguments are the REST body fields, passed directly (not wrapped in a body object). Save it as agent_mcp.py:
import asyncio
import json
import os
from fastmcp import Client
from fastmcp.client.transports import StreamableHttpTransport
transport = StreamableHttpTransport(
"https://syntropicapi.com/mcp/salary-net/mcp",
headers={"X-API-Key": os.environ["SYNTROPIC_API_KEY"]},
)
async def main():
async with Client(transport) as client:
# What an agent sees when it connects: five tools with JSON schemas (listing is free).
for tool in await client.list_tools():
print("tool:", tool.name)
# "I earn 70,000 EUR a year in Berlin, no church, no kids. What would 62,000 GBP in Manchester leave me?"
result = await client.call_tool("compare_net_salaries", {"scenarios": [
{"country": "DE", "year": 2026, "gross": 70000, "period": "year", "de": {"state": "BE"}},
{"country": "UK", "year": 2026, "gross": 62000, "period": "year", "uk": {"region": "england"}},
]})
data = json.loads(result.content[0].text)
for row in data["rows"]:
print(f"{row['label']}: net {row['annual_net']:,.2f} {row['currency']} per year, "
f"{row['deduction_rate']} % deductions (tax {row['income_tax']:,.2f}, "
f"social {row['social_contributions']:,.2f})")
print(data["notes"][0])
# Follow-up: "Which Manchester salary would keep my German net?" The API does no currency conversion,
# so the agent converts the German net with an exchange rate it gets elsewhere (example value here).
gbp_per_eur = 0.86
target = round(data["rows"][0]["annual_net"] * gbp_per_eur, 2)
result = await client.call_tool("calculate_gross_salary", {
"country": "UK", "year": 2026, "net": target, "period": "year", "uk": {"region": "england"}})
gross = json.loads(result.content[0].text)
print(f"UK gross for a net of {target:,.2f} GBP: {gross['gross']:,.2f} GBP "
f"(employer cost {gross['employer_cost']:,.2f} GBP)")
for line in gross["lines"]:
print(f" {line['payer']:8} {line['label']}: {line['amount']:,.2f} ({line['rule']})")
print(gross["disclaimer"])
asyncio.run(main())
Run it:
python agent_mcp.py
Output (run on 29 September 2026 against the live API):
tool: calculate_net_salary
tool: calculate_gross_salary
tool: compare_net_salaries
tool: get_payroll_parameters
tool: list_salary_countries
DE 2026, tax class 1: net 42,582.87 EUR per year, 39.17 % deductions (tax 12,220.00, social 15,197.13)
UK 2026-27, 1257L: net 46,521.00 GBP per year, 24.97 % deductions (tax 12,228.40, social 3,250.60)
Amounts are in each country's currency; convert with your own FX rate before comparing absolute values. deduction_rate compares directly.
UK gross for a net of 36,621.27 GBP: 45,971.81 GBP (employer cost 52,117.58 GBP)
employee Income tax (PAYE): 6,678.40 (Tax code 1257L, rest-of-uk rates, week1/month1 basis; taxable pay to date 33,392 GBP)
employee National Insurance (Class 1 employee): 2,672.14 (Category A (Standard rate): 8 % between PT 12570 and UEL 50270 GBP per year, 2 % above)
employer National Insurance (Class 1 employer): 6,145.77 (15 % above the secondary threshold 5000 GBP per year)
Estimate for offers, budgeting and comparisons, not a payroll run and not tax advice. Computed with the official algorithms and the rates cited on each line; individual circumstances (other income, benefits in kind, pensions, fund-specific levies) can change the result.
The agent can now answer with sourced figures: in Berlin the employee keeps 42,582.87 EUR a year (39.17 % deductions); 62,000 GBP in Manchester would leave 46,521.00 GBP (24.97 %); and at the example exchange rate the same net needs about 45,972 GBP gross in England.
Step 4: Tips for agent builders
- Tell the agent in its system prompt to quote the
disclaimerand to name the tax year it used. The API's defaults (2026 tax year, tax class I, standard tax code) are echoed inprofile, and every assumption is listed innotes, so the agent can mention them. - The API does not convert currencies. Give the agent an FX source and have it say which rate it used.
- Unsupported cases come back as errors with a readable
message(e.g. German Midijob pay, private health insurance, a tax year that isn't covered). Let the agent pass the message on instead of guessing. - Ask
list_salary_countriesfirst when a user mentions a country. Austria, Switzerland, the Netherlands and the US are listed as planned but not calculable yet.
Results are estimates for offers, budgeting and comparisons, not a payroll run and not tax advice.