Skip to content

Fix JSON deserialization crashes in MCP list_properties/list_units/list_leases/list_transactions - #13

Open
markd70 wants to merge 1 commit into
yllibed:masterfrom
markd70:fix/mcp-list-tools-json-deserialization
Open

Fix JSON deserialization crashes in MCP list_properties/list_units/list_leases/list_transactions#13
markd70 wants to merge 1 commit into
yllibed:masterfrom
markd70:fix/mcp-list-tools-json-deserialization

Conversation

@markd70

@markd70 markd70 commented Sep 1, 2026

Copy link
Copy Markdown

Problem

Fixes #12. Against a live multi-property tenant account, list_properties, list_units, list_leases, and list_transactions all returned a generic An error occurred invoking '...'. with no diagnostic detail.

Root cause was two separate JSON shape mismatches:

  1. property_status on TcProperty comes back as a number on this tenant, but Status is a plain string? with no converter -> System.Text.Json.JsonException on any call that loads properties. Since EntityCache (used to resolve unit/property names for leases and transactions) also loads all properties, this cascades and breaks list_leases and list_transactions too -- even though those tools have nothing to do with property status directly.
  2. price on TcUnit is sometimes null, but Price is a non-nullable decimal -> same style of crash on list_units.

Both failures were swallowed into the same generic MCP error string, so the underlying cause wasn't visible without attaching a debugger / running the server manually with debug logging.

Fix

  • Added JsonFlexibleStringConverter: accepts JSON string, number, or boolean tokens and normalizes to string?, following the same pattern as the existing tolerant converters in this file (JsonTcLeaseStatusConverter, JsonAutoLongConverter, etc.). Applied to TcProperty.Status.
  • Added JsonNullableDecimalConverter: accepts JSON null, number, or numeric string and returns decimal?. Changed TcUnit.Price to decimal? and applied it.

Testing

Rebuilt tc-mcp self-contained win-x64 (dotnet publish -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true) and ran it directly over stdio JSON-RPC against a live TenantCloud account with 14 properties across several buildings/units. Before the fix, list_properties, list_units, list_leases, and list_transactions all failed. After the fix, all four return correct data (verified property names/addresses, unit prices including nulls, lease status + tenant/unit name enrichment, and transaction records with status/category filters).

get_user_info and list_contacts were unaffected before and after, as noted in #12.

…st_leases/list_transactions

TenantCloud's internal API returns property_status as a numeric value in
some tenant accounts, but TcProperty.Status was typed as a plain string
without a converter, causing System.Text.Json to throw and the MCP
list_properties tool (and anything that triggers EntityCache, i.e.
list_leases and list_transactions) to fail with a generic 'An error
occurred invoking ...' message.

Similarly, TcUnit.Price is a non-nullable decimal, but some units
legitimately have a null price (e.g. no price set yet), crashing
list_units the same way.

Fixes:
- Added JsonFlexibleStringConverter: accepts string, number, or boolean
  JSON tokens and normalizes to a string, matching the codebase's
  existing pattern of tolerant converters (see JsonTcLeaseStatusConverter,
  JsonAutoLongConverter, etc.)
- Applied it to TcProperty.Status
- Added JsonNullableDecimalConverter: accepts null, number, or numeric
  string and returns decimal? (or null)
- Changed TcUnit.Price to decimal? and applied the new converter

Verified against a live multi-property TenantCloud account (14
properties, units, leases, and transactions) after rebuilding tc-mcp
self-contained win-x64 — all four previously-crashing tools now return
correct data.

Closes yllibed#12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCP: list_properties / list_units / list_leases / list_transactions all return generic invocation errors against a live tenant

1 participant