Skip to content

release: engine v0.10.0, plugin v0.5.0 - #20

Merged
svd merged 12 commits into
mainfrom
dev
Sep 9, 2026
Merged

svd merged 12 commits into
mainfrom
dev

Conversation

@svd

@svd svd commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Ten commits, three units of work, two artifacts.

Engine — v0.10.0

  • probe --save-raw FILE writes the untruncated payload; the .probe-raw.json suffix is enforced because .gitignore is what keeps an unredacted response out of a commit.
  • merge scrubs probed_args (emails, UUIDs, home-dir user segments including their file:// forms, 8+ digit runs) before writing the committed shapes file, and records raw values in the gitignored <stem>.verify.json the roundtrip verifier reads first. --no-scrub and --keep-parts opt out.
  • merge cross-checks carried-forward entries against the tool manifest and warns about entries the server no longer advertises.
  • Supported Python floor lowered to 3.10. Two 3.11-only constructs sat on error paths, so 3.10 imported fine and then raised the wrong exception. CI now runs 3.10-3.13.

Plugin — v0.5.0

  • Engine floor raised to mcpgen >= 0.10.0 in both skills' step 0: generate-mcp-wrappers now instructs probe --save-raw, which 0.9.0 lacks. All three coupled spots per skill moved together, including the resolver's worked examples.
  • generate-mcp-runner resolves the CLI instead of shelling out bare, taking the caller's invocation as a candidate rather than an authority.
  • Shape-spec fields rules now state when a container carries its element or value type, and name the nesting ceiling outright — codegen emits a TypedDict only for a return_model or variants name, so a nested model name renders an annotation with no class behind it.

After merge

Tag order matters — the floor must name a version that is already installable:

  1. git tag v0.10.0 on main, push (fires publish.yml → PyPI)
  2. git tag plugin-v0.5.0 on main, push
  3. Bump the mcp-client-kit ref in the svd/agent-skills marketplace repo to plugin-v0.5.0
  4. Re-advance dev: uv version --bump minor --bump dev → 0.11.0.dev1

The plugin bump rides this PR deliberately: a separate plugin-only PR from dev afterwards would drag the .devN bump onto main.

Gates

ruff check / ruff format --check / mypy clean, 714 tests pass.

svd added 12 commits August 27, 2026 17:33
Merging main brought back 0.9.0, since main was corrected to the released
version while dev's own .dev1 bump sat at the merge base. dev carries the
next unreleased version.

Claude-Session: https://claude.ai/code/session_01WLrTJYE9Rz6oRBtHhMYM7L
`generate-mcp-runner` gated on a bare `mcpgen --version` and ran a bare
`mcpgen list`, neither of which exists on PATH in a uv-managed project.
`generate-mcp-wrappers` step 7 already hands over the invocation it
resolved, but the runner never named that parameter, so an executor
following the text literally still shelled out bare. Step 0 now reads the
hand-off first and makes the caller's invocation the resolver loop's first
candidate: a valid one settles the check in a single `--version` call and
never reaches the probe, an invalid one falls through instead of aborting.
Treating it as a candidate rather than an authority is what covers the
callers that gated nothing — a user naming an invocation by hand, or a
skill with no floor of its own. The three command sites move to the
`<mcpgen>` placeholder the wrappers skill already uses.

Both resolvers now compare the release part of the reported version and
reject a pre-release whose release part equals the floor exactly. `sort -V`
alone orders `0.9.0.dev1` above `0.9.0`, and a clone parked at a
pre-release can predate the commit the floor exists for; `LoginWontHelp`
demonstrated this, landing at 4e07d03 when the version already read
`0.7.0.dev1`. A newer pre-release still passes, so `0.10.0.dev1` clears the
floor — which the eval suite depends on.

The runner's floor rises from 0.7.0 to 0.9.0 so one number covers the
plugin. Its templates need only 0.7.0 symbols, so this locks out a
standalone runner user on 0.7.x/0.8.x for nothing functional; the trade is
that the wrappers' "one floor for the whole procedure, step 7's runner
included" is true as written rather than contradicted 550 lines later.
`releasing-a-version` is updated to match: the floors move together, and
the third coupled spot per skill is the resolver's worked examples, where a
partial bump leaves the guard contradicting the text that explains it.

Claude-Session: https://claude.ai/code/session_01WLrTJYE9Rz6oRBtHhMYM7L
Two 3.11-only constructs were all that stood between the code and 3.10;
both sit on error paths, so imports and the CLI worked while any failure
raised the wrong exception.

- `_carries_interrupt` and `_describe` test `isinstance(exc, BaseExceptionGroup)`,
  a builtin only from 3.11. Below that, import the `exceptiongroup` backport —
  the same class anyio raises, and already present wherever the MCP SDK is.
- The OAuth callback wait caught the builtin `TimeoutError`, which is an alias
  of `asyncio.TimeoutError` only from 3.11. On 3.10 the timeout escaped
  unconverted instead of reaching the "browser never came back" message.

CI now runs 3.10 alongside 3.11-3.13; ruff and mypy target 3.10. Full suite
passes on 3.10.21 and on the project venv.
Review of the batch-2 scrub found the home-directory rule missed the two
spellings most likely to carry the leak it targets: file:///Users/<name>,
the standard arg form for filesystem-shaped servers, and Windows paths
written with forward slashes or a lowercase users segment. The UUID rule's
\b boundaries also failed against a word-adjacent id (id_3f25...).

Also drops --emit-shape from the SKILL.md bootstrapping recipe, which
would have merged the discovery tool into the committed shape spec, and
corrects the shape-spec recovery advice: --no-scrub cannot restore a value
after a default merge has removed .parts/, so verify.json is the source.

The merge test asserting no stale warning matched on a word the advisory
never emits and passed unconditionally; it now asserts on the real text.
Both artifacts ship from this cycle. The skills now instruct
`probe --save-raw`, a flag 0.9.0 does not have, so the plugin's engine
floor rises to 0.10.0 in both step 0 blocks — prose, `min=`, and the
resolver's worked examples, which move to `0.11.0.dev1` clearing a
`0.10.0` floor so the guard and the text that explains it still agree.

Bundling the plugin bump into the engine PR is what keeps a later
plugin-only PR from dragging step 6's `.devN` onto main. Tag order after
merge is v0.10.0 first, then plugin-v0.5.0: the floor must name a version
that is already installable.
@svd
svd merged commit 2a52bd3 into main Sep 9, 2026
13 checks passed
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