macromod for any ai — and any coder

Connect it. Or code it.

Hook MacroMod up to Claude or ChatGPT and score reforms from your prompts — or skip the middleman and drive the Python API yourself. Free and open source. No account, no sign-in.

coming soon — not live yet

The MCP server isn't running yet, so these steps are a preview of the flow. Want to score a reform today? Use the Python API below.

1

Copy the MacroMod URL

Click the copy button — you'll paste it in the next step.

https://mcp.macromod.dev/mcp
2

Open Settings → Connectors

In Claude, add a custom connector, name it MacroMod, and paste the URL.

3

Connect and ask

Click Add → Connect, then ask Claude to score a 1p basic-rate rise.

using a coding agent with a terminal? the CLI or the code below is the better fit.

or — write the code yourself

The Python API, in one screen.

No connector, no CLI — just Python. Pick a model: score a reform with the OLG or OBR engine in a handful of lines, or read the economy's current shocks and forecast it with the structural VAR.

Install straight from GitHub, no clone needed (Python 3.11–3.13). The whole scoring loop is four moves:

01 · buildthe reforma PolicyEngine parameter + a new value
02 · solveboth worldsbaseline and reform steady states
03 · mapto £bnmodel units → current-price aggregates
04 · readthe impactlevel, change, and % per aggregate
install
pip install git+https://github.com/PSLmodels/OG-UK
score_reform.py
from datetime import datetime
from policyengine.core import ParameterValue, Policy
from policyengine.tax_benefit_models.uk import uk_latest
from oguk import solve_steady_state, map_to_real_world

# 01 BUILD — a reform is real statute: a PolicyEngine parameter + a new value.
#          Here: basic rate of income tax 20% → 21% from 2026.
param = uk_latest.get_parameter("gov.hmrc.income_tax.rates.uk[0].rate")
reform = Policy(name="Basic rate 21%", parameter_values=[
    ParameterValue(parameter=param, value=0.21,
                   start_date=datetime(2026, 1, 1))])

# 02 SOLVE — two general-equilibrium solves (~5-15 min each).
#          No policy argument = current law. Same call + policy = the reform.
baseline  = solve_steady_state(start_year=2026)
reform_ss = solve_steady_state(start_year=2026, policy=reform)

# 03 MAP  — model units → current-price £bn, anchored to ONS/OBR data.
impact = map_to_real_world(baseline, reform_ss)

# 04 READ — level, change, and % change for each aggregate.
print(f"GDP:     {impact.gdp_change:+.1f}bn ({impact.gdp_pct:+.3f}%)")
print(f"Revenue: {impact.tax_revenue_change:+.1f}bn")
print(f"Debt:    {impact.debt_change:+.1f}bn")
output · illustrative
GDP:     +2.9bn (+0.041%)
Revenue: +6.4bn
Debt:    −3.1bn

Under the hood: PolicyEngine runs the reform through the actual UK tax-benefit rules on representative microdata, OG-UK estimates tax functions from that, and the OLG model solves for how 80 age cohorts and firms re-optimise — giving you the new equilibrium wages, interest rate, and aggregates.

Swap solve_steady_state for run_transition_path and you get the whole profile, year by year — and every series the model tracks. Here is the same basic-rate reform, actually solved:

Reform impact over the transition path

£bn change from baseline · fiscal years 2026–2055

-8 -4 +0 +4 +8 +12 2026 2035 2045 2055
GDP Tax revenue

Sector output, long-run

% change vs baseline · 8-sector model, 2055

Energy -0.58% Manufacturing -0.67% Construction -0.68% Trade & Transport -0.67% Info & Finance -0.68% Real Estate -0.70% Business Services -0.67% Public & Other +0.12%

Higher income tax pulls labor and capital out of the market sectors; the public & other sector expands relative to them.

Real output from OG-UK's transition-path solver for a +1p basic-rate rise — the same charts the model exports to tpi_charts.html. Revenue rises then settles; GDP dips as higher labor taxes trim work and saving over the long run.

mode

solve_steady_state() for the long-run answer; run_transition_path() for the year-by-year fiscal profile (slower, runs on Dask).

age_specific

"pooled" (default, fastest) → "brackets""each" for finer age-specific tax functions.

param_overrides

Structural shocks that aren't statute: {"cit_rate": [[0.25]]} for corporation tax, {"Z": [[1.004]]} for TFP.