Skip to content

chore(deps): bump mcp-toolsets-runtime to 0.2.1, document receipts - #20

Merged
ciaransweet merged 1 commit into
mainfrom
chore/runtime-0.2.1
Jul 31, 2026
Merged

chore(deps): bump mcp-toolsets-runtime to 0.2.1, document receipts#20
ciaransweet merged 1 commit into
mainfrom
chore/runtime-0.2.1

Conversation

@ciaransweet

Copy link
Copy Markdown
Contributor

Upgrades the pinned runtime 0.2.0 → 0.2.1, and the view bridge lockfile to @developmentseed/mcp-view 0.2.1.

What 0.2.1 is

runtime#40 — the other direction from capture. Capture tells the model what a tool wrote to tool_state; nothing recorded what a tool read out of it. Now a parameter filled from session state leaves a receipt on the tool message's artifact:

{"aoi": {"key": "dataset-search/geometry", "via": "declaration",
         "kind": "geojson.AreaOfInterest", "tool": "search_datasets"}}

Purely additive — new mcp_state.receipts module, new exports, no signature changed. No code change was required here and none was made.

But the README did need one

Its session-state section said a Kind tag buys two things: resolution between tools, and removal from the model's schema. Removal from the schema is precisely what made a fill untraceable — the parameter is absent from the tool call the model produced, so neither the model nor a step panel could tell the call ran against a stored value:

▸ clip_raster
    Input:   {"dataset_id": "chirps"}      <- no aoi anywhere
    Output:  clipped 3 rasters

The receipt is what makes the hidden parameter accountable, so it belongs next to the thing that hides it. Added as the third thing tagging buys.

Which side of it these toolsets are on

Checked rather than assumed. Nothing here tags a Kind, so nothing here produces a visible receipt — but the reason is more specific than "no tags", and worth stating precisely:

handle | receipts_of:  {'collections': {'key': 'stac-explorer/collections', 'via': 'handle', ...}}
handle | supplied:     {}      # host renders nothing
handle | breadcrumb:   None    # model is told nothing

declared | supplied:   {'aoi': {...}}
declared | breadcrumb: [state used: aoi ← x/geometry, published by search]

The handle path — the only one available to an untagged toolset — does record a receipt, and shows it on neither side by design: the model wrote @state:<key> itself, so the key is already in the tool call arguments and repeating it would buy nothing.

Both hosts, against the live local server:

CLI (mcp-agent) web (mcp-agent-web)
today, untagged [] {'name': 'dev'}
with a Kind aoi ← x/geometry, published by search {'dataset_id': 'chirps', 'aoi': '← x/geometry · geojson.AreaOfInterest · from search'}

So the README describes what receipts give you and says nothing here triggers one yet — the same framing it already uses for tagging, rather than documenting a feature as though it were live.

One more thing worth having in this repo's README

0.2.1's docs also record something that is not new behaviour but is easy to get wrong here, since this repo is what deploys the chat:

LangChain passes a ToolRuntime into every tool call, and it carries the whole agent state — messages plus all of tool_state. Anything hooking the tool boundary (a Langfuse CallbackHandler, the OpenTelemetry LangChain instrumentation) therefore records every stored payload on every subsequent call.

Values deliberately kept out of the transcript still leave the process. This is upstream behaviour with or without mcp_state — but it directly qualifies a promise our README makes, and it is the wrong thing to discover after wiring a tracing backend to chat.mcp-toolsets.ds.io. Now one sentence in that section: the guarantee is about what reaches the model, not about what leaves the process.

The npm half

package.json already allowed 0.2.1 via ^0.2.0, so only the lockfile pin moved (npm update). The package is unchanged but for its reported appInfo.version, which is what the MCP Apps host sees — worth keeping truthful.

Verification

./scripts/lint clean · ./scripts/test 18 passed · ./scripts/build-views rebuilt both views · mcp-agent install-elements rewrote public/elements/McpView.jsx.

Live against uv run mcp-serve-local:

  • all three toolsets ok; mcp-cli call hello name=dev{"message": "Hello, dev!"}
  • agent graph builds with tool_state present, 3 tools loaded, nothing withheld
  • receipt rendering exercised in both hosts (table above)

pyproject.toml + uv.lock change is version-only — 0.2.1 added no dependencies.

On merge

uv.lock is a shared build input, so every toolset, the index and the chat rebuild and redeploy. Chat conversations are checkpointed in pod memory and are lost, as on every runtime bump.

🤖 Generated with Claude Code

0.2.1 is runtime#40: a parameter filled from session state now leaves a
receipt on the tool message naming the key, the kind and the publishing
tool. Purely additive — new `mcp_state.receipts` module, new exports, no
signature changed — so nothing here needed a code change, and none was
made.

## Why the README changed anyway

Receipts close a gap the README's session-state section had described
only half of. It said a `Kind` tag buys resolution between tools and
removal from the model's schema. Removal from the schema is exactly what
made a fill untraceable: the parameter is absent from the tool call the
model produced, so neither the model nor a step panel could tell the call
had run against a stored value. The receipt is what makes the hidden
parameter accountable, so it belongs next to the thing that hides it.

Verified which side of that these toolsets fall on rather than assuming.
Nothing here tags a `Kind`, so nothing here produces a *visible* receipt:

    handle | receipts_of:  {'collections': {'key': 'stac-explorer/collections',
                            'via': 'handle', ...}}
    handle | supplied:     {}      # host renders nothing
    handle | breadcrumb:   None    # model is told nothing

    declared | supplied:   {'aoi': {...}}
    declared | breadcrumb: [state used: aoi ← x/geometry, published by search]

The handle path records a receipt and shows it nowhere, by design — the
model wrote `@state:<key>` itself, so the key is already in the arguments.
Both hosts confirmed against the live local server:

    CLI  (untagged): []
    web  (untagged): {'name': 'dev'}
    CLI  (tagged):   ['aoi ← x/geometry, published by search']
    web  (tagged):   {'dataset_id': 'chirps',
                      'aoi': '← x/geometry · geojson.AreaOfInterest · from search'}

So the README says what receipts give you and that nothing here triggers
one yet — the same framing it already uses for tagging, rather than
describing a feature as if it were live.

## The tracing caveat

0.2.1's docs also document something that is not new behaviour but is
easy to get wrong here, since this repo deploys the chat: LangChain hands
every tool call the whole agent state, so a tracing backend records
stored payloads on every subsequent call. Values deliberately kept out of
the transcript still leave the process. That is upstream behaviour with
or without `mcp_state`, but it is the wrong thing to find out after
turning tracing on, so it is now a sentence in the section that promises
values stay out of the context — the promise is about the model, not the
process.

Also moves the view bridge lockfile to `@developmentseed/mcp-view` 0.2.1,
released in lockstep. `package.json` already allowed it; only the pin
moved, and the package is unchanged but for its reported version.

## Checks

`./scripts/lint` clean, `./scripts/test` 18 passed, `./scripts/build-views`
rebuilt both views, `mcp-agent install-elements` rewrote McpView.jsx.
Live against `mcp-serve-local`: all three toolsets ok, `hello` returns
`{"message": "Hello, dev!"}`, agent graph builds with `tool_state`
present and nothing withheld. `pyproject.toml`/`uv.lock` change is
version-only — 0.2.1 added no dependencies.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ciaransweet
ciaransweet merged commit 5188cc4 into main Jul 31, 2026
7 checks passed
@ciaransweet
ciaransweet deleted the chore/runtime-0.2.1 branch July 31, 2026 22:20
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.

1 participant