Skip to content

0.4.0 — cost analysis and secret key inspection

Choose a tag to compare

@george-bobby george-bobby released this 09 Sep 07:22
· 1 commit to main since this release

cost analysis and secret key inspection

analyze_modal_costs (read-only)
Fetches modal billing once and aggregates locally, the same way
search_modal_logs does: a week on a busy workspace is 1500+ flat rows,
one per app per interval, and adding those up is not work to hand back
to the caller. Views: by_app, timeline, by_environment, by_resource,
summary, rates. Decimal arithmetic throughout — summing hundreds of
8-decimal strings as floats drifts.

"what is my costliest app?" -> view="by_app"
"why was Monday expensive?" -> view="timeline", whose explanation
finds the peak interval, diffs it against the one before, and ranks
apps by how much they grew into it.

Two client-version landmines, both handled: modal 1.4.x names the report
columns in Title Case ("Object ID") while 1.5+ uses snake_case, so every
field is read through an alias table — reading one spelling silently
yields a report full of zeros. And billing summary/rates only exist
in 1.5+, where an old client fails with a bare "No such command"; that
becomes an upgrade hint, and pyproject now pins modal>=1.5.

inspect_modal_secret
Lists the KEY NAMES in a secret, never the values. Modal exposes this
nowhere — not the CLI, not Secret.info(), not the gRPC SecretMetadata
message — so the only route is to mount the secret in a container and
list the environment, subtracting the ~35 variables the image and the
Modal runtime set anyway (including the MODAL_TOKEN_* credentials that
live there).

The probe is compgen -e, a bash builtin that prints exported variable
names only, so no value is printed even inside the container. It has to
be quote- and paren-free: modal shell -c shlex-splits the string,
re-joins it with spaces and runs it under bash -c, so a python -c
probe arrives mangled.

Unlike every other read here this call starts remote compute, costs a
few cents and takes tens of seconds, so it is annotated non-read-only
and deliberately kept out of list_modal_resources.

Also

  • New prompt: investigate_modal_costs.
  • Redact longest values first. With one secret value a substring of
    another ("dummy" inside "dummy2"), replacing the short one first left
    the remainder visible as "***2".

Verified against a live workspace: the cost views on both modal 1.4.3 and
1.5.5 (identical totals), and the secret probe end-to-end via a throwaway
secret with two dummy keys — both returned, 35 runtime variables filtered,
nothing leaked, secret deleted afterwards.


Install

uvx mcp-modal@0.4.0          # run this exact version
claude mcp add mcp-modal -- uvx mcp-modal@0.4.0

Also on PyPI: mcp-modal 0.4.0. The .whl and
.tar.gz attached below are the exact artifacts published to PyPI for this version.

Full changelog: v0.3.1...v0.4.0