All notable changes to modelchoice-mcp. Versions are tag-driven; pushing a
vX.Y.Z tag publishes to PyPI via the release workflow.
- The wheel is now installed and booted before it is published (AB#3143). The wheel is
what PyPI serves and what
pip installgives you, but nothing ever installed it — the exe check gates the PyInstaller binary built from source, a different artifact with different dependency resolution, so a wheel-only fault (a missingpackagesentry, a bad hatch build glob, an undeclared dependency) would have shipped. Thebuildjob now installs the freshly-built wheel into a clean virtualenv, makes it answer a real MCPinitializehandshake, and asserts the version it reports matches the tag being released — so a forgotten version bump can no longer burn a PyPI version number. - The PyPI publish now waits for the Windows exe verification (AB#3142).
publish-pypidepended onbuildalone, sobuild-windows-exe— which packs the single-file exe and asserts it answers an MCPinitializehandshake — raced the publish instead of gating it, and a packaging break would still have reached PyPI. Publishing is the one irreversible step in the workflow (a version number can never be reused), so it now runs after every verification. Costs a few minutes per release; buys the ability to fix a bad build by deleting a tag rather than burning a version. Release-workflow only — no change to the package.
- Migrated to the mcp 2.0 SDK (AB#3134). mcp 2.0 removed
mcp.server.fastmcpand renamed the high-level server classFastMCP→MCPServer(from mcp.server import MCPServer). The@mcp.tool/@mcp.resource/@mcp.promptdecorators are unchanged and still return the plain function, so all 25 tools, 4 resources and 2 prompts register exactly as before — verified name-for-name against the 1.x baseline. The dependency is nowmcp>=2,<3; the major-version cap stays, deliberately.- HTTP transports: host and port are now
run()keyword arguments (mcp.run(transport=..., host=..., port=...)) instead of mutatingmcp.settingsbeforehand.--transport,--hostand--portbehave as before. - The server now reports its own version in
serverInfo—MCPServertakes aversionargument, whichFastMCPhad no equivalent for.
- HTTP transports: host and port are now
- CI stops drifting with upstream releases.
uv.lockis now committed (it was in.gitignore), and CI syncs with--locked. Previously CI had no pins at all: it re-resolved the open floors inpyproject.tomlon every run, so a new upstream major landed the day it shipped —mcp 2.0.0movedmcp.server.fastmcpand brokemypyacross every@mcp.toolon an unchangedmain.mcpis also capped to<2for people installing from PyPI, who resolve against the constraints rather than the lock. Editingpyproject.tomlnow requires re-runninguv lockand committing the result; CI fails with a clear message if you forget, instead of silently upgrading you. export_tree_jsonnow carries ageneratorfield (AB#3123) — product (ModelChoice by Vose Software), server version, UTC export timestamp and the product URL, so an exported tree stays attributable once it lands in version control, a ticket, or someone else's repository. It sits alongsidemodel_json, never inside it:model_jsonstill round-trips byte-identically throughimport_tree_json. Part of the ModelChoice output-branding work (Feature AB#3118).
- Licence gate (AB#2659) — building and analysis ACTIONS now require a fully
licensed ModelChoice. The bridge reads the add-in's licence state via the new
headless
MC_LicenseStatus_Autoand refuses actions (build/edit commit, build_mcda, control panel, set_input_distribution, run_utility / evii / evpi / risk_profile / decision_report / robustness / sensitivity / analysis, import) unlessisComplete(full licence). Reading is unaffected — list/get/roll_up/ verify/scenarios/export and open/close workbook work regardless. New read-onlylicense_statustool reports the state. Fail-closed: if the status can't be read (add-in missing/old), actions are blocked with an actionable message. (Trial/expired users can read but not drive actions.) Needs the add-in build withMC_LicenseStatus_Auto. .mcpbnow built with the officialmcpbCLI (@anthropic-ai/mcpb, validates during pack) instead of a hand-rolled zip; plain-zip fallback when node isn't present. README install section reworked: PyPI + config is the recommended path; the.mcpbone-click carries a note that the Claude Desktop Extensions installer silently no-ops on the latest Windows MSIX builds (a client bug, not the bundle) — usepip installuntil Anthropic patches it.
- One-click install: Claude Desktop Extension (
.mcpb) — the release now also builds a standalone Windows.exe(new PyInstaller spec) and wraps it in a.mcpbDesktop Extension attached to the GitHub release. Installing into Claude Desktop becomes 1. openmodelchoice-mcp.mcpb2. restart Claude — no Python, noclaude_desktop_config.jsonediting. Built CLI-free in CI (scripts/build_mcpb.py); the bundle version is injected from the release tag. Excel + the ModelChoice add-in are still required for rendering.
close_workbook— close an open workbook by file name (counterpart toopen_workbook). By default unsaved changes are discarded (save=False); passsave=Trueto write them first. (Mirrorsclose_workbookin modelrisk-mcp.)open_workbooksuppresses Excel's open prompts —Workbooks.Openis now called withupdate_links=False,ignore_read_only_recommended=True,notify=False,add_to_mru=Falseand withDisplayAlerts/AskToUpdateLinksoff, so a headless open can't hang on an Update-Links / read-only dialog. (External links aren't refreshed on open; values stay as last saved.)
open_workbook— open a decision-tree workbook (.xlsx) from disk in the running Excel so the other tools can act on it. Reports the workbook's sheets and any ModelChoice tree sheets it contains; reuses an already-open workbook of the same name. (Mirrors the newopen_workbookin modelrisk-mcp.)
build_mcdagains AHP weight elicitation (AB#2646) — setweight_source="ahp"and pass anahp_matrix(Saaty 1-9 pairwise comparisons,(1 + criteria)square, ordered[financial, …criteria]) instead of direct weights. The tool computes the eigenvector weights + consistency ratio for the preview and forwardsweightSource/ahpMatrixtoMC_ApplyMcda_Auto, which recomputes them authoritatively (CR surfaced; CR > 0.10 flagged inconsistent).McdaBuildResultnow reportsweight_source,weights,consistency_ratio.
/decision-tree-monte-carloprompt — guides the cross-server Monte Carlo hand-off: assignVose*distributions to a tree's uncertain inputs (set_input_distribution), wrap the root EV (MC_V_<rootId>) as a ModelRisk output, run the simulation in modelrisk-mcp, and read the EV's output distribution back. The/design-decision-treeprompt's step 5 now points to it.- README roadmap refreshed — Phases 0–3 marked delivered (22 tools, 2 prompts), with simulation-orchestration and AHP-for-MCDA as candidate next steps.
set_input_distribution— assign an uncertainty (a ModelRiskVose*distribution) to a tree input (branch cash flow or probability), the way the UI lets you type a distribution into a cell. Stored as the input's user-formula and re-rendered, so it persists. This is the decision-tree half of a Monte Carlo: once inputs are distributions, run the simulation with modelrisk-mcp (it samples these cells and collects the tree's output distribution). Pure_MC_Storeedit + re-render — no new add-in command.
build_mcda— build a multi-criteria (MCDA) model: tree + criteria (ordinal options, weights, direction) + aggregation + per-terminal scores. Validates structure/weights/scores in Python; drives the newMC_ApplyMcda_Auto(AB#2637) to set MCDA mode + render. v1 = direct weights (AHP follow-up). No-op until that add-in build ships.
run_utility— risk-attitude (utility) rollback: certainty equivalent, risk premium, and the optimal decision under risk aversion vs EV. Drives the newMC_Utility_Auto(AB#2635); no-op until that add-in build ships.
- Drivers for the C# add-in batch —
import_precisiontree(drivesMC_ImportPrecisionTree_Auto) andtwo_way_sensitivityviarun_decision_report(drivesMC_TwoWaySensitivity_Auto). Both no-op until the matching add-in build (PR !2032) is installed. (Terminal-payoff linking in the control panel is add-in-side; no new MCP tool needed.)
- Housekeeping — CHANGELOG; gated live integration tests
(
MODELCHOICE_LIVE=1) exercising the real COM attach/read/rollback path.
- Knowledge resources —
modelchoice://guide/*curated decision-analysis guidance (building trees, EVPI vs EVII, which analysis to use, pitfalls).
- Import / export —
export_tree_json(a tree's raw ModelChoice JSON, to save/share/version) andimport_tree_json(validate raw JSON → write/render).
run_decision_reportgainsforce_to_outcome(what inputs would have to change to force a chosen outcome).
run_risk_profile— per-option outcome distribution (expected value, min, max, std dev + the cumulative-probability table), not just the EV.
run_scenarios— what-if comparison: named bundles of input edits, each rolled back and compared to the baseline (EV, optimal decision, Δ, flips).
- Excel attach fix — bind to the running Excel via
GetActiveObject(ROT) instead of xlwings' window-handle walk, which failed (0x800A01A8) once the ModelChoice add-in was loaded. Fixes timeouts/hangs from the MCP server.
build_control_panel— lift a tree's inputs into a labelled control panel at the top of its sheet, with the tree linked back to it.
edit_treegains structural ops:add_option,add_branch,remove_branch.
run_evii— Expected Value of Imperfect Information for a specific test.
run_decision_report— strategy table / policy / decision brief / MCDA.
- Phases 0–2: read + rollback engine (
list_trees,get_tree,roll_up,verify_rollback), build/edit (build_tree,edit_tree), and analysis drivers (run_evpi,run_robustness,run_sensitivity,run_analysis,read_sheet), plus the/design-decision-treeprompt. CI + tag-driven PyPI release. First PyPI publish at 0.0.1.